Skip to content

Commit 4dd7309

Browse files
committed
chore(workflow): document model v6 — 2-stage discovery, PO-owned feature moves, unified session protocol
- Split docs/discovery.md into three append-only files: docs/discovery_journal.md (raw Q&A), docs/discovery.md (synthesis), docs/architecture.md (architectural decisions) - Remove docs/features/discovery.md (superseded) - Replace Phase 1/Phase 2 model with 2-stage model: Stage 1 Discovery (unified iterative sessions) + Stage 2 Specification (stories + criteria) - PO is sole owner of all .feature file moves; SE and reviewer never move or edit .feature files; explicit escalation when no in-progress feature - Add bug handling protocol: PO adds @bug @id, SE writes both @id test and @given Hypothesis property test - Add real-time split rule: >2 concerns or >8 Examples splits immediately within the same session - Add session status markers to discovery_journal.md: IN-PROGRESS/COMPLETE - Update all agent files, skills, workflow docs, and research docs to match
1 parent 5a5429e commit 4dd7309

File tree

18 files changed

+508
-466
lines changed

18 files changed

+508
-466
lines changed

.opencode/agents/product-owner.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@ Load `skill session-workflow` first — it reads TODO.md, orients you to the cur
2525

2626
| Step | Action |
2727
|---|---|
28-
| **Step 1 — SCOPE** | Load `skill scope` — contains the full 4-phase discovery and criteria protocol |
28+
| **Step 1 — SCOPE** | Load `skill scope` — contains Stage 1 (Discovery sessions) and Stage 2 (Stories + Criteria) |
2929
| **Step 5 — ACCEPT** | See acceptance protocol below |
3030

3131
## Ownership Rules
3232

33-
- You are the **sole owner** of `.feature` files and `docs/features/discovery.md`
33+
- You are the **sole owner** of `.feature` files, `docs/discovery_journal.md`, and `docs/discovery.md`
3434
- No other agent may edit these files
35+
- **You are the sole owner of all `.feature` file moves**: backlog → in-progress (before Step 2) and in-progress → completed (after Step 5 acceptance). No other agent moves `.feature` files.
3536
- Software-engineer escalates spec gaps to you; you decide whether to extend criteria
36-
- **NEVER move a feature to `in-progress/` unless its discovery section has `Status: BASELINED`** — if not baselined, complete Step 1 (Phase 2 + 3 + 4) first
37+
- **NEVER move a feature to `in-progress/` unless its `.feature` file has `Status: BASELINED`** — if not baselined, complete Step 1 (Stage 1 Discovery + Stage 2 Specification) first
3738

3839
## Step 5 — Accept
3940

@@ -55,8 +56,17 @@ When a gap is reported (by software-engineer or reviewer):
5556
| Behavior contradicts an existing Example | Write a new Example with new `@id`. |
5657
| Post-merge defect | Move the `.feature` file back to `in-progress/`, add new Example with `@id`, resume at Step 3. |
5758

59+
## Bug Handling
60+
61+
When a defect is reported against any feature:
62+
63+
1. Add a `@bug @id:<new-8-char-hex>` Example to the relevant `Rule:` block in the `.feature` file.
64+
2. Write the Example using the standard `Given/When/Then` format describing the correct behavior.
65+
3. Update TODO.md to note the new `@id` for the SE to implement.
66+
4. SE implements the `@id` test in `tests/features/` **and** a `@given` Hypothesis property test in `tests/unit/`. Both are required.
67+
5868
## Available Skills
5969

6070
- `session-workflow` — session start/end protocol
6171
- `feature-selection` — when TODO.md is idle: score and select next backlog feature using WSJF
62-
- `scope` — Step 1: 3-session discovery (Phase 1 + 2), stories (Phase 3), and criteria (Phase 4)
72+
- `scope` — Step 1: Stage 1 (Discovery sessions with stakeholder) and Stage 2 (Stories + Criteria, PO alone)

.opencode/agents/reviewer.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ Load `skill session-workflow` first. Then load `skill verify` for Step 4 verific
4242
- **Never suggest `noqa`, `type: ignore`, or `pytest.skip` as a fix.** These are bypasses, not solutions.
4343
- **Report specific locations.** "`physics/engine.py:47`: unreachable return" not "there is dead code."
4444
- **Every PASS/FAIL cell must have evidence.** Empty evidence = UNCHECKED = REJECTED.
45+
- **Never move `.feature` files.** The PO is the sole owner of all feature file moves. After producing an APPROVED report, update TODO.md and stop — the PO accepts and moves the file.
46+
47+
## After APPROVED
48+
49+
When your report verdict is APPROVED:
50+
1. Write the report as described in `skill verify`.
51+
2. Update TODO.md `## Next` line: `Run @product-owner — accept feature <name> at Step 5.`
52+
3. Stop. Do not touch `.feature` files. The PO reviews the feature themselves and moves it to `completed/`.
4553

4654
## Gap Reporting
4755

.opencode/agents/software-engineer.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ Load `skill session-workflow` first — it reads TODO.md, orients you to the cur
4545

4646
- You own all technical decisions: module structure, patterns, internal APIs, test tooling, linting config
4747
- **PO approves**: new runtime dependencies, changed entry points, scope changes
48+
- **You never move `.feature` files.** The PO is the sole owner of all feature file moves (backlog → in-progress → completed). If you find no `.feature` file in `docs/features/in-progress/`, **STOP** — do not self-select a feature. Write the gap in TODO.md and escalate to PO.
49+
50+
## No In-Progress Feature
51+
52+
If `docs/features/in-progress/` contains only `.gitkeep` (no `.feature` file):
53+
1. Do not pick a feature from backlog yourself.
54+
2. Update TODO.md: `Next: Run @product-owner — load skill feature-selection and pick the next BASELINED feature from backlog.`
55+
3. Stop. The PO must move the chosen feature into `in-progress/` before you can begin Step 2.
4856

4957
## Spec Gaps
5058

.opencode/skills/feature-selection/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ Run @<agent-name> — <first concrete action for this feature>
100100
```
101101

102102
- If the feature has no `Rule:` blocks yet → Step 1 (SCOPE): `Run @product-owner — load skill scope and write stories`
103-
- If the feature has `Rule:` blocks but no `@id` Examples → Step 1 Phase 4 (Criteria): `Run @product-owner — load skill scope and write acceptance criteria`
103+
- If the feature has `Rule:` blocks but no `@id` Examples → Step 1 Stage 2 Step B (Criteria): `Run @product-owner — load skill scope and write acceptance criteria`
104104
- If the feature has `@id` Examples → Step 2 (ARCH): `Run @software-engineer — load skill implementation and write architecture stubs`
105105

106106
### 6. Commit

.opencode/skills/implementation/SKILL.md

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Design correctness is far more important than lint/pyright/coverage compliance.
2828

2929
### Prerequisites (stop if any fail — escalate to PO)
3030

31-
1. `docs/features/in-progress/` contains only `.gitkeep` (no `.feature` files). If another `.feature` file exists, **STOP**another feature is already in progress.
31+
1. `docs/features/in-progress/` contains exactly one `.feature` file (not just `.gitkeep`). If none exists, **STOP**update TODO.md `Next:` to `Run @product-owner — move the chosen feature to in-progress/` and stop. Never self-select or move a feature yourself.
3232
2. The feature file's discovery section has `Status: BASELINED`. If not, escalate to PO — Step 1 is incomplete.
3333
3. The feature file contains `Rule:` blocks with `Example:` blocks and `@id` tags. If not, escalate to PO — criteria have not been written.
3434
4. Package name confirmed: read `pyproject.toml` → locate `[tool.setuptools]` → confirm directory exists on disk.
@@ -39,24 +39,18 @@ Design correctness is far more important than lint/pyright/coverage compliance.
3939
2. Confirm directory exists: `ls <name>/`
4040
3. All new source files go under `<name>/`
4141

42-
### Move Feature File
43-
44-
```bash
45-
mv docs/features/backlog/<name>.feature docs/features/in-progress/<name>.feature
46-
```
47-
48-
Update `TODO.md` Source path from `backlog/` to `in-progress/`.
42+
**Note on feature file moves**: The PO moves `.feature` files between folders. The software-engineer never moves or edits `.feature` files. Update TODO.md `Source:` path to reflect `in-progress/` once the PO has moved the file.
4943

5044
### Read Phase (all before writing anything)
5145

52-
1. Read `docs/features/discovery.md` (project-level)
46+
1. Read `docs/discovery.md` (project-level synthesis changelog) and optionally `docs/discovery_journal.md` (Q&A history for context)
5347
2. Read **ALL** `.feature` files in `docs/features/backlog/` (discovery + entities sections)
5448
3. Read in-progress `.feature` file (full: Rules + Examples + @id)
5549
4. Read **ALL** existing `.py` files in `<package>/` — understand what already exists before adding anything
5650

5751
### Domain Analysis
5852

59-
From Entities table + Rules (Business) in `.feature` file:
53+
From the Domain Model table in `docs/discovery.md` + Rules (Business) in the `.feature` file:
6054
- **Nouns** → named classes, value objects, aggregates
6155
- **Verbs** → method names with typed signatures
6256
- **Datasets** → named types (not bare dict/list)
@@ -116,19 +110,20 @@ class UserRepository(Protocol):
116110

117111
Place stubs where responsibility dictates — do not pre-create `ports/` or `adapters/` folders unless a concrete external dependency was identified in scope. Structure follows domain analysis, not a template.
118112

119-
### Write ADR Files (significant decisions only)
113+
### Record Architectural Decisions
120114

121-
For each significant architectural decision, create or append to `docs/architecture/adr.md`:
115+
Append a new dated block to `docs/architecture.md` for each significant decision:
122116

123117
```markdown
124-
# ADR-NNN: <title>
118+
## YYYY-MM-DD — <feature-name>: <short title>
125119

126-
**Decision:** <what was decided>
127-
**Reason:** <why, one sentence>
128-
**Alternatives considered:** <what was rejected and why>
120+
Decision: <what was decided>
121+
Reason: <why, one sentence>
122+
Alternatives considered: <what was rejected and why>
123+
Feature: <feature-name>
129124
```
130125

131-
Only write an ADR if the decision is non-obvious or has meaningful trade-offs. Routine YAGNI choices do not need an ADR.
126+
Only write a block for non-obvious decisions with meaningful trade-offs. Routine YAGNI choices do not need a record.
132127

133128
### Architecture Smell Check (hard gate)
134129

@@ -155,7 +150,7 @@ Commit: `feat(<feature-name>): add architecture stubs`
155150

156151
- [ ] Exactly one .feature `in_progress`. If not present, Load `skill feature-selection`
157152
- [ ] Architecture stubs present in `<package>/` (committed by Step 2)
158-
- [ ] Read all `docs/architecture/adr.md` files — understand the architectural decisions before writing any test
153+
- [ ] Read `docs/architecture.md` — understand all architectural decisions before writing any test
159154
- [ ] Test stub files exist in `tests/features/<feature-name>/<rule_slug>_test.py` — one file per `Rule:` block, all `@id` stub functions present with `@pytest.mark.skip`; if missing, write them now before entering RED
160155

161156
### Write Test Stubs (if not present)
@@ -284,10 +279,10 @@ tests/features/<feature-name>/<rule_slug>_test.py
284279
### Function Naming
285280

286281
```python
287-
def test_<rule_slug>_<@id>() -> None:
282+
def test_<feature_slug>_<@id>() -> None:
288283
```
289284

290-
- `rule_slug` = the `Rule:` title with spaces/hyphens replaced by underscores, lowercase
285+
- `feature_slug` = the `.feature` file stem with spaces/hyphens replaced by underscores, lowercase
291286
- `@id` = the `@id` from the `Example:` block
292287

293288
### Docstring Format (mandatory)

0 commit comments

Comments
 (0)