---
name: code-writing
domain: dev
description: |
  [METHODOLOGY] Universal quality coding process (plan, TDD, reviews).
  Preloaded by dev-backend-engineer, dev-frontend-engineer, dev-fullstack-engineer
  agents.
---

# Code Writing

## Phase 1: Preparation

1. **Parse Requirements**
   - Extract what needs to be built from user message or passed acceptance criteria
   - Clarify ambiguities — ask user if unclear
   - Formulate acceptance criteria (what "done" looks like)

2. **Read Project Context (Graceful)**

   **Working on a task?** Read all files listed in the task's "Context" section — it already specifies everything needed.

   **Standalone (no task file)?** Read (skip if missing):
   - `.claude/skills/project-knowledge/references/project.md` — project overview
   - `.claude/skills/project-knowledge/references/architecture.md` — system structure
   - `.claude/skills/project-knowledge/references/patterns.md` — project conventions

   Then read `.claude/skills/project-knowledge/SKILL.md` (if exists).
   Consider which domain-specific guides are relevant to your task and read those
   (e.g., `architecture.md` Data Model section for DB work, `ux-guidelines.md` for UI tasks).

   **No project patterns?** Apply baseline from [universal-patterns.md](references/universal-patterns.md) — naming, error handling, structure.

3. **Brainstorm Approaches** (for non-trivial tasks)

   **Skip this step if:** single-file change, obvious fix, user gave exact implementation instructions.

   **Do this step if:** multiple valid approaches exist, architectural decision needed, new feature, unfamiliar area.

   Explore 2-3 implementation approaches before writing code:

   | Approach | Pros | Cons | Complexity |
   |----------|------|------|------------|
   | A: ... | ... | ... | Low/Med/High |
   | B: ... | ... | ... | Low/Med/High |

   For each approach consider:
   - Does it follow existing project patterns?
   - How much code needs to change?
   - What breaks if it's wrong? (blast radius)
   - Testing difficulty?

   **Pick the approach** with clear reasoning. Default to simplest unless simplest has obvious drawbacks.
   If genuinely uncertain — present options to user, let them decide.

   This step prevents: over-engineering, wrong abstractions, rework after half-implementation.

4. **Analyze & Review Approach**

   Before coding, output your findings:
   - Grep for usages of code to be modified
   - Read all files that will be changed
   - Verify solution follows project patterns (or universal patterns)
   - Identify existing code that can be reused
   - If modifying existing code, run existing tests for the area to establish baseline
   - Reversibility check: Can changes be rolled back without data loss?
     For M/L features: consider feature flags for new behavior.
     For DB migrations: ensure rollback works.
     For external integrations: adapter pattern (easy to swap/disable).
     Principle: Adopt existing code > Adapt existing patterns > Invent new.

   If concerns → discuss with user before proceeding.

**Checkpoint:** List completed preparation steps (including chosen approach if brainstorm was done) before moving to implementation.

## Phase 2: Implementation (TDD)

1. **Write Tests First**

   **Before writing tests**, read [testing-guide.md](references/testing-guide.md) — when to write which test type, test structure.

   - Write tests for: business logic, validations, transforms, error handling. Skip trivial code without logic (simple getters, one-liners, configs)
   - Write tests for requirements and edge cases
   - Tests should fail initially (no implementation yet)
   - One test = one scenario, test behavior not implementation
   - If mocking >3 dependencies → wrong test type, use integration test

2. **Write Code**
   - Implement to pass tests
   - Follow project patterns (from Phase 1) or apply baseline from [universal-patterns.md](references/universal-patterns.md)
   - If tech-spec Complexity Classification is "Product": prefer simplest working solution, use existing patterns. New abstractions require explicit justification.
   - For risky integrations: wrap behind a toggle/config flag if feasible
   - Use env vars for secrets, validate inputs at boundaries
   - Handle edge cases, comment WHY not WHAT

3. **Run Tests**
   - All new tests pass
   - Fix any failures

**Checkpoint:** List implemented functionality and test results.

## Phase 3: Post-work

1. **Run Lint/Format**
   - Run project's linter and formatter before reviews

2. **Run Relevant Tests**
   - Tests for files changed
   - Tests mentioned in task (if applicable)
   - Save full test suite for end of feature

3. **Smoke Verification** (if task has Verification Steps → Smoke or User)

   Execute each command from the Smoke section. Record results in decisions.md Verification section.
   If a check fails — fix the code before proceeding to reviews.
   If the task has User checks — ask the user to verify, wait for confirmation.

   Smoke catches integration bugs that mocked tests miss:
   real API responses, library initialization, config validity.

4. **Run Reviews** (launch in parallel)

   **Reviewer selection:**
   - Working on a task file → run reviewers from the task's "Reviewers" section
   - Standalone (no task file) → default: code-reviewer, security-auditor, test-reviewer

   For each reviewer:
   1. Spawn subagent via Task tool (subagent_type = reviewer name, e.g. `code-reviewer`)
   2. Pass: git diff of changes, path to task file, path to tech-spec, path to user-spec
   3. Reviewer loads its own skill automatically (via agent frontmatter `skills:`)
   4. Report path: from the task's "Reviewers" section (or `logs/working/` if standalone)

   Reviewers write JSON reports to `logs/working/task-{N}/{reviewer-name}-{round}.json`.
   `{N}` = task number from task file; `"standalone"` if no task file.
   On re-review: new file with incremented round number, old file stays.

5. **Process Findings**

   Evaluate each finding on merit — severity is metadata, not a filter.
   A valid minor fix still improves quality. Reason: skipping valid findings
   silently degrades the codebase over time.

   For each finding:
   - **Valid, improves code** → apply (any severity: critical, major, minor, low)
   - **Disagree or uncertain** → discuss with user (explain reasoning)
   - **Out of scope** → skip, note in findings log

   Produce a findings log:
   | # | Source | Severity | Finding | Action | Reason |
   Each finding appears in this table — transparent decision trail.

   After applying fixes → re-run tests → re-run the reviewer(s) that reported them.
   Limit: 3 review iterations. If findings remain after round 3 → ask user.
   Reason: fixes can introduce new issues — a second pass catches regressions.

**Checkpoint:** List post-work steps completed.

## Self-Verification

Verify each item before marking complete. If any item fails, return to the relevant phase.

- [ ] All phases completed (Preparation, Implementation, Post-work)
- [ ] Tests pass
- [ ] Smoke verification executed (if task had Smoke/User checks)
- [ ] Each reviewer finding evaluated and logged
- [ ] Findings log table produced
- [ ] Review JSON reports saved to `logs/working/task-{N}/`

