Skip to content

FLOW.md state machine missing STEP-1-BACKLOG-CRITERIA state causes infinite loop in product-owner agent #105

@nullhack

Description

@nullhack

Summary

When a product-owner subagent is invoked to write Stage 2 specification (Rules + Examples) for features that are BASELINED but still in backlog/, the agent enters an infinite loop. Root cause: FLOW.md has no state covering Stage 2 work on backlog files, so the agent falls through to [IDLE], loads skill select-feature, finds no BASELINED feature in in-progress/, escalates to PO — which is itself — and loops.

Root Causes (3)

1. Missing state: Stage 2 on backlog files is not modelled

FLOW.md detection rules are evaluated against docs/features/in-progress/. Stage 2 (writing Rule: + Example: blocks) is legitimately done on files that remain in backlog/ — they are not moved to in-progress/ until SA starts Step 2 (Architecture). This valid workflow state has no detection rule, so the agent always falls through to [IDLE].

Fix: Add a [STEP-1-BACKLOG-CRITERIA] state with detection rule:

No file in in-progress/ AND any backlog/ feature has Status: BASELINED but no Example: with @id[STEP-1-BACKLOG-CRITERIA]

This state must be checked before [IDLE] in the detection order.

2. run-session skill hijacks subagent task prompts

When a product-owner subagent is launched via the task tool, it loads skill run-session at startup. This skill evaluates FLOW.md state and takes over control flow, overriding whatever the task prompt instructed. If the detected state is [IDLE], the agent follows the idle protocol regardless of the task it was given.

Fix: The [STEP-1-BACKLOG-CRITERIA] state must be explicitly handled in the agent's session-start routing table so run-session takes the correct action instead of falling to idle. The agent's identity file should include a note: detecting this state is not idle — there is work to do.

3. Precondition gap: features were never BASELINED before Stage 2 was attempted

Stage 2 is gated on Status: BASELINED. All 14 features had Status: ELICITING. The stakeholder approval step was skipped, so there was nothing to work on even if the routing had been correct.

Fix: The define-scope skill and AGENTS.md already document the baselining gate. No template change needed — this was a process gap, not a missing rule.

Proposed Template Changes

FLOW.md state machine diagram

Add to the diagram:

[IDLE] ──► [STEP-1-BACKLOG-CRITERIA] (Stage 2 on backlog files — no WIP slot needed)

FLOW.md detection rules (prepend before rule 1)

0. No file in in-progress/ AND any backlog/ feature has Status: BASELINED but no Example: with @id
   → [STEP-1-BACKLOG-CRITERIA]

FLOW.md states section — add new state

### [STEP-1-BACKLOG-CRITERIA]
**Owner**: `product-owner`
**Entry condition**: No file in `in-progress/` AND one or more `backlog/` features have `Status: BASELINED` but no `Example:` with `@id`
**Action**: Write `Rule:` blocks and `Example:` blocks with `@id` tags for BASELINED backlog features. Files stay in `backlog/` — do NOT move to `in-progress/`. No `WORK.md` entry required.
**Exit**: All BASELINED backlog features have `@id` tags → transition to `[IDLE]`
**Commit**: `feat(criteria): write acceptance criteria for <feature-stem>` per feature
**Note**: This state does not consume the WIP slot. `run-session` must not treat this as `[IDLE]`.

.opencode/agents/product-owner.md — add to Session Start section

**[STEP-1-BACKLOG-CRITERIA] detection**: If `run-session` detects this state, do **not** treat it as `[IDLE]`. Write `Rule:` + `Example:` blocks with `@id` tags for BASELINED backlog features. Files stay in `backlog/`. Do NOT move any feature to `in-progress/` during this state.

FLOW.md auto-detection commands — add command 0

# 0. Check for STEP-1-BACKLOG-CRITERIA
NO_INPROGRESS=$(ls docs/features/in-progress/*.feature 2>/dev/null | grep -v ".gitkeep" | wc -l)
HAS_BASELINED_WITHOUT_IDS=$(grep -rl "Status: BASELINED" docs/features/backlog/ 2>/dev/null | xargs grep -L "@id:" 2>/dev/null | wc -l)
# If NO_INPROGRESS=0 AND HAS_BASELINED_WITHOUT_IDS>0 → [STEP-1-BACKLOG-CRITERIA]

Impact

Without this fix, any project using this template that:

  1. Runs discovery (Stage 1) across multiple backlog features before starting development, AND
  2. Tries to run Stage 2 specification via a product-owner subagent

...will hit this infinite loop every time.

Priority

High — blocks the normal workflow for any project with more than one backlog feature.

Reference

Post-mortem: docs/post-mortem/2026-04-22-stage2-infinite-loop.md in the beehave project.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions