# Design Tracker

> Record a project design decision into .claude/docs/DESIGN.md through the shared typed writer. Use when the user says "record this", "add to design", "document this", "記録して", or asks what has been decided so far — and when a design decision has just been made and should not be lost.

- Skill: `del-taiseiozaki/design-tracker` (Agent Skill)
- Install (CLI): `npx skillmds@latest add del-taiseiozaki/design-tracker`
- Raw SKILL.md: https://api.skillmd.com/api/skills/del-taiseiozaki/design-tracker/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: DeL-TaiseiOzaki (https://skillmd.com/u/del-taiseiozaki)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/del-taiseiozaki/design-tracker

---


# Design Tracker Skill

## Purpose

This skill keeps the project's 要件定義書 (`.claude/docs/DESIGN.md`) current.
DESIGN.md is the **macro** requirements & design document (*what* the project builds
and *why*); micro work progress lives in `PROGRESS.md`. It covers:
- Background & purpose, scope
- Functional & non-functional requirements
- Architecture (including agent roles)
- Tech stack choices and their rationale
- Constraints, key decisions, and open questions

## How This Skill Is Reached

Read this before relying on it: **nothing in the repository activates this skill
automatically.** The description above is the entire trigger surface, and it works
only through the runtime's own description-based skill selection.

- **Explicit request** — "record this", "add to design", "update DESIGN",
  "記録して", `/design-tracker`. This is the reliable path.
- **Model invocation** from the description, at the runtime's discretion.
  Claude Code discovers the skill through `.claude/skills` → `.claude/skills`;
  Codex through `.codex/config.toml`'s `path = ".claude/skills/design-tracker"`.
- **No hook mechanism.** `.claude/hooks/` contains no design-tracker branch, and
  the words a design conversation actually uses (設計 / design / architecture)
  are claimed by `CODEX_TRIGGERS` in `agent-router.py`, which injects a *Codex*
  consultation nudge instead. `check-codex-before-write.py` also nudges when
  `DESIGN.md` is edited, but it blocks nothing — a freehand edit still lands.

So an agent in a design conversation must decide to record the decision; no
automation will decide for it. If a decision was made and this skill was not
reached, record it at the next checkpoint — `/checkpointing` describes recording
decisions via `update_design.py` for exactly that reason.

> Previous versions of this file promised proactive, automatic activation
> ("Do NOT wait for user to ask"). That promise was enforced by nothing, so it
> has been removed rather than left as a false statement in a normative
> document.

## Workflow

### Recording Decisions

1. Decide whether this *is* a design decision, and whether it is already
   recorded. Grep the target table (e.g. `grep -n "^| " .claude/docs/DESIGN.md`)
   instead of reading the whole document — the writer locates the table and
   heading itself.
2. Extract the decision from the conversation.
3. Map it to a section and to that section's **typed input key** (table below).
4. Write a per-invocation input JSON and run the shared writer (see Mechanical
   Update).

### Sections to Update

DESIGN.md uses these fixed sections (Japanese + English headings). Every target
has a typed input key, so no markdown row is ever hand-written:

| Conversation Topic | Target Section | Input key | Fields |
|-------------------|----------------|-----------|--------|
| Project goals, problem, stakeholders | `## 背景・目的 (Background & Purpose)` | `section_updates` | `heading`, `content` (prose) |
| What is / isn't covered | `## スコープ (Scope)` — In / Out of Scope | `section_updates` | `heading`, `content` (bullets) |
| A feature the system must provide | `## 機能要件 (Functional Requirements)` | `requirements` | `id`, `requirement`, `priority`, `notes` |
| Performance, security, availability, maintainability targets | `## 非機能要件 (Non-Functional Requirements)` | `nfr` | `category`, `requirement`, `metric` |
| System structure, components, agent roles | `## アーキテクチャ (Architecture)` — overview + Agent Roles table | `section_updates` for the overview prose, `agent_roles` for the table | `agent`, `role`, `responsibilities` |
| Library / framework / infra choice + why | `## 技術選定 (Tech Stack & Rationale)` | `tech_choices` | `area`, `technology`, `rationale`, `alternatives` |
| Hard limits (technical, org, compatibility) | `## 制約 (Constraints)` bullets | `section_updates` | `heading`, `content` (bullets) |
| Why we chose X over Y (significant) | `## Key Decisions` | `decisions` | `decision`, `rationale`, `alternatives` (the date is stamped by the writer) |
| Things to do later, unresolved questions | `## TODO / Open Questions` | `section_updates` | `heading`, `content` (checklist) |

The four prose sections have no typed key **because they have no fixed shape** —
their content is a sentence or a bullet an agent writes, and there is no correct
rendering for a script to own. Every section that *does* have a fixed shape (a
table) has a typed key, and the writer refuses table rows passed through
`section_updates`: it exits `2` naming the key you should have used, so the
unescaped-cell and orphaned-row corruptions are now unreachable from this skill.

Choosing the section stays judgment. Rendering the row does not.

### Mechanical Update

Use a **per-invocation** input path, never a shared one: this skill can run
concurrently with other work (and inside a subagent), and two recordings sharing
one input file overwrite each other. Resolve the path from the shared workspace
registry rather than deriving it by hand, so the slug rule is the same one every
other skill uses:

```bash
python3 .claude/skills/_shared/workspace.py \
  --skill design-tracker --title "{decision topic}" --create
```

That prints one JSON object whose `paths.design_input` is
`.claude/logs/design-input-{slug}.json`. Use it verbatim as `${input}` below.
Exit 0 resolved/created · 1 bad args · 3 `.claude/logs/` could not be created.

Example input (use only the keys you need):

```json
{
  "decisions": [
    {"decision": "Use ReAct pattern", "rationale": "Better tool-use control", "alternatives": "Function calling only"}
  ],
  "tech_choices": [
    {"area": "Agent loop", "technology": "ReAct", "rationale": "Tool-use control", "alternatives": "Function calling only"}
  ],
  "section_updates": [
    {"heading": "## TODO / Open Questions", "content": "- [ ] Evaluate streaming support"}
  ]
}
```

Run dry-run, read the preview, then apply:

```bash
python3 .claude/skills/_shared/update_design.py --input "${input}"
# Read the file named by preview_file in the JSON output, then:
python3 .claude/skills/_shared/update_design.py --input "${input}" --apply --require-change
```

**Completion test.** `"ok": true` alone is not it — a duplicate or empty entry
used to return `ok: true` with `result: "no-op"` and exit `0` while nothing was
written. Require all of:

- `result == "applied"`, and
- `decisions_appended > 0` **or** some `rows_appended` value `> 0` **or**
  `sections_updated` non-empty.

Always report `skipped_duplicates` when it is non-zero — that is the honest
"already recorded" answer. `--require-change` makes the writer enforce the same
thing: a no-op becomes `ok: false` and exit `2`, so "recorded" can never be
reported for a run that wrote nothing.

Other exit codes: `1` bad arguments or input-schema violation · `2` DESIGN.md
structure invalid or missing (run `/init` first), a duplicate requirement ID, a
table row passed through `section_updates`, or a no-op under `--require-change` ·
`3` DESIGN.md changed while the writer held it, or the write failed — re-read and
retry.

## Output Format

When recording, report concisely:
- What was recorded, and into which DESIGN.md section
- The writer's `result`, the appended counts, and `skipped_duplicates`
- Anything you decided *not* to record, and why

## Language Rules

- **Reasoning / code examples**: English
- **Document content**: English (technical terms); Japanese descriptions are
  acceptable to match the existing 要件定義書 headings
- **Report**: follow the surrounding session's language

