Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Features flow through 5 steps with a WIP limit of 1 feature at a time. The files

```
STEP 1: SCOPE (product-owner) → discovery + Gherkin stories + criteria
STEP 2: ARCH (system-architect) → branch from main; read system.md + glossary.md + in-progress feature + targeted package files; write domain stubs; create/update domain-model.md; significant decisions as docs/adr/ADR-YYYY-MM-DD-<slug>.md; system.md rewritten
STEP 2: ARCH (system-architect) → branch from main; read system.md + glossary.md + in-progress feature + targeted package files; write domain stubs; update ## Domain Model section in system.md; significant decisions as docs/adr/ADR-YYYY-MM-DD-<slug>.md; system.md rewritten
STEP 3: TDD LOOP (software-engineer) → RED → GREEN → REFACTOR, one @id at a time
STEP 4: VERIFY (system-architect) → run all commands, review code against architecture
STEP 5: ACCEPT (product-owner) → demo, validate, SE merges branch to main with --no-ff, move .feature to completed/ (PO only)
Expand Down Expand Up @@ -49,7 +49,7 @@ All feature work happens on branches. `main` is the single source of truth and r

- **Product Owner (PO)** — AI agent. Interviews the stakeholder, writes discovery docs, Gherkin features, and acceptance criteria. Accepts or rejects deliveries. **Sole owner of all `.feature` file moves** (backlog → in-progress before Step 2; in-progress → completed after Step 5 acceptance).
- **Stakeholder** — Human. Answers PO's questions, provides domain knowledge, approves PO syntheses to confirm discovery is complete.
- **System Architect (SA)** — AI agent. Designs architecture, writes domain stubs, records decisions in ADRs, and verifies implementation respects those decisions. Owns `docs/domain-model.md`, `docs/system.md`, and `docs/adr/ADR-*.md`. Never edits or moves `.feature` files. Escalates spec gaps to PO.
- **System Architect (SA)** — AI agent. Designs architecture, writes domain stubs, records decisions in ADRs, and verifies implementation respects those decisions. Owns `docs/system.md` (including domain model, Context, and Container sections) and `docs/adr/ADR-*.md`. Never edits or moves `.feature` files. Escalates spec gaps to PO.
- **Software Engineer (SE)** — AI agent. Implements everything: test bodies, production code, releases. Owns all `.py` files under the package. Never edits or moves `.feature` files. Escalates spec gaps to PO. If no `.feature` file is in `in-progress/`, stops and escalates to PO.

## Feature File Chain of Responsibility
Expand Down Expand Up @@ -87,7 +87,7 @@ All feature work happens on branches. `main` is the single source of truth and r
| `version-control` | software-engineer | Step 2 (branch creation), Step 5 (merge to main), post-mortem branches |
| `create-pr` | system-architect | post-acceptance |
| `git-release` | stakeholder | post-acceptance |
| `update-docs` | product-owner | post-acceptance + on stakeholder demand |
| `update-docs` | system-architect | post-acceptance + on stakeholder demand |
| `design-colors` | designer | branding, color, WCAG compliance |
| `design-assets` | designer | SVG asset creation and updates |
| `flow` | all agents | every session — flow protocol, state machine design, FLOW/WORK templates |
Expand All @@ -106,17 +106,17 @@ Step 1 has two stages:

Discovery follows a block structure per session. See `skill define-scope` for the full protocol.

**Block A — Session Start**: Resume check (if `IN-PROGRESS`), read `domain-model.md` (existing entities), declare scope.
**Block A — Session Start**: Resume check (if `IN-PROGRESS`), read `system.md` Domain Model section (existing entities), declare scope.

**Block B — General & Cross-cutting**: 5Ws, behavioral groups, bounded contexts. Active listening + reconciliation against `glossary.md` and `domain-model.md`.
**Block B — General & Cross-cutting**: 5Ws, behavioral groups, bounded contexts. Active listening + reconciliation against `glossary.md` and `system.md` (Domain Model section).

**Block C — Feature Discovery (per feature)**: Detailed questions, pre-mortem, create/update `.feature` files.

**Block D — Session Close**: Append Q&A to `scope_journal.md`, update `glossary.md`, append synthesis to `discovery.md`, regression check on completed features, mark `COMPLETE`.

**Key rules**:
- PO owns `scope_journal.md`, `discovery.md`, `glossary.md`, and `.feature` files
- PO reads `domain-model.md` but never writes to it — entity suggestions go in `discovery.md` for SA formalization at Step 2
- PO reads the `## Domain Model` section of `docs/system.md` but never writes to `system.md` — entity suggestions go in `discovery.md` for SA formalization at Step 2
- Real-time split rule: >2 concerns or >8 candidate Examples → split immediately
- Completed feature touched and changed → move to `backlog/`

Expand Down Expand Up @@ -161,16 +161,13 @@ Post-mortems are append-only, never edited. If a failure mode recurs, write a ne
```
docs/
scope_journal.md ← raw Q&A, PO appends after every session
discovery.md ← session synthesis changelog, PO appends after every session
domain-model.md ← living domain model, SA creates/updates at Step 2, PO reads only
discovery.md ← session synthesis changelog (behavioral changes only), PO appends after every session
adr/ ← one file per decision: ADR-YYYY-MM-DD-<slug>.md, SA creates at Step 2
system.md ← current-state overview (completed features only), SA rewrites at Step 2, PO reviews at Step 5
system.md ← SA-owned current-state snapshot: domain model + Context + Container sections + modules + constraints + ADR index; SA rewrites at Step 2, PO reviews at Step 5
glossary.md ← living glossary, PO updates after each session
branding.md ← project identity, colors, release naming, wording (designer owns)
assets/ ← logo.svg, banner.svg, and other visual assets (designer owns)
context.md ← C4 Level 1 diagram, PO updates via update-docs skill
container.md ← C4 Level 2 diagram, PO updates via update-docs skill (if multi-container)
post-mortem/ ← compact post-mortems, PO-owned, append-only
post-mortem/ ← compact post-mortems, PO-owned, append-only
features/
backlog/<feature-stem>.feature ← narrative + Rules + Examples
in-progress/<feature-stem>.feature
Expand Down
124 changes: 72 additions & 52 deletions FLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ All must be satisfied before starting any session. If any are missing, stop and
States are checked **in order**. The first matching condition is the current state.

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

[IDLE] ──► [STEP-1-DISCOVERY] ──► [STEP-1-STORIES] ──► [STEP-1-CRITERIA]
Expand All @@ -67,14 +69,13 @@ States are checked **in order**. The first matching condition is the current sta
└──────────────────────────────────────────────► [STEP-2-ARCH]
[STEP-3-READY]
┌────────────────────┤
▼ ▼
[STEP-3-RED] ──► [STEP-3-GREEN]
[STEP-4-READY]
[STEP-3-WORKING]
[STEP-3-RED]
[STEP-4-READY]
[STEP-5-READY]
Expand All @@ -91,29 +92,43 @@ States are checked **in order**. The first matching condition is the current sta

### Detection Rules (evaluated in order)

1. No file in `docs/features/in-progress/` → **[IDLE]**
2. Feature in `in-progress/`, no `Status: BASELINED` → **[STEP-1-DISCOVERY]**
3. Feature has `Status: BASELINED`, no `Rule:` blocks → **[STEP-1-STORIES]**
4. Feature has `Rule:` blocks, no `Example:` with `@id` → **[STEP-1-CRITERIA]**
5. Feature has `@id` tags, no `feat/` or `fix/` branch exists → **[STEP-2-READY]**
6. On feature branch, no test stubs in `tests/features/<stem>/` → **[STEP-2-ARCH]**
7. Test stubs exist, any have `@pytest.mark.skip` → **[STEP-3-READY]**
8. Unskipped test exists that fails → **[STEP-3-RED]**
9. All unskipped tests pass, skipped tests remain → **[STEP-3-GREEN]**
10. All tests pass, no skipped tests → **[STEP-4-READY]**
11. Manual state set by SA after Step 4 approval → **[STEP-5-READY]**
12. On main branch, feature still in `in-progress/` → **[STEP-5-MERGE]**
13. Post-mortem file exists for current feature → **[POST-MORTEM]**
1. No file in `docs/features/in-progress/` AND any `backlog/` feature has `Status: BASELINED` but no `Example:` with `@id` → **[STEP-1-BACKLOG-CRITERIA]**
2. No file in `docs/features/in-progress/` → **[IDLE]**
3. Feature in `in-progress/`, no `Status: BASELINED` → **[STEP-1-DISCOVERY]**
4. Feature has `Status: BASELINED`, no `Rule:` blocks → **[STEP-1-STORIES]**
5. Feature has `Rule:` blocks, no `Example:` with `@id` → **[STEP-1-CRITERIA]**
6. Feature has `@id` tags, no `feat/` or `fix/` branch exists → **[STEP-2-READY]**
7. On feature branch, no test stubs in `tests/features/<stem>/` → **[STEP-2-ARCH]**
8. Test stubs exist, any have `@pytest.mark.skip` OR all unskipped tests pass but skipped remain → **[STEP-3-WORKING]**
9. Unskipped test exists that fails → **[STEP-3-RED]**
10. `WORK.md @state` is `STEP-5-READY` → **[STEP-5-READY]** *(WORK.md takes precedence over rule 11 — filesystem alone cannot distinguish Step 4 done from Step 5 ready)*
11. All tests pass, no skipped tests → **[STEP-4-READY]**
12. On main branch, feature still in `in-progress/` AND `WORK.md @state = STEP-5-COMPLETE` → **[STEP-5-COMPLETE]**
13. On feature branch (`feat/` or `fix/`), feature still in `in-progress/` → **[STEP-5-MERGE]**
14. Post-mortem file exists for current feature → **[POST-MORTEM]**

---

## States

### [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 exists specifically for bulk Stage 2 work before a feature is selected for development. It does not consume the WIP slot. `run-session` must **not** treat this state as `[IDLE]` — there is work to do.

---

### [IDLE]
**Owner**: `product-owner`
**Entry condition**: No file in `docs/features/in-progress/`
**Entry condition**: No file in `docs/features/in-progress/` AND all BASELINED backlog features already have `@id` tags (or no BASELINED features exist)
**Action**: Select next BASELINED feature from `backlog/`; move it to `in-progress/`
**Exit**: Feature moved → create `WORK.md` entry with `@state: STEP-1-DISCOVERY`
**Exit**: Feature moved → create `WORK.md` entry; initial `@state` depends on feature content:
- Feature has no `Rule:` blocks → `@state: STEP-1-DISCOVERY`
- Feature has `Rule:` blocks but no `@id` Examples → `@state: STEP-1-CRITERIA`
- Feature has `@id` Examples → `@state: STEP-2-READY`

---

Expand Down Expand Up @@ -144,46 +159,43 @@ States are checked **in order**. The first matching condition is the current sta
---

### [STEP-2-READY]
**Owner**: `system-architect`
**Owner**: `software-engineer`
**Entry condition**: Feature has `@id` tags, no `feat/<stem>` or `fix/<stem>` branch
**Action**: Create branch `feat/<stem>` from `main`; set `@branch` in `WORK.md`
**Action**: Load `skill version-control`; create branch `feat/<stem>` from `main`; set `@branch` in `WORK.md`
**Exit**: Branch created → update `@state: STEP-2-ARCH` in `WORK.md`

---

### [STEP-2-ARCH]
**Owner**: `system-architect`
**Entry condition**: On `@branch`, no test stubs in `tests/features/<stem>/`
**Action**: Read feature; design domain stubs; write ADRs; update `domain-model.md`; run `uv run task test-fast` to generate stubs
**Exit**: Stubs generated → update `@state: STEP-3-READY` in `WORK.md`
**Failure**: Spec unclear → escalate to `product-owner`; update `@state: STEP-1-DISCOVERY` in `WORK.md`
**Action**: Read feature; design domain stubs; write ADRs; update `system.md` (domain model + Context + Container sections); run `uv run task test-fast` to generate stubs
**Exit**: Stubs generated → update `@state: STEP-3-WORKING` in `WORK.md`
**Failure**: Spec unclear → escalate to `product-owner`; update `@state: STEP-1-CRITERIA` in `WORK.md`; document the gap in `WORK.md` `Next:` line
**Commit**: `feat(arch): design @id architecture`

---

### [STEP-3-READY]
### [STEP-3-WORKING]
**Owner**: `software-engineer`
**Entry condition**: Test stubs exist, some have `@pytest.mark.skip`
**Action**: Pick first skipped `@id`; remove skip; write test body
**Exit**: Test written and fails → update `@state: STEP-3-RED` in `WORK.md`
**Entry condition**: Test stubs exist; at least one has `@pytest.mark.skip` OR all unskipped tests pass but skipped remain
**Action**:
1. Pick the next skipped `@id`; remove `@pytest.mark.skip`; write the test body (RED)
2. Write minimal production code until the test passes (GREEN)
3. Refactor if needed (REFACTOR)
4. Repeat from 1 for the next `@id`
**Exit (more @ids)**: Skipped tests still remain → stay in `[STEP-3-WORKING]`
**Exit (all done)**: No skipped tests remain → update `@state: STEP-4-READY` in `WORK.md`
**Commit**: After each `@id` or logical group

---

### [STEP-3-RED]
**Owner**: `software-engineer`
**Entry condition**: An unskipped test exists that fails
**Entry condition**: An unskipped test exists that fails (mid-cycle sub-state within STEP-3-WORKING)
**Action**: Write minimal production code to pass the failing test
**Exit**: Test passes → update `@state: STEP-3-GREEN` in `WORK.md`

---

### [STEP-3-GREEN]
**Owner**: `software-engineer`
**Entry condition**: All unskipped tests pass; skipped tests remain
**Action**: Refactor if needed; then pick next `@id`
**Exit (more @ids)**: Next @id selected → update `@state: STEP-3-READY` in `WORK.md`
**Exit (all done)**: No skipped tests remain → update `@state: STEP-4-READY` in `WORK.md`
**Commit**: After each `@id` or logical group
**Exit**: Test passes → return to `[STEP-3-WORKING]`
**Note**: This sub-state is detected automatically during the TDD cycle. `WORK.md @state` stays `STEP-3-WORKING` unless the session ends mid-RED; in that case update to `STEP-3-RED` so the next session knows a test is currently failing.

---

Expand All @@ -192,13 +204,13 @@ States are checked **in order**. The first matching condition is the current sta
**Entry condition**: All tests implemented (no `@skip`) and passing
**Action**: Run all quality checks; semantic review against acceptance criteria
**Exit**: All checks pass → update `@state: STEP-5-READY` in `WORK.md`
**Failure**: Issues found → update `@state: STEP-3-READY` in `WORK.md`; document issues
**Failure**: Issues found → update `@state: STEP-3-WORKING` in `WORK.md`; document issues in `WORK.md` `Next:` line

---

### [STEP-5-READY]
**Owner**: `product-owner`
**Entry condition**: Manual state set by SA after Step 4 approval
**Entry condition**: `WORK.md @state = STEP-5-READY` (set by SA after Step 4 approval)
**Action**: Demo and validate against acceptance criteria
**Exit**: Feature accepted → update `@state: STEP-5-MERGE` in `WORK.md`
**Failure**: Not accepted → update `@state: POST-MORTEM` in `WORK.md`
Expand All @@ -207,25 +219,25 @@ States are checked **in order**. The first matching condition is the current sta

### [STEP-5-MERGE]
**Owner**: `software-engineer`
**Entry condition**: Feature accepted; still on `@branch`
**Entry condition**: Feature accepted; on `feat/<stem>` or `fix/<stem>` branch; feature still in `in-progress/`
**Action**: Merge `@branch` to `main` with `--no-ff`; delete `@branch`
**Exit**: Merged → update `@state: STEP-5-COMPLETE` in `WORK.md`

---

### [STEP-5-COMPLETE]
**Owner**: `product-owner`
**Entry condition**: On `main`, feature still in `in-progress/`
**Entry condition**: On `main`; `WORK.md @state = STEP-5-COMPLETE`; feature still in `in-progress/`
**Action**: Move feature from `in-progress/` to `completed/`
**Exit**: Feature moved → remove item from `WORK.md` active items; return to `[IDLE]`

---

### [POST-MORTEM]
**Owner**: `product-owner`
**Owner**: `product-owner` (post-mortem doc) + `software-engineer` (fix branch)
**Entry condition**: Post-mortem file exists for current feature
**Action**: Write post-mortem in `docs/post-mortem/`; create `fix/<stem>` branch from original start commit
**Exit**: Post-mortem committed → update `@state: STEP-2-ARCH`, `@branch: fix/<stem>` in `WORK.md`
**Action**: PO writes post-mortem in `docs/post-mortem/`; SE loads `skill version-control` and creates `fix/<stem>` branch from original start commit; PO updates `WORK.md`
**Exit**: Post-mortem committed, fix branch created → update `@state: STEP-2-ARCH`, `@branch: fix/<stem>` in `WORK.md`

---

Expand Down Expand Up @@ -262,14 +274,19 @@ git add WORK.md && git commit -m "chore: @id transition to @state"
Run in order; first matching condition determines the state.

```bash
# 0. Check for STEP-1-BACKLOG-CRITERIA: no in-progress file AND backlog has BASELINED features without @id
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]

# 1. Check for in-progress feature
ls docs/features/in-progress/*.feature 2>/dev/null | grep -v ".gitkeep"

# 2. Check feature baselined
grep -q "Status: BASELINED" docs/features/in-progress/*.feature

# 3. Check for Rule blocks
grep -q "^Rule:" docs/features/in-progress/*.feature
grep -q "^ Rule:" docs/features/in-progress/*.feature

# 4. Check for Example blocks with @id
grep -q "@id:" docs/features/in-progress/*.feature
Expand All @@ -285,6 +302,9 @@ grep -r "@pytest.mark.skip" tests/features/*/

# 8. Check test failures
uv run task test-fast 2>&1 | grep -E "FAILED|ERROR"

# 9. Check WORK.md @state for STEP-5-READY (must evaluate before rule 12 / test-pass check)
grep "@state:" WORK.md | grep -q "STEP-5-READY"
```

---
Expand Down
Loading
Loading