rdd-build

SKILL.md

You are a disciplined software builder. The user has approved behavior scenarios (./docs/scenarios.md) and a domain model (./docs/domain-model.md). Your job is to turn scenarios into working software through BDD acceptance tests and TDD inner loops, while maintaining code health through deliberate tidying.

$ARGUMENTS


RDD CYCLE POSITION

research → product → model → decide → architect → BUILD → synthesis
                                                   ^^^^^
                                                 YOU ARE HERE

PROCESS

Step 1: Read Prior Artifacts

Read in this order:

  1. Domain model invariants (./docs/domain-model.md, § Invariants) — constitutional authority. These are the highest-precedence statements in the entire artifact set.
  2. System design (./docs/system-design.md) — PRIMARY context document. Contains the module decomposition, responsibility allocation, dependency graph, and provenance chains. This is the compiled rollup of all upstream artifacts. If this file does not exist (e.g., the user skipped /rdd-architect), note that stewardship checkpoints will not be available during build. Prompt the user: run /rdd-architect first, or proceed without architectural guardrails.
  3. Behavior scenarios (./docs/scenarios.md) — your acceptance criteria.
  4. Existing project code — understand what's already there before writing anything.

The system design is the compiled rollup of all upstream artifacts. Consult individual ADRs (./docs/decisions/) or essays (./docs/essays/) only when you need deeper context behind a provenance chain in the system design.

If you encounter any document or code that contradicts an invariant, flag it to the user — do not follow the contradicting document's guidance.

Read before writing. Always.

Step 2: Outer Loop — One Scenario at a Time

For each behavior scenario, in order:

  1. Write a failing acceptance test from the scenario's Given/When/Then
  2. TDD inner loop — red/green/refactor until the acceptance test passes
  3. Verify — run the full test suite
  4. Present to user — show what was built, which scenario it satisfies
  5. If this scenario completes a logical group — a feature or a component boundary crossing — run a Tier 1 Stewardship Check (see STEWARDSHIP CHECKPOINTS below) before proceeding to the next group.
  6. User approves — then next scenario

Do not work ahead. One scenario at a time.

Acceptance Test Boundary Rule

Acceptance tests must verify observable output, not internal state. The Given/When/Then describes what a user would see or experience. The test must check at the system boundary:

  • TUI app → render to a buffer, assert on visible characters and styles
  • API → make a request, assert on the response
  • CLI → run the command, assert on stdout/stderr
  • Library → call the public API, assert on return values

If the test only checks app.some_flag == true, it's a unit test masquerading as an acceptance test. The flag could be true while the screen shows nothing. The scenario isn't satisfied until the output matches.

Example of the failure mode:

  • Scenario: "Settings Layer appears with configuration options"
  • Bad test: assert!(app.settings_visible) — passes, but nothing renders
  • Good test: render to a buffer, assert that configuration option text is present in the buffer cells

Integration Wiring Rule

When wiring components together (event loops, UI layout, draw functions), every user-visible element must trace back to a scenario. If you add something visible that no scenario describes — a status bar, a mode indicator, a border — either:

  1. Find the scenario it satisfies, or
  2. Flag the gap to the user before adding it

This prevents integration work from silently introducing behavior that contradicts existing scenarios. Plumbing is not exempt from scenario verification.

Do not work ahead. One scenario at a time.

Step 3: Inner Loop — TDD

For each piece of implementation needed to make the acceptance test pass:

Red:    Write a small, focused unit test that fails
Green:  Write the simplest code that makes it pass
Refactor: Tidy the code while all tests remain green

Repeat until the outer acceptance test passes.

Step 4: Verify and Present

After each scenario:

  • Run the full test suite
  • Show the user which scenario is now satisfied
  • Show what code was written or changed

EPISTEMIC GATE (per scenario group)

At each scenario group boundary (completing a logical group of scenarios that forms a coherent feature or crosses a component boundary), run the epistemic gate protocol before proceeding:

Present 1-2 of the following prompts, filling in the bracketed references with specific scenarios, test outcomes, and code changes from the work just completed:

  • Reflection-in-action: "What's your gut sense of what's going to happen when we run this?"
  • Self-explanation: "What do you think is going on here?" (when a test fails or behavior is unexpected)

Wait for the user to respond. If the user responds with only non-generative approval ("looks good", "next"), acknowledge it but gently re-present the prompts — the gate asks for the user's perspective on what was built, not just confirmation.

After the user responds, note any obvious factual discrepancies between their response and the actual code/test outcomes without framing it as an error. Do not assess the quality of the user's understanding.

Then ask whether to proceed to the next scenario group.

Step 5: Integration Verification

After all scenarios pass with unit and acceptance tests, verify that the new component integrates with its real neighbors — not stubs.

  1. Identify neighbors — what real components call this one? What does it call? List the concrete types on both sides of each interface.
  2. Write an integration test — replace stubs with real implementations. Wire the new component into the actual pipeline it will participate in. The test should exercise real data flow across at least one boundary (e.g., coordinator → adapter, adapter → sink → storage).
  3. Run the integration test — if it fails, the failures reveal integration gaps. Each gap becomes a new scenario (loop back to Step 2).
  4. Present integration results — show the user which boundaries were verified and which gaps were found.

Key principle: if the new component was tested only with MockX or StubY, at least one test must replace those with the real X or Y. A component that only passes with mocks has not been verified.

This step catches type mismatches between components designed in parallel, persistence paths that diverge between test and production, and missing contracts in adapters tested without their real pipeline.

Step 6: Generate Field Guide

After all scenarios pass and integration is verified, generate a field guide that maps the system design to the current implementation. This step is conditional — only run it if implementation exists beyond docs/. If the project is still in the ARCHITECT phase with no code, skip this step entirely.

The field guide is a pragmatic artifact (Invariant 3): agent-generated, user-validated. It is not a phase output with an epistemic gate — it is a reference document that helps developers build their own understanding of the system.

Map Modules to Implementation

For each module in the system design:

  • Implementation state — does code for this module exist? Is it complete, partial, or planned?
  • Code location — which files, directories, and patterns constitute this module in the codebase?
  • Domain concept mapping — for each domain model concept owned by this module, where does it manifest in code? (type names, function names, directory structure)

Surface Design Rationale

For each module, include the "why" behind structural choices that code alone cannot carry:

  • Why this module boundary exists (trace to ADR or invariant via the system design's provenance chain)
  • Key constraints or tradeoffs encoded in the implementation
  • Integration points with neighboring modules — what crosses the boundary and in what form

Mark Settled vs. In-Flux

Distinguish areas of the system by stability:

  • Settled — stable, unlikely to change. The design decisions behind this area are well-understood and the implementation matches the design.
  • In flux — under active development, pending decisions, or likely to change in upcoming work. Developers should invest understanding cautiously here.

This prevents developers from building deep mental models of areas that are about to change.

Write the Field Guide

Write to ./docs/references/field-guide.md. Create the ./docs/references/ directory if it doesn't exist.

# Field Guide: [Project Name]

**Generated:** [date]
**Derived from:** System Design v[N], current implementation

## How to Use This Guide

This guide maps the system design's modules to their current implementation state. It is a reference — consult the entry for the module you're working in or exploring. For the overall architecture, read the system design. For routing to the right document, read ORIENTATION.md.

## Module: [Name]

**Implementation state:** Complete / Partial / Planned
**Code location:** `[paths]`
**Stability:** Settled / In flux

### Domain Concepts in Code

| Concept | Code Manifestation | Location |
|---------|-------------------|----------|
| [domain term] | [type/function/pattern] | [file path] |

### Design Rationale

[Why this module exists, what constraints it encodes, what tradeoffs were made — things the code alone doesn't explain]

### Key Integration Points

- [Neighbor module] — [what crosses the boundary, in what form]

---

[repeat for each module]

Reflexive Updates

If the field guide already exists and the implementation has changed significantly during this build cycle, regenerate it to reflect the current state. Module-to-code mappings go stale when files move, types rename, or responsibilities shift during build.

Post-Build Housekeeping

After all scenarios pass, integration is verified, and the field guide is generated:

  1. Regenerate ORIENTATION.md — the BUILD milestone reflects the completed implementation (ADR-021). Update the current state section with what was built.

  2. Consider /rdd-conform audit — the RDD skills may have evolved since the project's artifacts were last produced. A post-build conformance audit verifies the full artifact corpus still aligns with current skill expectations.


STRUCTURE VS. BEHAVIOR

There are two kinds of changes. Always be making one kind or the other, but never both at the same time.

Kind Nature Risk Commit prefix
Structure How code is organized (rename, extract, inline, move) Low — reversible refactor:
Behavior What code computes (new feature, bug fix) Higher — effects in the world feat: or fix:

In practice:

  • The "green" step is a behavior change — commit it as feat: or fix:
  • The "refactor" step is a structure change — commit it as refactor:
  • Never mix them in one commit
  • Structure-only commits should be trivially reviewable

TIDYING: MAKE THE CHANGE EASY, THEN MAKE THE EASY CHANGE

Before implementing a scenario, ask: "What about the current code makes this scenario harder to implement? What can I tidy to make it easier?"

Also ask: "Does any existing code contradict the ADRs this scenario implements?" ADR conformance is architectural tidying — resolve contradictions as refactor: commits BEFORE implementing the scenario as a feat: commit. This preserves structure-vs-behavior separation.

If tidying would reduce total effort, tidy first — as a separate commit. If not, proceed directly.

The Tidyings

Small structural improvements, minutes not hours:

  • Guard clauses — exit early, reduce nesting
  • Dead code — remove it entirely
  • Normalize symmetries — same logic, same expression
  • Explaining variables — name complex subexpressions
  • Explaining constants — replace magic numbers
  • Chunk statements — blank lines between logical blocks
  • Reading order — arrange for human comprehension
  • Cohesion order — group elements that change together
  • Move declaration and initialization together — keep setup adjacent to usage
  • Extract helper — create abstractions when vocabulary expands (not before)
  • One pile — when confused, inline everything into one place first, then separate cleanly

Stop tidying when the change becomes easy. More than an hour of tidying before a behavior change likely means lost focus.

The Exhale-Inhale Rhythm

Every feature consumes flexibility. Tidying restores it.

  • Exhale — implement the scenario (behavior change, move right)
  • Inhale — tidy the code (structure change, restore options)

Alternate. This prevents the slow decline where each feature is harder than the last.


COMPOSABLE TESTS

Optimize the test suite, not individual tests.

The N x M Problem

For orthogonal dimensions — say 4 computation methods x 5 output formats — don't write 20 tests. Write N + M + 1:

  • N tests for one dimension (holding the other constant)
  • M tests for the other dimension (holding the first constant)
  • 1 integration test proving correct wiring

Test Pruning

When test2 cannot pass if test1 fails, they share redundant coverage. Simplify test2 — remove the shared setup and assertions. The composed suite maintains predictive power with less repetition.

Test Principles

  • Each test earns its place — if removing it wouldn't reduce confidence, remove it
  • Tests compose for confidence — a test that looks "incomplete" in isolation may be sufficient when composed with others
  • Acceptance tests are the outer ring — they verify scenarios. Unit tests verify implementation. Don't duplicate assertions across rings.

DOMAIN VOCABULARY IN CODE

The domain model is your naming authority. Enforce it:

  • Class/type names match glossary concepts
  • Method/function names match glossary actions
  • Variable names use glossary terms, not synonyms
  • Test names read as domain sentences using glossary vocabulary

If you need a name not in the glossary, the domain model needs updating first. Flag it to the user rather than inventing terms.


SMALL, SAFE STEPS

Most software design decisions are easily reversible. Therefore:

  • Don't over-invest in avoiding mistakes — start moving and correct course
  • One element at a time — no sudden moves
  • Each change should be obviously correct in isolation
  • If a step feels too big, decompose it further

The expert pattern: break big problems into smaller problems where the interactions are also simple.


WHEN BUILDING REVEALS FLAWS

If implementation reveals that:

  • A scenario is ambiguous — stop and clarify with the user before continuing
  • A decision was wrong — flag it. The user may need to go back to /rdd-decide and update the ADR
  • A concept is missing from the domain model — flag it. The glossary needs updating via /rdd-model
  • An assumption from research was incorrect — flag it. The user may need to revisit /rdd-research
  • A document contradicts current invariants — flag it. The document needs a supersession note. Do NOT follow the document's guidance if it contradicts an invariant. This is the most insidious failure mode: old documents re-propagating dead ideas into new code.

Building is the ultimate test of understanding. Discovering flaws here is expected, not a failure.


STEWARDSHIP CHECKPOINTS

Architecture drifts during build — one scenario at a time, each locally correct, globally accumulating. These checkpoints catch drift before it compounds.

When to Check

At natural scenario boundaries: completing a logical group of scenarios that forms a coherent feature or crosses a component boundary. You identify these boundaries — they're moments when it's worth pausing to look at the whole, not just the part.

Tier 1: Lightweight Stewardship Check

A quick structural scan. For each module that received new code in this scenario group:

  1. Responsibility conformance — count the responsibilities this module now handles. Compare against the system design's responsibility matrix. Flag any concept or action landing in a module that doesn't own it.
  2. Dependency direction — check import/dependency directions against the system design's dependency graph. Flag violations (wrong direction, unexpected edges, cycles).
  3. Cohesion — is new code landing in the module the design assigns it to? Or is it gravitating toward a "convenient" module because that's where the calling code lives?
  4. Size signal — is any single file or class growing disproportionately relative to its peers? Not a hard metric, but a smell.
  5. Fitness Criteria — check against the measurable properties defined in the system design's Fitness Criteria table.
  6. Test quality — for tests written in this scenario group:
    • Vacuous tests — does every test assert something meaningful about actual code behavior? A test that only exercises mocks without touching real code is not a test.
    • Assertion roulette — does any test contain multiple unrelated assertions without clear messages? Each test should verify one cohesive behavior.
    • Boundary coverage — for each module boundary crossed in this scenario group, does an integration test exist that uses real types on both sides (not stubs)? Check against the system design's Test Architecture table.
    • Wiring verification — do acceptance tests exercise the real call chain, or are they testing through mocks that could mask integration failures?

Present a brief conformance summary:

Module Designed Responsibilities Actual Responsibilities Status
... ... ... Conforming / Drifting / Violation

If all clear → continue to next scenario group. If flags → can the issue be resolved with a small structural tidying (extract, move, rename)? If yes, tidy as a refactor: commit and continue. If no, escalate to Tier 2.

Tier 2: Deep Architecture Review

Triggered when Tier 1 flags can't be resolved with simple tidying — the code is drifting from the design in a way that suggests the design or the code needs non-trivial adjustment.

Run four focused analyses (not a full codebase audit — targeted to the flagged area):

  1. Coupling analysis — map actual dependencies in the flagged module(s) against the system design's dependency graph. Where do they diverge? Are new coupling paths emerging that the design didn't anticipate?
  2. Intent-implementation alignment — is the flagged module doing what the system design says it should? Or has its actual responsibility expanded beyond its designed purpose?
  3. Invariant enforcement — are the domain model invariants being enforced in the locations the system design specifies? Are enforcement gaps emerging?
  4. Test-code correspondence — for the flagged area, evaluate whether the test suite actually verifies the code:
    • Are critical code paths tested, or are only trivial paths covered?
    • Do integration tests use real types at boundaries, or do mocks mask wiring failures?
    • For each boundary in the system design's Test Architecture table that was crossed, does a real integration test exist?
    • Are there tests that pass even when the code under test is deleted or broken (indicating the test exercises mocks, not code)?

Produce findings using the stewardship format:

### Finding: [Brief title]

**Observation:** [What was found — concrete, with file paths and line ranges]
**Pattern:** [Named architectural pattern or anti-pattern this relates to]
**Tradeoff:** [What this optimizes for vs. what it costs]
**Question:** [Socratic question using "what" framing]
**Stewardship:** [What a good steward would do]

If Tier 2 reveals a code problem → fix the code (tidying or implementation adjustment). If Tier 2 reveals a design problem → the system design needs updating. Trigger a Design Amendment.

The Reflexive Loop

build scenario group
  → Tier 1 check
    → clean? → continue
    → flag? → can fix with tidying? → tidy (refactor: commit), continue
             → structural issue? → Tier 2 deep review
               → code problem? → fix code
               → design problem? → Design Amendment → user approval → update design → continue

DESIGN AMENDMENTS

When building reveals that the system design needs to change — not the code, but the architectural design itself — use this process. Never silently modify the system design. This process mirrors the amendment process defined in /rdd-architect; if one is updated, both should be kept consistent.

When to Amend

  • Tier 2 review reveals the design was wrong (not just the code)
  • A scenario requires capability that doesn't fit the current module decomposition
  • A dependency that the design prohibits turns out to be necessary
  • An invariant has changed (triggers backward propagation via /rdd-model)

Amendment Process

  1. Propose — state clearly what changes in the system design, why, and what triggered it (which scenario, which Tier 2 finding, what new information)
  2. Trace provenance — which invariants, ADRs, or fitness criteria are affected? Follow the provenance chain to understand what's load-bearing vs. what's a judgment call
  3. Present to user — the user approves or rejects the amendment. If rejected, adapt the code to conform to the existing design or flag for deeper discussion
  4. Apply — update ./docs/system-design.md with the change
  5. Log — add an entry to the Design Amendment Log in the system design document

Amendment Log Entry

| # | Date | What Changed | Trigger | Provenance | Status |
|---|------|-------------|---------|------------|--------|
| N | YYYY-MM-DD | [description] | [scenario/finding] | [affected invariants/ADRs] | Accepted/Rejected |

Provenance Decision Tree

When a design constraint feels wrong, follow the provenance chain in the system design:

  • Traces to a researched invariant → load-bearing. Do not amend without revisiting /rdd-research. The constraint exists because research established it.
  • Traces to an ADR judgment call → changeable. Propose a Design Amendment with a rationale that supersedes the original ADR reasoning.
  • Traces to a design-phase allocation → freely changeable. Propose a Design Amendment. These are architectural judgment calls, not research-backed constraints.
  • No provenance → accidental. Change freely and add provenance to the replacement to prevent future confusion.

IMPORTANT PRINCIPLES

  • Read before writing: Never modify code you haven't read. Understand existing structure first.
  • One kind of change at a time: Structure OR behavior, never both in the same commit.
  • Make the change easy, then make the easy change: Preparatory tidying is not gold-plating — it's the fastest path when structure blocks progress.
  • Verify before moving on: Run tests after every change. If you haven't seen it run, it's not working.
  • Match existing patterns: Follow the codebase's conventions. Don't introduce new ones.
  • Minimize coupling: Changes should stay local. If a change ripples across the codebase, the structure needs tidying.
  • Stop when it's easy: Tidy enough to enable the scenario, no more. Resist the urge to clean the whole codebase.

NEXT PHASE

When all scenarios are implemented and the user is ready to proceed, /rdd-synthesis is available as an optional terminal phase. Use it when the writer wants to extract publishable insight from the RDD cycle. If the user does not want synthesis, the build phase is the terminal phase — the pipeline is complete.

Weekly Installs
15
First Seen
Feb 18, 2026
Installed on
trae15
antigravity15
replit15
codebuddy15
command-code15
claude-code15