Skip to content

[Bug]: Inconsistent story-status vocabulary across templates, workflow-chains and lifecycle rule (Approved/Review vs Ready/InReview) #810

Description

@renatolhamas

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

  1. 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.

  2. 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".

  3. 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".

  4. 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

  • I have searched existing issues to avoid duplicates
  • I have tested with the latest version
  • I can consistently reproduce this issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreCore framework (.aios-core/core/)status: needs-triageAwaiting initial triagetype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions