Summary
The state file (aidlc-state.md) carries a ## Phase Progress section:
## Phase Progress
- **Initialization**: Active
- **Ideation**: Pending
- **Inception**: Pending
- **Construction**: Pending
- **Operation**: Pending
aidlc-utility.ts seeds this section once when the state file is created, and the code documents an intended lifecycle for it (aidlc-utility.ts around the phaseStatus helper):
// … Pending phases flip to Active on their phase-boundary advance and to Verified at phase completion.
But no code performs that flip. I searched every tool for a writer that sets a phase row to Active or Verified after init — there is none. handleAdvance in aidlc-state.ts already computes crossesPhaseBoundary and emits PHASE_COMPLETED / PHASE_VERIFIED / PHASE_STARTED audit events on a boundary, but it updates only the Lifecycle Phase field and the Stage Progress checkboxes — it never touches the ## Phase Progress rows.
So the section is a write-once field: it holds its init values for the whole run while the Stage Progress checkboxes advance underneath it. A few stages in, a reader sees every Ideation stage checked [x] but - **Ideation**: Pending right above — a visible contradiction. The comment describes behaviour the code does not implement (a code-comment drift), and the rendered section misinforms anyone reading the state file directly.
Impact is display-only
I confirmed nothing consumes this section, so the drift does not affect routing:
- Engine routing reads the compiled
runtime-graph.json plus the Stage Progress checkboxes; the phase it reads from state is the Lifecycle Phase field, not this section.
/aidlc --status prints a "Phase Progress:" block, but it recomputes that block live from the checkboxes (aidlc-utility.ts handleStatus) — it does not read the ## Phase Progress section.
- No hook, sensor, or skill parses the section.
So this is a correctness/clarity bug in a human-facing field, not a workflow-breaking one. But a state file that shows Ideation: Pending after Ideation is done reads as broken state to a user inspecting it.
Two ways to fix
Either resolve the drift:
- Implement the documented flip (make the field honour its comment). In
handleAdvance, when crossesPhaseBoundary is true, flip the completed phase's row to Verified and the entered phase's row to Active. The existing setField(content, "<Phase>", "<status>") helper matches the - **<Phase>**: … lines directly and is a no-op when the label is absent, so it is a small additive change right after the Completed counter sync. Each phase name appears exactly once as a - **<name>**: field (only inside this section), so there is no collision with other fields.
- Or remove the section and the comment if the field is not wanted — since nothing reads it, deleting it loses no behaviour and removes the drift surface.
I have taken approach (1) in my downstream IDE-format variant and verified it end-to-end: a non-boundary transition leaves ## Phase Progress byte-identical, and a boundary transition flips exactly the completed phase → Verified and the entered phase → Active. (Note that a fix only corrects boundaries crossed after it lands; a run already mid-flow keeps its stale rows for the boundaries it already passed. A fresh run is correct from its first boundary.)
Environment
Summary
The state file (
aidlc-state.md) carries a## Phase Progresssection:aidlc-utility.tsseeds this section once when the state file is created, and the code documents an intended lifecycle for it (aidlc-utility.tsaround thephaseStatushelper):But no code performs that flip. I searched every tool for a writer that sets a phase row to
ActiveorVerifiedafter init — there is none.handleAdvanceinaidlc-state.tsalready computescrossesPhaseBoundaryand emitsPHASE_COMPLETED/PHASE_VERIFIED/PHASE_STARTEDaudit events on a boundary, but it updates only theLifecycle Phasefield and the Stage Progress checkboxes — it never touches the## Phase Progressrows.So the section is a write-once field: it holds its init values for the whole run while the Stage Progress checkboxes advance underneath it. A few stages in, a reader sees every Ideation stage checked
[x]but- **Ideation**: Pendingright above — a visible contradiction. The comment describes behaviour the code does not implement (a code-comment drift), and the rendered section misinforms anyone reading the state file directly.Impact is display-only
I confirmed nothing consumes this section, so the drift does not affect routing:
runtime-graph.jsonplus the Stage Progress checkboxes; the phase it reads from state is theLifecycle Phasefield, not this section./aidlc --statusprints a "Phase Progress:" block, but it recomputes that block live from the checkboxes (aidlc-utility.tshandleStatus) — it does not read the## Phase Progresssection.So this is a correctness/clarity bug in a human-facing field, not a workflow-breaking one. But a state file that shows
Ideation: Pendingafter Ideation is done reads as broken state to a user inspecting it.Two ways to fix
Either resolve the drift:
handleAdvance, whencrossesPhaseBoundaryis true, flip the completed phase's row toVerifiedand the entered phase's row toActive. The existingsetField(content, "<Phase>", "<status>")helper matches the- **<Phase>**: …lines directly and is a no-op when the label is absent, so it is a small additive change right after theCompletedcounter sync. Each phase name appears exactly once as a- **<name>**:field (only inside this section), so there is no collision with other fields.I have taken approach (1) in my downstream IDE-format variant and verified it end-to-end: a non-boundary transition leaves
## Phase Progressbyte-identical, and a boundary transition flips exactly the completed phase →Verifiedand the entered phase →Active. (Note that a fix only corrects boundaries crossed after it lands; a run already mid-flow keeps its stale rows for the boundaries it already passed. A fresh run is correct from its first boundary.)Environment