feat(operation): resumable-conduct Tier 0 (step_index + resolved-steps manifest)#258
Merged
Conversation
The Conductor walks a step list but its journal entries never recorded which position each step held: the enumerate index reached the in-memory ConductorFailure but stopped before _record, so a recorded outcome could not be mapped back to its place in the conducted sequence. Persist the zero-based position as a `step_index` key on the step payload (rides the existing jsonb body, no column or migration). This is the first foundation for an honest resume: a future ConductManifestPinned event will pin the conducted list, and resume will use step_index to map each recorded outcome back onto that manifest. Additive only; no behavior change to conduct, halt, or the FSM. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A conduct's final step list is derived fresh each time from recipe re-expansion, pseudoaxis expansion, and live Plan.wires / partition-rule / calibration. Recomputing it on a future resume could yield a DIFFERENT list and silently skip or mis-target a step. So record the resolved list the moment a conduct begins, before any step executes: a future resume will replay this pinned list verbatim instead of re-deriving it. New ResolvedStepsRecorded provenance event on the Procedure stream, serialized via conductor.step_to_payload (inverse of step_from_wire, so the list round-trips back to Steps). Distinct from RecipeExpansionRecorded (registration-time, pre-pseudoaxis, hashed); this is conduct-time, post-pseudoaxis, full list. Provenance-only: no-op evolver arm, no state fold (mirrors RecipeExpansionRecorded). Emitted inline from the conduct_procedure orchestration handler via a pure, unit-testable helper, NOT a dedicated command slice: the slice contract would force an operator route + MCP tool on an event that must only ever fire automatically at conduct. This mirrors how RecipeExpansionRecorded is emitted from within an existing flow. The helper records only while the Procedure is Defined and returns [] for any other state, leaving start_procedure to surface the lifecycle failure so the conduct route keeps its failures-in-body contract. naming-r3: ResolvedStepsRecorded reuses the established steps/expansion vocabulary (no "manifest"), matching the RecipeExpansionRecorded sibling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tier 0 of resumable Procedure conduct: two additive provenance foundations. No behavior change to conduct / halt / the Procedure FSM.
step_index on every conducted step entry (jsonb payload key, no migration; the runner already had
index, the gap was the_recordhop) so a recorded outcome maps back to its position in the conducted sequence.ResolvedStepsRecorded pins the fully-resolved step list (after recipe + pseudoaxis + constituent resolution) at conduct start, so a future resume replays it verbatim instead of re-deriving it (which could silently skip or mis-target a step). Serialized via
conductor.step_to_payload(inverse ofstep_from_wire). Emitted inline from the conduct handler via a pure helper, NOT a dedicated slice: the slice-contract fitness would force an operator route + MCP tool on an event that must only ever fire automatically at conduct, so this mirrors howRecipeExpansionRecordedis emitted from within a flow. Provenance-only: no-op evolver arm, no state fold.Design and gate-review r1 detail live in
project_resumable_conduct_design.md. Tier 1 (resume itself: pre-effect in-flight marker,Suspended/ResumedFSM,execute_from) is future and trigger-gated.Green locally: pyright, tach, 26450 architecture tests, ruff. New unit tests cover the manifest helper (Defined emits / non-Defined silent),
step_to_payloadround-trip throughstep_from_wire, and end-to-end emission before conduct.🤖 Generated with Claude Code