100%

Ledger-matrix grind as a nested sub-SM

Goal

  • Implement ledger_grind.json through the generic child protocol.
  • Reuse the live matrix read/disposition append paths.
  • Add missing select_grind_target, dead_end_match, and matrix_frontier_empty primitives.

Self-hosting constraint

On the new engine. Reuse the live append/heal halves (append_execution_disposition_cycle, the coordinate-heal which IS wired); only the SELECT path is new.

Implementation sketch

  • ledger_grind.json: fixed reconcile over the plan-owned ledger matrix -> select_grind_target -> attempt (work-item steps 2-4) -> append_ledger_cycle -> reconcile; dead_end_match ends a dead angle; matrix_frontier_empty fires the novelty trigger. The ledger/plan state selects the next semantic node; frame data only resumes an unresolved attempt effect. The parent work-item node uses the full invoke contract (workflow, input, target, narrowed capability, ReturnContract, cancellation policy, result disposition, reconcile success/error targets), and the source-spec fragment itself schema-validates.
  • Author select_grind_target as an Action wired to the live ledger_matrix.select_grind_target read-view (thread last_advanced so the fairness floor actually advances — today no caller does).
  • Author dead_end_match (DO-NOT-RE-TRY gate over the dead-ends ledger) + matrix_frontier_empty LogicGates — these are NEW (no as-built equivalent).
  • Preserve the disposition->cell fold completeness the research flagged (KEPT/REFINED->CURED, PARTIAL->PARTIAL, REVERTED/INERT/REJECTED->DEAD-evidence, admin-DEAD, BLOCKED, ATTEMPTED->OPEN); only evidence-DEAD soft-demotes siblings.
  • Keep root identity fixed; each attempt uses a distinct child/attempt identity and folds into the owning work item.
  • Resolve dead-end, attempt-vs-bug, and next-angle guidance through Reminder mappings.

Spec references

  • plans/workflow-engine-rework/spec/workflow-state-machines.md sec 3 (grind wiring), sec 10 (nested sub-SM). Research: select_grind_target unconsumed; _read_floor_members stub; append_execution_disposition_cycle is the live append.

Work items

  • select_grind_target Action wired to the live matrix read-view (thread last_advanced)
  • Author dead_end_match + matrix_frontier_empty LogicGates (new — no as-built equivalent)
  • Nest the existing disposition-append loop; preserve the full disposition->cell fold
  • ledger_grind.json child workflow with fixed plan-ledger-derived reconcile entry, invoked from the work-item retry body through the full generic invoke/capability/ReturnContract/cancellation/reconcile protocol; schema-validate the source-spec invoke fragment too
  • Run grind retries through generic child invocation while root stays fixed; map dead-end, attempt-vs-bug, and next-angle Reminders

Test strategy / acceptance

Matrix: pass/fail/dead-end x retry Reminder state x unchanged root/frame capability. Pins: every settled attempt clears its cursor and reconciles from the plan ledger; the parent invoke omits no required field and uses no undeclared sm key; dead angle stops; active-fix regression stays a cycle; retry cannot switch plan/unit or resurrect an abandoned run.

Fresh intel (regenerated)

This is NOT new-algorithm work — it is a WIRING section. The graph shows the ledger-matrix’s pure primitives (select_grind_target, domain_novelty_fires, the disposition->cell fold, the decay read-view) are ALREADY BUILT and UNIT-PINNED in scripts/plan_corpus/ledger_matrix/, and the live disposition-append (append_execution_disposition_cycle) is ALREADY PRODUCTION-WIRED through verify_and_complete_v7. What does NOT exist is the ENGINE side: select_grind_target has ZERO callers/callees in the graph (fully unwired — the body’s own “today no caller does”), ledger_grind appears NOWHERE (no workflow JSON, no test), and the two new LogicGates (dead_end_match, matrix_frontier_empty) have no as-built equivalent. The section’s job is to CONNECT a finished read-view to a finished engine through the generic child-invocation protocol — nothing more, nothing less.

The single most important [JOIN]: select_grind_target (0 graph edges) + append_execution_disposition_cycle (6 callers incl. production verify_and_complete_v7) means the section straddles a BUILT-but-DORMANT half and a BUILT-and-LIVE half. The self-hosting constraint (reuse the live append/heal, only the SELECT path is new) is therefore a REUSE-DON’T-FORK mandate: the new append_ledger_cycle engine Action (currently a folder stub) must DELEGATE to the live append, never re-implement it — re-implementing is LEAK:algorithmic-duplication against a production write path.

Decisions this package forces before any code is written:

  1. Read root-closure-arbitrary-depth-invocation (s-be712e10) FIRST — it OWNS the InvocationFrame / ChildCapability / ReturnContract / cancellation protocol this section’s parent-invoke node consumes; landing the grind child before that protocol is stable re-fragments it (plan boundaries = impl boundaries).
  2. Read work-item-slice (s-051a0f91) — it owns the work-item SM steps 2-4 the grind nests into; the grind’s “attempt” body REUSES those steps, it does not re-author them.
  3. The new engine Action select_grind_target must WIRE to the live scripts/plan_corpus/ledger_matrix/_selection.py:select_grind_target read-view and THREAD last_advanced (the fairness-floor ordinal today no caller advances) — a non-threaded wiring silently defeats anti-starvation.
  4. Do NOT un-stub _read_floor_members — it is a locked D6 design (Always returns {}; NO hardcoded cross-space path); the grind wiring surfaces the floor via the matrix’s declared join, never by “fixing” this accessor.
  5. The parent invoke fragment must omit NO required field (workflow / input / target / capability{derive_from,scope} / return_contract / cancellation_policy{mode,target} / on_done / on_error) and carry NO undeclared sm key — mirror the existing register_blocker / attempt_livelock invoke nodes in work_item.json, and schema-validate the fragment.

DIG DEEPER

python -m scripts.plan_corpus.read --summary plans/workflow-engine-rework
scripts/intel-query.sh callers select_grind_target --repo ori-platform   # 0 = unwired
scripts/intel-query.sh callers append_execution_disposition_cycle --repo ori-platform  # 6 = live

(full dossier: ledger-grind-nested—s-1da1710b.intel.md)