Bug Description
The story lifecycle has a single canonical vocabulary defined in
.claude/rules/story-lifecycle.md and enforced by the procedural tasks:
Draft → Ready → InProgress → InReview → Done
However, at least three other authoritative sources ship a DIFFERENT
vocabulary for the same logical states. They disagree with the canonical
rule and with each other:
-
.aiox-core/product/templates/story-tmpl.yaml:44
choices: [Draft, Approved, InProgress, Review, Done]
→ uses "Approved" and "Review" instead of "Ready" / "InReview".
This is the template the story-creation flow is told to use.
-
.aiox-core/data/workflow-chains.yaml:29
condition: Story status is Approved
.aiox-core/data/workflow-chains.yaml:39
condition: Story status is Ready for Review
→ the SDC chain expects "Approved" after PO validation and
"Ready for Review" for the review phase.
-
.aiox-core/product/templates/story.hbs:34
choices: [Draft, Ready, In Progress, In Review, Done, Blocked]
→ uses spaced spellings ("In Progress"/"In Review") that differ from
the canonical "InProgress"/"InReview", and adds "Blocked".
Meanwhile the procedural tasks are internally correct and consistent:
- validate-next-story.md:479 → GO sets Draft → Ready
- dev-develop-story.md:939 → Ready → InProgress
- dev-develop-story.md:951 → InProgress → InReview
Net effect: a story legitimately created via story-tmpl.yaml is set to
"Approved" (a valid choice in that template), which is NOT a state the
lifecycle rule or the dev task recognize. Because dev-develop-story.md
and validate-next-story.md now HALT when the status is not exactly the
expected one, an "Approved" story blocks the next step instead of
progressing.
NOTE: prd.hbs and pmdr.hbs also contain "Approved", but those are
separate PRD/PMDR lifecycles where "Approved" is legitimate — they are
NOT part of this bug and should stay as they are.
Steps to Reproduce
-
Create a story using the mandated template
.aiox-core/product/templates/story-tmpl.yaml. When filling the Status
field, note the allowed choices (line 44):
[Draft, Approved, InProgress, Review, Done] — "Ready" is NOT offered.
-
Run PO validation (validate-next-story.md). Step 12 (line 479) sets
the status to "Ready" on GO. Now open workflow-chains.yaml (line 29):
the SDC chain condition for the same point says
"Story status is Approved".
-
Observe that three sources now describe the post-validation state
with three different tokens: "Ready" (task/rule), "Approved"
(story-tmpl.yaml + workflow-chains.yaml), "Ready for Review" appears
later in the same chain (line 39) for what the rule calls "InReview".
-
If a story ends up as "Approved" (a valid template choice), start the
dev task. dev-develop-story.md:937 requires status == "Ready" or
"InProgress" and otherwise HALTs
("Cannot start development: expected Ready or InProgress, found Approved").
Expected Behavior
A single source of truth for story status. Every template, workflow chain
and task should use the SAME tokens defined in
.claude/rules/story-lifecycle.md:
Draft · Ready · InProgress · InReview · Done
Specifically:
- story-tmpl.yaml choices should be [Draft, Ready, InProgress, InReview, Done]
- workflow-chains.yaml conditions should read "Ready" (not "Approved")
and "InReview" (not "Ready for Review")
- story.hbs should use the same spelling (InProgress/InReview), and any
extra state like "Blocked" should be defined in the rule or dropped
- prose spellings inside dev-develop-story.md should match its own
procedural steps
WHY THIS IS THE RIGHT APPROACH (single canonical enum):
- Determinism: the lifecycle HALT guards (validate-next-story.md:477,
dev-develop-story.md:937/949) only work if producers and consumers of
the status field agree on the exact tokens. One vocabulary makes the
guards reliable instead of tripping on synonyms.
- No silent drift: today a wrong-but-plausible token ("Approved") passes
unnoticed until a downstream guard fails. A single enum turns "wrong
status" into an impossible state rather than a late runtime block.
- Tooling & reporting: any filter/dashboard/automation that groups by
status treats "Approved", "Ready", "Ready for Review" and "InReview"
as distinct buckets for the same logical state. Unifying them keeps
metrics and chain routing correct.
- Cross-IDE parity: the same status is read by Claude/Codex/Antigravity
agents. Divergent tokens across templates make behavior IDE-dependent;
one enum makes it uniform.
Actual Behavior
Three story-status vocabularies coexist and contradict each other:
- Canonical (rule + tasks): Draft · Ready · InProgress · InReview · Done
- story-tmpl.yaml (line 44): Draft · Approved · InProgress · Review · Done
- story.hbs (line 34): Draft · Ready · In Progress · In Review · Done · Blocked
- workflow-chains.yaml (29/39): Draft · Approved · Ready for Review
As a result, stories created through the mandated template get status
"Approved", which the lifecycle rule and dev task do not recognize,
causing the workflow to HALT at the next transition instead of advancing.
Error Output
Representative HALT emitted by the procedural guard when a story reaches
@dev with the non-canonical status produced by the template:
Cannot start development: expected Ready or InProgress, found Approved
(dev-develop-story.md, Status Transitions guard, ~line 937)
Analogous guard on the PO side:
Cannot apply GO transition: expected Draft, found {status}
(validate-next-story.md, Step 12 guard, ~line 477)
Affected Area
Core Framework (.aiox-core/core/)
AIOX Version
5.2.9
Operating System
Windows 10
Node.js Version
v22.18.0
Priority
Medium - Minor impact, workaround available
Checklist
Bug Description
The story lifecycle has a single canonical vocabulary defined in
.claude/rules/story-lifecycle.md and enforced by the procedural tasks:
However, at least three other authoritative sources ship a DIFFERENT
vocabulary for the same logical states. They disagree with the canonical
rule and with each other:
.aiox-core/product/templates/story-tmpl.yaml:44
choices: [Draft, Approved, InProgress, Review, Done]
→ uses "Approved" and "Review" instead of "Ready" / "InReview".
This is the template the story-creation flow is told to use.
.aiox-core/data/workflow-chains.yaml:29
condition: Story status is Approved
.aiox-core/data/workflow-chains.yaml:39
condition: Story status is Ready for Review
→ the SDC chain expects "Approved" after PO validation and
"Ready for Review" for the review phase.
.aiox-core/product/templates/story.hbs:34
choices: [Draft, Ready, In Progress, In Review, Done, Blocked]
→ uses spaced spellings ("In Progress"/"In Review") that differ from
the canonical "InProgress"/"InReview", and adds "Blocked".
Meanwhile the procedural tasks are internally correct and consistent:
Net effect: a story legitimately created via story-tmpl.yaml is set to
"Approved" (a valid choice in that template), which is NOT a state the
lifecycle rule or the dev task recognize. Because dev-develop-story.md
and validate-next-story.md now HALT when the status is not exactly the
expected one, an "Approved" story blocks the next step instead of
progressing.
NOTE: prd.hbs and pmdr.hbs also contain "Approved", but those are
separate PRD/PMDR lifecycles where "Approved" is legitimate — they are
NOT part of this bug and should stay as they are.
Steps to Reproduce
Create a story using the mandated template
.aiox-core/product/templates/story-tmpl.yaml. When filling the Status
field, note the allowed choices (line 44):
[Draft, Approved, InProgress, Review, Done] — "Ready" is NOT offered.
Run PO validation (validate-next-story.md). Step 12 (line 479) sets
the status to "Ready" on GO. Now open workflow-chains.yaml (line 29):
the SDC chain condition for the same point says
"Story status is Approved".
Observe that three sources now describe the post-validation state
with three different tokens: "Ready" (task/rule), "Approved"
(story-tmpl.yaml + workflow-chains.yaml), "Ready for Review" appears
later in the same chain (line 39) for what the rule calls "InReview".
If a story ends up as "Approved" (a valid template choice), start the
dev task. dev-develop-story.md:937 requires status == "Ready" or
"InProgress" and otherwise HALTs
("Cannot start development: expected Ready or InProgress, found Approved").
Expected Behavior
A single source of truth for story status. Every template, workflow chain
and task should use the SAME tokens defined in
.claude/rules/story-lifecycle.md:
Specifically:
and "InReview" (not "Ready for Review")
extra state like "Blocked" should be defined in the rule or dropped
procedural steps
WHY THIS IS THE RIGHT APPROACH (single canonical enum):
dev-develop-story.md:937/949) only work if producers and consumers of
the status field agree on the exact tokens. One vocabulary makes the
guards reliable instead of tripping on synonyms.
unnoticed until a downstream guard fails. A single enum turns "wrong
status" into an impossible state rather than a late runtime block.
status treats "Approved", "Ready", "Ready for Review" and "InReview"
as distinct buckets for the same logical state. Unifying them keeps
metrics and chain routing correct.
agents. Divergent tokens across templates make behavior IDE-dependent;
one enum makes it uniform.
Actual Behavior
Three story-status vocabularies coexist and contradict each other:
As a result, stories created through the mandated template get status
"Approved", which the lifecycle rule and dev task do not recognize,
causing the workflow to HALT at the next transition instead of advancing.
Error Output
Affected Area
Core Framework (.aiox-core/core/)
AIOX Version
5.2.9
Operating System
Windows 10
Node.js Version
v22.18.0
Priority
Medium - Minor impact, workaround available
Checklist