Skip to content

Commit 6bf5550

Browse files
committed
docs(workflow): add complete workflow diagram and reference
1 parent 49e87b0 commit 6bf5550

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

docs/workflow.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Development Workflow
2+
3+
This document describes the complete feature lifecycle used to develop software with this framework.
4+
5+
---
6+
7+
## Overview
8+
9+
Features flow through 6 steps with a WIP limit of 1 feature at a time. The filesystem enforces the limit:
10+
11+
```
12+
docs/features/backlog/<name>.feature ← waiting
13+
docs/features/in-progress/<name>.feature ← exactly one being built
14+
docs/features/completed/<name>.feature ← accepted and shipped
15+
```
16+
17+
Each step has a designated agent and a specific deliverable. No step is skipped.
18+
19+
---
20+
21+
## Full Workflow Diagram
22+
23+
```
24+
╔══════════════════════════════════════════════════════════════════════╗
25+
║ FEATURE LIFECYCLE (WIP = 1) ║
26+
╚══════════════════════════════════════════════════════════════════════╝
27+
28+
FILESYSTEM ENFORCES WIP:
29+
backlog/<name>.feature → in-progress/<name>.feature → completed/<name>.feature
30+
31+
32+
┌─────────────────────────────────────────────────────────────────────┐
33+
│ STEP 1 — SCOPE agent: product-owner │
34+
├─────────────────────────────────────────────────────────────────────┤
35+
│ │
36+
│ Phase 1 — Project Discovery (once per project) │
37+
│ PO asks stakeholder 7 questions → silent pre-mortem │
38+
│ → baseline → create backlog/<name>.feature stubs │
39+
│ │
40+
│ Phase 2 — Feature Discovery (per feature) │
41+
│ PO populates Entities table → generates questions from gaps │
42+
│ → interview rounds → stakeholder says "baseline" │
43+
│ → decomposition check (>2 concerns or >8 examples → split) │
44+
│ │
45+
│ Phase 3 — Stories (PO alone) │
46+
│ Write Rule: blocks with user story headers (no Examples yet) │
47+
│ commit: feat(stories): write user stories for <name> │
48+
│ │
49+
│ Phase 4 — Criteria (PO alone) │
50+
│ Write @id-tagged Example: blocks under each Rule: │
51+
│ commit: feat(criteria): write acceptance criteria for <name> │
52+
│ ★ FROZEN — changes require @deprecated + new Example │
53+
│ │
54+
└─────────────────────────────────────────────────────────────────────┘
55+
↓ PO picks feature from backlog
56+
┌─────────────────────────────────────────────────────────────────────┐
57+
│ STEP 2 — ARCHITECTURE agent: developer │
58+
├─────────────────────────────────────────────────────────────────────┤
59+
│ │
60+
│ mv backlog/<name>.feature → in-progress/<name>.feature │
61+
│ Read discovery + feature file │
62+
│ Silent pre-mortem (YAGNI/KISS/DRY/SOLID/OC/patterns) │
63+
│ Append Architecture section to feature file description │
64+
│ (Module Structure + ADRs + Build Changes) │
65+
│ Architecture contradiction check → PO acknowledges │
66+
│ commit: feat(<name>): add architecture │
67+
│ │
68+
└─────────────────────────────────────────────────────────────────────┘
69+
70+
┌─────────────────────────────────────────────────────────────────────┐
71+
│ STEP 3 — TEST FIRST agent: developer │
72+
├─────────────────────────────────────────────────────────────────────┤
73+
│ │
74+
│ uv run task gen-tests → creates tests/features/<name>/ │
75+
│ one <rule-slug>_test.py per Rule: │
76+
│ test_<rule_slug>_<hex>() per Example │
77+
│ Write test bodies (real assertions, not raise NotImplementedError) │
78+
│ Confirm every test FAILS (ImportError / AssertionError) │
79+
│ ★ STOP — reviewer checks test design + semantic alignment │
80+
│ ★ WAIT for APPROVED │
81+
│ commit: test(<name>): write failing tests │
82+
│ │
83+
└─────────────────────────────────────────────────────────────────────┘
84+
85+
┌─────────────────────────────────────────────────────────────────────┐
86+
│ STEP 4 — IMPLEMENT agent: developer │
87+
├─────────────────────────────────────────────────────────────────────┤
88+
│ │
89+
│ For each failing test (one at a time): │
90+
│ │
91+
│ RED → GREEN → REFACTOR → SELF-DECLARE ─STOP─ REVIEWER ─WAIT─ │
92+
│ ↓ APPROVED │
93+
│ COMMIT │
94+
│ ↓ │
95+
│ next test │
96+
│ │
97+
│ RED: confirm test fails │
98+
│ GREEN: minimum code to pass (YAGNI + KISS only) │
99+
│ REFACTOR: DRY → SOLID → Object Calisthenics (9 rules) │
100+
│ → type hints → docstrings │
101+
│ SELF-DECLARE: write ## Self-Declaration block in TODO.md │
102+
│ 21-item checklist with file:line evidence │
103+
│ REVIEWER: code-design check only (no lint/pyright/coverage) │
104+
│ COMMIT: feat(<name>): implement <what> │
105+
│ │
106+
│ After all tests green: │
107+
│ lint + static-check + test + timeout run (all must pass) │
108+
│ developer pre-mortem (2-3 sentences) │
109+
│ │
110+
└─────────────────────────────────────────────────────────────────────┘
111+
112+
┌─────────────────────────────────────────────────────────────────────┐
113+
│ STEP 5 — VERIFY agent: reviewer │
114+
├─────────────────────────────────────────────────────────────────────┤
115+
│ │
116+
│ Default hypothesis: broken despite green checks │
117+
│ │
118+
│ 1. Read feature file — all @id Examples, interaction model │
119+
│ 2. Check commit history — one commit per test, clean status │
120+
│ 3. Production-grade gate: │
121+
│ app exits cleanly + output changes with input │
122+
│ 4. Code review (stop on first failure): │
123+
│ 4a Correctness (dead code, DRY, YAGNI) │
124+
│ 4b KISS (one thing, nesting, size) │
125+
│ 4c SOLID (5-row table) │
126+
│ 4d Object Calisthenics (9-row table) │
127+
│ 4e Design Patterns (5 smells) │
128+
│ 4f Tests (docstrings, contracts, @id coverage, naming) │
129+
│ 4g Code Quality (noqa, type hints, docstrings, coverage) │
130+
│ 5. Run: gen-tests --orphans → lint → static-check → test │
131+
│ 6. Interactive verification (if UI involved) │
132+
│ 7. Written report: APPROVED or REJECTED │
133+
│ │
134+
└─────────────────────────────────────────────────────────────────────┘
135+
↓ APPROVED
136+
┌─────────────────────────────────────────────────────────────────────┐
137+
│ STEP 6 — ACCEPT agent: product-owner │
138+
├─────────────────────────────────────────────────────────────────────┤
139+
│ │
140+
│ PO runs/observes the feature (real user interaction) │
141+
│ Checks against original Rule: user stories │
142+
│ │
143+
│ ACCEPTED: │
144+
│ mv in-progress/<name>.feature → completed/<name>.feature │
145+
│ developer creates PR + tags release │
146+
│ │
147+
│ REJECTED: │
148+
│ feedback in TODO.md → back to relevant step │
149+
│ │
150+
└─────────────────────────────────────────────────────────────────────┘
151+
```
152+
153+
---
154+
155+
## Supporting Tools
156+
157+
| Command | When | Purpose |
158+
|---|---|---|
159+
| `uv run task gen-tests` | Step 3, Step 4 | Reads `.feature` files → creates/syncs test stubs in `tests/features/` |
160+
| `uv run task gen-tests -- --check` | Before gen-tests | Dry run — preview what would change |
161+
| `uv run task gen-tests -- --orphans` | Step 5 | List tests with no matching `@id` |
162+
| `uv run task gen-todo` | Every session | Reads in-progress `.feature` → syncs `TODO.md` |
163+
| `uv run task gen-id` | Step 1 Phase 4 | Generate 8-char hex `@id` for a new Example |
164+
| `uv run task test-fast` | Step 4 cycle | Fast test run (no coverage) — used during Red-Green-Refactor |
165+
| `uv run task test` | Handoff, Step 5 | Full suite with coverage — must reach 100% |
166+
| `uv run task lint` | Handoff, Step 5 | ruff — must exit 0 |
167+
| `uv run task static-check` | Handoff, Step 5 | pyright — must exit 0, 0 errors |
168+
| `timeout 10s uv run task run` | Handoff, Step 5 | App must exit cleanly (exit 124 = hang = fix it) |
169+
170+
---
171+
172+
## Test Layout
173+
174+
```
175+
tests/
176+
features/<feature-name>/
177+
<rule-slug>_test.py ← generated by gen-tests, one per Rule: block
178+
function: test_<rule_slug>_<8char_hex>()
179+
unit/
180+
<anything>_test.py ← developer-authored extras, no @id traceability
181+
plain pytest or Hypothesis @given (developer's choice)
182+
```
183+
184+
---
185+
186+
## TODO.md Structure (Step 4)
187+
188+
```markdown
189+
# Current Work
190+
191+
Feature: <name>
192+
Step: 4 (implement)
193+
Source: docs/features/in-progress/<name>.feature
194+
195+
## Cycle State
196+
Test: @id:<hex> — <description>
197+
Phase: RED | GREEN | REFACTOR | SELF-DECLARE | REVIEWER(code-design) | COMMITTED
198+
199+
## Self-Declaration (@id:<hex>)
200+
- [x] YAGNI-1 … SOLID-D … OC-1…OC-9 … Semantic (21 items, file:line each)
201+
202+
## Progress
203+
- [x] @id:<hex>: <done> — reviewer(code-design) APPROVED
204+
- [~] @id:<hex>: <in progress>
205+
- [ ] @id:<hex>: <next>
206+
207+
## Next
208+
<one actionable sentence>
209+
```
210+
211+
---
212+
213+
## Roles
214+
215+
| Role | Type | Responsibilities |
216+
|---|---|---|
217+
| **Stakeholder** | Human | Answers questions, provides domain knowledge, says "baseline" |
218+
| **Product Owner** | AI agent | Interviews stakeholder, writes `.feature` files, picks features, accepts deliveries |
219+
| **Developer** | AI agent | Architecture, tests, code, git, releases |
220+
| **Reviewer** | AI agent | Adversarial verification — defaults to REJECTED until proven correct |
221+
222+
---
223+
224+
## Quality Gates (non-negotiable)
225+
226+
| Gate | Standard |
227+
|---|---|
228+
| Test coverage | 100% |
229+
| Type errors (pyright) | 0 |
230+
| Lint errors (ruff) | 0 |
231+
| Function length | ≤ 20 lines |
232+
| Class length | ≤ 50 lines |
233+
| Max nesting | 2 levels |
234+
| Instance variables per class | ≤ 2 |
235+
| Uncovered `@id` tags | 0 |
236+
| `noqa` comments | 0 |
237+
| `type: ignore` comments | 0 |
238+
| Orphaned tests | 0 |
239+
| Hypothesis tests missing `@pytest.mark.slow` | 0 |

0 commit comments

Comments
 (0)