Work-item vertical slice — validate-first SM + REAL proof
Goal
Migrate the work-item SM end-to-end with real proof and the first complete ContextAssembly. The plan API owns workflow state, root/frame facts fix exact scope, and reconcile/validate/do_work/invoke-child/fold/revalidate/complete is script-selected; the LLM receives only bounded coding context.
Self-hosting constraint
Still off-path: the slice runs on a sandbox plan via the engine; the live per-item path (complete_work_item_v7) is unchanged. This is migration step 3 (the cleanest slice).
Implementation sketch
- Author
workflows/work_item.jsonper the canonical SM:state_authority=domain_artifact; fixed plan-derived reconcile entry; journaled initial proof Action; read-only validate gate; bounded do-work; journaled post-work proof Action; read-only revalidate; reconcile-selected proof persistence and completion flip. Every settled Action/invoke/finalizer returns through reconcile. Persist no semantic node in the frame; only unresolved effect/wait cursors survive. - Author proof/action components and consume the engine-core ContextAssembler; the script derives the exact coding prompt and result contract from the current plan-API projection, while the LLM chooses only implementation/discovery details inside that capability.
- Emit one
always, onewhile_state, and onewhen_conditionReminder with the active root/frame capability anchor. - Dispatch bounded work with an engine task token; only an authorized ResultSubmission may enter revalidation.
- Reject targets outside the root frame; permit another plan only through an engine-issued child capability and typed return.
- Close the proof gap:
run_proof_probesexecutes/journalsprobe_ref;proof_satisfiedreads current receipts and appliescriterion_verdict; refuse hand-supplied non-probe readings. - Route post-work proof failure through stable evidence fingerprinting and a bounded classifier; its opaque ResultSubmission reference may select only
record_failure_disposition, which persists the closed FailureDisposition through the plan API before another coding attempt, blocker detour, transient recovery, or human decision. - Add retry/catch to proof and classification Actions; persist authenticated human disposition before routing; fail closed through a default arm.
- Invoke blocker children through the generic child protocol with atomic shelve-on-push, fold-once return, exact-origin resume, and proof rerun.
- Use structured GateCall/ActionCall args for every parameterized component; restore shelved origin on all stopped-child paths and append DEAD evidence only after active-regression classification.
- Persist failure origin phase and exact symbolic resume target before classification; recover initial proof, work dispatch, or post-work proof without crossing accounting phases.
- Bind add-bug and attempt-livelock returns to opaque protocol references, then consume them through
record_registered_blocker/record_attempt_regroundplan-writer Actions before their values can route; bind HumanDecisionReceipt the same way throughrecord_human_decision. Catch classifier business failure, use canonical status/cycle vocabulary, and route proof-persistence/completion-write failure through reconciled typed engine error. - Normalize tracked and human dispositions into the same FailureContext blocker field; gate active regression on work/post-work origin and bounded attempt budget.
- Invoke generic attempt-livelock on exhaustion; only folded accepted reground evidence resets the budget. Commit blocked/error receipts through terminal on_commit.
- Request add-bug, fix-bug, and reground capabilities declaratively; generic push derives scoped child tokens from root authority.
- Require work-item proof, subtree quiescence, and all child results folded before proof persistence; reach
completedonly after a second plan-derived reconcile observes the committed complete status and current proof. Keep irreducible block separate from runnable livelock recovery. - Prove vs
./test-all.sh; consume the canonicalpython -m scripts.test_all_runtime status/verdictenvelope, never a singleton build summary file.
Spec references
- plans/workflow-engine-rework/spec/workflow-state-machines.md sec 2 (work-item SM), sec 10.2 (canonical work_item.json), sec 11 (hardening). Research:
review_phase.complete_work_item_v7;write.record_criterion_evidence(proof gap).
Test strategy / acceptance
Matrix: validate/pass/fail x retry/catch/disposition x child open/folded x blocker register/fix/return x human receipt x token. Pins: every ordinary entry starts at plan-derived reconcile; a present-but-bypassed reconcile node rejects; every settled effect clears its cursor and returns to reconcile; route-affecting results without sanctioned plan/tracker writers reject; unbound/stale frame cursors reject; incomplete composite cannot flip; errors route typed; irreducible block has no cure; wrong/stale result cannot advance; model-authored state/control text cannot replace a plan API read or select a transition.
Work Items
- Author
workflows/work_item.jsonwith domain-artifact authority, initial/reachable plan-derived reconcile, all settled effects returning through it, exactly-one derived route, plan-writer-backed semantic result paths, consume-only classifier/bug-registration/reground/human-decision references plus their named persist Actions, proof/completion composite, receipt-bound in-flight cursors, retry/catch/disposition routing, blocker invoke/fold/resume, and irreducible block separation - Author proof/action components and bind bounded work dispatch/result ingestion to the engine-core ContextAssembler; generate the exact prompt from plan/root state and leave only bounded coding/discovery judgment to the LLM
- Implement run_proof_probes as a journaled sandboxed Action; keep proof_satisfied read-only over current receipts
- Refuse a non-probe-sourced reading on the new path (harden record_criterion_evidence)
- Prove the slice vs
./test-all.sh(no new failures) in isolation - Extend the vertical slice to emit one always-on, one while-state, and one conditional reminder in payload.reminders without changing route selection; pin mandatory reminder acknowledgment and evidence
- Pin ContextAssembly to root + active frame; reject unauthorized targets and prove one capability-scoped cross-plan child return
Fresh intel (regenerated)
This slice is the first vertical proof that the whole workflow-engine mission works — it lifts ONE real state machine (work-item complete/abandon/push-forward/revalidate) out of the plan_orchestrator god-object tangle and re-expresses it as one declarative workflows/work_item.json driven by a generic engine, running off-path on a sandbox plan so the live per-item path never moves. Three graph facts frame every decision:
- The engine does not exist yet. No
EngineTurn/RootClosure/InvocationFrame/ContextAssembler/ReminderScheduler/ResultSubmission/workflows/*.jsonanywhere inscripts/(grep-empty). This slice CONSUMES the siblingengine-core(s-e585be74) + root-closure (s-be712e10) deliverables — it is BLOCKED on them landing first (bothnot-started). - The “before” picture is a low-cohesion god-object cluster.
design-opportunitiesranksroadmap._route_dispatch(321070),roadmap.orchestrate(265273), andreview_phase.verify_and_complete_v7(callable-risk 75456, span 537, fanout 38) as the top DESIGN:low-cohesion hazards, all mission-cited to the SRP conflict rule. The scattered*_v7work-item operations (complete/abandon/push_forward/mark_reviewed) embedding-cluster at 0.81-0.86 — they ARE the one SM the JSON must unify. This slice is the mission’s proof-of-concept that the tangle collapses. - The live per-item path is a DO-NOT-TOUCH surface.
complete_work_item_v7(span 289, betweenness 2302, 11 behavioral pins intest_complete_work_item_v7.py) andverify_and_complete_v7(span 537, fanout 38, betweenness 13924 — the single highest-risk callable) are the strangler-fig’s untouched trunk. The section body states the live path is “unchanged”; the mission bans switching an active root mid-migration.
Decisions this package forces before any code is written:
- Confirm the engine-core (s-e585be74) ContextAssembler + root-closure (s-be712e10) capability primitives have landed — this slice is a CONSUMER, not a builder, of them (w-35887a59, w-f3b0946e). It cannot start cold.
- Build the SM as
workflows/work_item.json+ pluggable LogicGate/Action components, NEVER by editingreview_phase.py/roadmap.py— the god-object is the anti-pattern the engine replaces, and editing the live path violates the strangler-fig constraint (SCHEMA:unvalidated-config+STRUCTURE:plan-specific-tooling-leakguard the JSON). - The proof gate is a validator terrain — pin it with teeth.
run_proof_probes(journaled sandbox exec) andproof_satisfied(read-only receipt read) are NEW; the harden ofrecord_criterion_evidence(w-7151d418, “refuse a non-probe-sourced reading”) is anINVERTED-TDDrisk surface — the negative pins (bypassed reconcile rejects, non-probe reading rejects, stale result cannot advance) MUST fail pre-fix. - Prove vs
./test-all.shthrough the canonicaltest_all_runtime status/verdictenvelope (w-f6ff0bc6) — the section body +test-all-runtime.mdban singleton-summary reads.
["complete_work_item_v7", "verify_and_complete_v7", "orchestrate", "_route_dispatch"]
DIG DEEPER
# confirm the engine core still absent (this slice's dependency):
grep -rln "EngineTurn\|RootClosure\|InvocationFrame\|ContextAssembl\|ReminderScheduler\|ResultSubmission" scripts/
python -m scripts.plan_corpus.read --summary plans/workflow-engine-rework # section roster + statuses
(full dossier: work-item-slice—s-051a0f91.intel.md)