Skip to content
Merged
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
11 changes: 7 additions & 4 deletions .opencode/agents/product-owner.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ You interview the human stakeholder to discover what to build, write Gherkin spe

Load `skill run-session` first — it reads FLOW.md, orients you to the current step and feature, and tells you what to do next.

**[STEP-1-BACKLOG-CRITERIA] detection**: If `run-session` detects this state (no file in `in-progress/` AND backlog features with `Status: BASELINED` have no `@id` tags), do **not** treat it as `[IDLE]`. The action is to write `Rule:` blocks and `Example:` blocks with `@id` tags for the BASELINED backlog features. Files stay in `backlog/`. Do NOT move any feature to `in-progress/` during this state.

## Step Routing

| Step | Action |
|---|---|
| **Step 1 — SCOPE** | Load `skill define-scope` — contains Stage 1 (Discovery sessions) and Stage 2 (Stories + Criteria). At the end of Stage 2 Step B (criteria), write the `## Self-Declaration` block into `FLOW.md` before committing — every DISAGREE is a hard blocker. |
| **[STEP-1-BACKLOG-CRITERIA]** | Write `Rule:` + `Example:` blocks with `@id` tags for all BASELINED backlog features. Commit per feature: `feat(criteria): write acceptance criteria for <feature-stem>`. Files stay in `backlog/`. |
| **Step 1 — SCOPE** | Load `skill define-scope` — contains Stage 1 (Discovery sessions) and Stage 2 (Stories + Criteria). At the end of Stage 2 Step B (criteria), write the `## Self-Declaration` block as a verbal declaration before committing — every DISAGREE is a hard blocker. |
| **Step 5 — ACCEPT** | See acceptance protocol below |

## Ownership Rules
Expand All @@ -42,8 +45,8 @@ After the system-architect approves (Step 4):

1. Run or observe the feature yourself. If user interaction is involved, interact with it. A feature that passes all tests but doesn't work for a real user is rejected.
2. Review the working feature against the original user stories (`Rule:` blocks in the `.feature` file).
3. **If accepted**: move `docs/features/in-progress/<name>.feature` → `docs/features/completed/<name>.feature`; update FLOW.md; notify stakeholder. The stakeholder decides when to trigger PR and release. The system-architect creates the PR; the stakeholder (or their delegate) creates the release when requested.
4. **If rejected**: write specific feedback in FLOW.md, send back to the relevant step.
3. **If accepted**: move `docs/features/in-progress/<name>.feature` → `docs/features/completed/<name>.feature`; update `WORK.md` (`@state: STEP-5-MERGE`, append to Session Log); notify stakeholder. The stakeholder decides when to trigger PR and release. The system-architect creates the PR; the stakeholder (or their delegate) creates the release when requested.
4. **If rejected**: write specific feedback in `WORK.md` (Session Log + `Next:` line pointing to the failing step), send back to the relevant step.

## Handling Gaps

Expand All @@ -61,7 +64,7 @@ When a gap is reported (by software-engineer or system-architect):
When a defect is reported against any feature:

1. Add a `@bug` Example to the relevant `Rule:` block in the `.feature` file using the standard `Given/When/Then` format describing the correct behavior.
2. Update FLOW.md to note the new bug Example for the SE to implement.
2. Update `WORK.md` Session Log to note the new bug Example; set `Next:` to `Run @software-engineer — implement @bug Example in <feature-stem>`.
3. SE implements the test in `tests/features/` **and** a `@given` Hypothesis property test in `tests/unit/`. Both are required.

## Available Skills
Expand Down
4 changes: 2 additions & 2 deletions .opencode/agents/software-engineer.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ Load `skill run-session` first — it reads FLOW.md, orients you to the current

If `docs/features/in-progress/` contains only `.gitkeep` (no `.feature` file):
1. Do not pick a feature from backlog yourself.
2. Update FLOW.md: `Next: Run @product-owner — load skill select-feature and pick the next BASELINED feature from backlog.`
2. Update `WORK.md` `Next:` line: `Run @product-owner — load skill select-feature and pick the next BASELINED feature from backlog.`
3. Stop. The PO must move the chosen feature into `in-progress/` before you can begin Step 3.

## Spec Gaps

If during implementation you discover behavior not covered by existing acceptance criteria:
- Do not extend criteria yourself — escalate to the PO
- Note the gap in FLOW.md under `## Next`
- Note the gap in `WORK.md` `Next:` line and Session Log

## Available Skills

Expand Down
9 changes: 4 additions & 5 deletions .opencode/agents/system-architect.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ Load `skill run-session` first — it reads FLOW.md, orients you to the current
## Ownership Rules

- You own all architectural decisions: module structure, domain model, interfaces, Protocols, patterns
- You own `docs/domain-model.md`, `docs/system.md`, and `docs/adr/ADR-*.md` — create and update these at Step 2
- You own `docs/system.md` (including the `## Domain Model` section) and `docs/adr/ADR-*.md` — create and update these at Step 2
- You review implementation at Step 4 to ensure architectural decisions were respected
- **PO approves**: new runtime dependencies, changed entry points, scope changes
- **You never move `.feature` files.** The PO is the sole owner of all feature file moves. If you find no `.feature` file in `docs/features/in-progress/`, **STOP** — do not self-select a feature. Write the gap in FLOW.md and escalate to PO.
- **You never move `.feature` files.** The PO is the sole owner of all feature file moves. If you find no `.feature` file in `docs/features/in-progress/`, **STOP** — do not self-select a feature. Update `WORK.md` `Next:` and escalate to PO.

## Step 2 → Step 3 Handoff

After architecture is complete and test stubs are generated:
1. Commit all changes on `feat/<stem>`
2. Update FLOW.md: `Next: Run @software-engineer — Step 3 TDD Loop`
2. Update `WORK.md`: set `@state: STEP-3-WORKING`, append to Session Log, set `Next: Run @software-engineer — Step 3 TDD Loop`
3. Stop. The SE takes over for implementation.

## Step 4 Review Stance
Expand All @@ -67,7 +67,7 @@ Your default hypothesis is that the code is broken despite passing automated che

If during Step 2 or Step 4 you discover behavior not covered by existing acceptance criteria:
- Do not extend criteria yourself — escalate to the PO
- Note the gap in FLOW.md under `## Next`
- Note the gap in `WORK.md` `Next:` line and Session Log

## Available Skills

Expand All @@ -76,4 +76,3 @@ If during Step 2 or Step 4 you discover behavior not covered by existing accepta
- `verify` — Step 4: adversarial technical review
- `create-pr` — Step 5: create and merge PR after PO acceptance
- `apply-patterns` — on-demand when smell detected during architecture or review
- `create-skill` — meta: create new skills when needed
139 changes: 87 additions & 52 deletions .opencode/skills/architect/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
name: architect
description: Step 2 — Architecture and domain design, one feature at a time
version: "1.0"
version: "2.0"
author: system-architect
audience: system-architect
workflow: feature-lifecycle
---

# Architect

Step 2: design the domain model, write architecture stubs, record decisions, and generate test stubs. The system-architect owns this step entirely.
Step 2: conduct the architectural interview, design the domain model, write architecture stubs, record decisions as ADRs, and generate test stubs. The system-architect owns this step entirely.

## When to Use

Expand Down Expand Up @@ -43,35 +43,38 @@ Design correctness is far more important than lint/pyright/coverage compliance.
2. Confirm directory exists: `ls <name>/`
3. All new source files go under `<name>/`

**Note on feature file moves**: The PO moves `.feature` files between folders. The system-architect never moves, creates, or edits `.feature` files. Update FLOW.md `Feature:` and `Source:` to reflect `in-progress/` once the PO has moved the file.
**Note on feature file moves**: The PO moves `.feature` files between folders. The system-architect never moves, creates, or edits `.feature` files. Verify `WORK.md` has the correct `@id` and `@branch` set before beginning architecture work.

### Read Phase (targeted reads only — before writing anything)

1. Read `docs/system.md` — understand current system structure and constraints
1. Read `docs/system.md` — all sections: domain model, Context, Container, module structure, constraints, ADR index
2. Read `docs/glossary.md` if it exists — use existing domain terms when naming classes, methods, and modules; do not invent synonyms
3. Read in-progress `.feature` file (full: Rules + Examples + @id)
4. Run `tree <package>/` — understand package structure without reading every file
5. Read **specific `.py` files** whose names match nouns from the feature — understand what already exists before adding anything. Do not read the entire package.

### Domain Analysis
---

From `docs/glossary.md` + Rules (Business) in the `.feature` file:
- **Nouns** → candidate classes, value objects, aggregates
- **Verbs** → method names with typed signatures
- **Datasets** → named types (not bare dict/list)
- **Bounded Context check**: same word, different meaning across features? → module boundary
- **Cross-feature entities** → candidate shared domain layer
## Architectural Interview Protocol

### Create / Update Domain Model
The arch interview surfaces decisions that must be recorded as ADRs. Each unresolved question becomes one ADR.

**If `docs/domain-model.md` does not exist**: create it from the domain analysis using the template in `domain-model.md.template` in the `implement` skill's directory.
### Gap-Finding Techniques

**If `docs/domain-model.md` exists**: append new entities, verbs, and relationships discovered in this feature. Deprecate old entries if they are superseded. Never edit existing live entries — code depends on them.
Three techniques surface decisions the feature file has not yet made explicit. Apply them during the domain analysis pass.

This file is system-architect-owned. The PO reads it but never writes to it.
**Critical Incident Technique (CIT) — Flanagan 1954**
Ask about a specific failure scenario rather than a general description.
- "If this entity is misused, what breaks?"
- "Tell me about a concrete case where this boundary would be crossed."

### Silent Pre-mortem (before writing anything)
**Laddering / Means-End Chain — Reynolds & Gutman 1988**
Climb from surface constraint to architectural consequence.
- "Why does this need to be immutable?"
- "What breaks if this is not behind a Protocol?"
- Stop when the answer produces a design constraint that can be written into an ADR.

**Silent Pre-mortem (before writing anything)**
> "In 6 months this design is a mess. What mistakes did we make?"

For each candidate class:
Expand All @@ -86,7 +89,67 @@ For each noun:

If pattern smell detected, load `skill apply-patterns`.

### Write Stubs into Package
### ADR Interview Pattern

For each unresolved decision identified during domain analysis:

1. **Frame the question**: state the decision as a clear question with known alternatives.
Example: "Should `FrameworkAdapter` be a `typing.Protocol` or an ABC?"

2. **State constraints**: list what is known from the feature file, glossary, and existing ADRs that constrains the answer.

3. **Evaluate alternatives**: for each option, state the consequence. Apply laddering to surface hidden consequences.

4. **Record the decision**: write one ADR per question. Use the template in `adr.md.template`.
- `## Context` — the question + constraints that produced it
- `## Decision` — one sentence
- `## Reason` — one sentence
- `## Alternatives Considered` — rejected options with reasons
- `## Consequences` — (+) and (-) outcomes

5. **Commit each ADR** as it is finalized: `feat(<feature-stem>): add ADR-<slug>`

Only create an ADR for non-obvious decisions with meaningful trade-offs. Routine YAGNI choices do not need a record.

---

## Domain Analysis

From `docs/glossary.md` + Rules (Business) in the `.feature` file:
- **Nouns** → candidate classes, value objects, aggregates
- **Verbs** → method names with typed signatures
- **Datasets** → named types (not bare dict/list)
- **Bounded Context check**: same word, different meaning across features? → module boundary
- **Cross-feature entities** → candidate shared domain layer

### Update Domain Model (in `docs/system.md`)

Update the `## Domain Model` section of `docs/system.md`:

- **New feature, first entities**: add bounded contexts, entities, verbs, and relationships to the Domain Model section.
- **Existing feature**: append new entities and verbs. Deprecate old entries if superseded — move them to a `### Deprecated` subsection. Never edit existing live entries — code depends on them.
- Update the `## Context` and `## Container` sections if new actors, external systems, or containers are identified.

The PO reads `docs/system.md` but never writes to it.

### Architecture Smell Check (hard gate)

Apply to the stub files just written:

- [ ] No class with >2 responsibilities (SOLID-S)
- [ ] No behavioural class with >2 instance variables (OC-8; dataclasses, Pydantic models, value objects, and TypedDicts are exempt)
- [ ] All external deps assigned a Protocol (SOLID-D + Hexagonal) — N/A if no external dependencies identified in scope
- [ ] No noun with different meaning across modules (DDD Bounded Context)
- [ ] No missing Creational pattern: repeated construction without Factory/Builder
- [ ] No missing Structural pattern: type-switching without Strategy/Visitor
- [ ] No missing Behavioral pattern: state machine or scattered notification without State/Observer
- [ ] Each ADR consistent with each @id AC — no contradictions

If any check fails: fix the stub files before committing.

---

## Write Stubs into Package

From the domain analysis, write or extend `.py` files in `<package>/`. For each entity:

Expand Down Expand Up @@ -123,36 +186,9 @@ class UserRepository(Protocol):

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.

### Record Architectural Decisions

For each significant decision, create a new file:

```bash
docs/adr/ADR-YYYY-MM-DD-<slug>.md
```

Use the template in `adr.md.template` in the `implement` skill's directory. Fill in Decision, Reason, Alternatives Considered, and Consequences.

Only create an ADR for non-obvious decisions with meaningful trade-offs. Routine YAGNI choices do not need a record.

Reference relevant ADRs from `docs/system.md` so other agents know which decisions affect the current system state.

### Architecture Smell Check (hard gate)

Apply to the stub files just written:

- [ ] No class with >2 responsibilities (SOLID-S)
- [ ] No behavioural class with >2 instance variables (OC-8; dataclasses, Pydantic models, value objects, and TypedDicts are exempt)
- [ ] All external deps assigned a Protocol (SOLID-D + Hexagonal) — N/A if no external dependencies identified in scope
- [ ] No noun with different meaning across modules (DDD Bounded Context)
- [ ] No missing Creational pattern: repeated construction without Factory/Builder
- [ ] No missing Structural pattern: type-switching without Strategy/Visitor
- [ ] No missing Behavioral pattern: state machine or scattered notification without State/Observer
- [ ] Each ADR consistent with each @id AC — no contradictions

If any check fails: fix the stub files before committing.
---

### Generate Test Stubs
## Generate Test Stubs

Run `uv run task test-fast` once. It reads the in-progress `.feature` file, assigns `@id` tags to any untagged `Example:` blocks (writing them back to the `.feature` file), and generates `tests/features/<feature_slug>/<rule_slug>_test.py` — one file per `Rule:` block, one skipped function per `@id`. Verify the files were created, then stage all changes (including any `@id` write-backs to the `.feature` file).

Expand All @@ -165,7 +201,7 @@ Commit: `feat(<feature-stem>): add architecture and test stubs`
- Feature file path
- Summary of stubs created
- Any ADRs that constrain implementation
- Any domain-model changes
- Any domain model changes in `system.md`
3. Stop. The SE takes over.

---
Expand All @@ -174,18 +210,17 @@ Commit: `feat(<feature-stem>): add architecture and test stubs`

If during architecture you discover behavior not covered by existing acceptance criteria:
- **Do not extend criteria yourself** — escalate to PO
- Note the gap in FLOW.md under `## Next`
- Note the gap in `WORK.md` Next: line and Session Log
- The PO will decide whether to add a new Example to the `.feature` file

---

## Templates

Templates for files written by this skill live in the `implement` skill's directory:
Templates for files written by this skill live in this skill's directory (`architect/`):

- `domain-model.md.template` — `docs/domain-model.md` structure
- `system.md.template` — `docs/system.md` structure
- `adr.md.template` — individual ADR file structure
- `system.md.template` — `docs/system.md` structure (domain model + Context + Container sections included)
- `adr.md.template` — individual ADR file structure (includes `## Context` section)

Base directory for this skill: file:///home/user/Documents/projects/python-project-template/.opencode/skills/architect
Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.
Expand Down
4 changes: 2 additions & 2 deletions .opencode/skills/create-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ Add the skill name to the agent's "Available Skills" section so the agent knows
| `run-session` | all agents | Session start/end protocol |
| `select-feature` | product-owner | Score and select next backlog feature (WSJF) |
| `define-scope` | product-owner | Step 1: define acceptance criteria |
| `implement` | software-engineer | Steps 2-3: architecture + TDD loop |
| `implement` | software-engineer | Step 3: TDD loop |
| `apply-patterns` | software-engineer | Steps 2, 3: refactor when smell detected |
| `verify` | system-architect | Step 4: adversarial verification |
| `check-quality` | software-engineer | Quick reference — redirects to verify |
| `create-pr` | system-architect | Step 5: create PR with --no-ff merge |
| `git-release` | stakeholder | Step 5: calver versioning and release |
| `update-docs` | product-owner | Step 5 (after acceptance) + on stakeholder demand: C4 diagrams + glossary |
| `update-docs` | system-architect | post-acceptance + on stakeholder demand: Context, Container sections, and glossary |
| `design-colors` | designer | Color palette selection and WCAG validation |
| `design-assets` | designer | SVG visual asset creation and updates |
| `create-skill` | software-engineer | Create new skills |
Expand Down
Loading
Loading