feat(flow): flow doctor + local run-state materialization#22
Draft
skapoor8 wants to merge 8 commits into
Draft
Conversation
Move mutable run-state out of the flow definition into a local run instance under .codevoyant/runs/<slug>/ (progress.md + context.md), so flow definitions stay read-only templates and global flows are no longer clobbered by concurrent or cross-project runs. - flow-dir.md: add Run instance section defining RUN_DIR - go.md: seed/read progress.md + context.md from RUN_DIR; never mutate the definition's flow.md - status.md: prefer run instance progress/Status, fall back to definition - list.md: note that live progress lives in the run instance
Add references/workflows/doctor.md: diagnoses (default) and repairs (--fix) one flow or every flow across both scopes. Runs six checks (clobber, stale context, orphaned worktree/branch, step-file drift, schema drift, placeholder coherence) as PASS/WARN/FAIL, and five heals under --fix. Honors the critical guard that a legitimately-interrupted context.md matching its own steps is never deleted. Built against the Phase 1 run-instance layout: a global definition paired with a local run instance is treated as normal, not drift.
Expose the flow doctor workflow and the definition-vs-run-instance model across the dispatcher, help, and public docs. - SKILL.md: add fix/diagnose/check → doctor aliases, --fix pass-through note, and doctor row in the workflow index - help.md: add the doctor usage line, doctor aliases, and a run-instance storage note - docs/skills/flow.md: add a doctor section and a definition-vs-run-instance note under go
skapoor8
commented
Jul 10, 2026
go.md now writes a run.md identity file into the run instance capturing
the resolved slug/branch/spec-slug/worktree, backfilling identifiers as
steps produce them. This gives /flow doctor a concrete anchor to compare
context.md against, since the definition and progress.md only ever hold
{{placeholders}}. Documents run.md in flow-dir.md and help.md.
…positive signal Check 1 now compares context.md against the run's recorded identity in run.md instead of the placeholder-bearing step text, so a legitimately interrupted run is no longer misread as unrelated. Heal A deletes a context.md ONLY on a positive clobber signal (identifier differs from run.md, legacy context beside a global definition, or Status=Complete) and preserves on uncertainty or match — inverting the previous delete-unless-PASS bias that risked destroying live resume state. Also inspect both RUN_DIR/context.md and a legacy FLOW_DIR/context.md independently rather than first-match, so an old clobber beside the definition still gets cleaned, and announce any deletion under ~/.codevoyant/flows (global scope) before acting.
Update the flow docs to describe the run.md identity file in the run instance and the revised doctor behaviour: clobber detection anchored on run identity, delete only on a positive signal, both context locations inspected, and explicit announcement of global-scope deletions.
skapoor8
commented
Jul 10, 2026
Step 3 left progress.md on disk (all [x], Status=Complete) and only removed context.md, but Step 1's resume branch was keyed on progress.md existence — so a second /flow go of a finished flow took Resume, found zero pending steps, and exited 'already complete'. A completed run could never re-run. Step 1 now classifies the run instance into three states: first run (no progress.md), completed run (all [x] or Status=Complete — archive the stale instance to RUN_DIR/archive and re-seed a clean run), and resume (partially complete — preserved, never wiped). Step 3's wording now matches the mechanism. Genuinely in-progress runs still resume with their context intact.
…-dir A step handoff reports slug= (the resolved spec slug), but run.md has two slug-like fields — the flow's own slug: and spec-slug: — so the backfill target and doctor's comparison field were ambiguous. Pin one canonical mapping everywhere: handoff slug= -> run.md spec-slug: (never the flow slug:), branch= -> branch:, worktree= -> worktree:. go.md (backfill), doctor.md (Check 1), and flow-dir.md now spell out and share the same field names, so Check 1's identity match is reliable.
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.
Changes
Two related fixes for flow run-state. Feature B is the preventive fix; feature A cleans up the same class of problem reactively.
A —
flow doctorflow doctor [name] [--fix] [--global]. Diagnoses a flow's run-state.--fixapplies repairs.B — Local run-state materialization
flow gonow writes mutable run-state (progress + context) to a local run instance at.codevoyant/runs/<slug>/instead of mutating the flow definition in place.Validation
flow gowrites progress/context to.codevoyant/runs/<slug>/, leaves the flow definition unchangedflow doctor(no flag) reports issues without modifying anythingflow doctor --fixrepairs the 5 healable checksNotes for reviewers