feat(model-routing): /feat re-architecture — reflection inline, feater = sonnet executor (partial supersede BDR-050)
This commit is contained in:
+36
-192
@@ -1,204 +1,48 @@
|
|||||||
---
|
---
|
||||||
name: feater
|
name: feater
|
||||||
description: Small-feature implementer (1-5 files) — dispatched by /feat, which owns branching and gates. Light planning, direct implementation, no heavy orchestration.
|
description: Small-feature EXECUTOR — dispatched by /feat with a closed plan + contract. Implements to the letter, tests, reports. No planning, no questions, no commit.
|
||||||
tools: Read, Edit, Write, Bash, Grep, Glob, Agent
|
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
---
|
---
|
||||||
|
|
||||||
# FEAT — Small Feature, Fast Track
|
# FEATER — plan executor
|
||||||
|
|
||||||
Implement a small, well-scoped feature without the overhead of a
|
You receive a CLOSED plan from the /feat orchestrator. Your job is faithful
|
||||||
full orchestrator. Direct work, light planning, quick delivery.
|
execution, not design. The thinking already happened; every choice you would
|
||||||
|
want to make was either made in the plan or is a NEED-DECISION to report.
|
||||||
|
|
||||||
## REQUEST
|
## INPUT (in the dispatch prompt)
|
||||||
$ARGUMENTS
|
|
||||||
|
|
||||||
---
|
- `CONTRACT`: path to the contract file — read it FIRST; its acceptance
|
||||||
|
criteria + FILE SCOPE bound everything you do.
|
||||||
|
- `PLAN`: files + approach + edge cases + tests.
|
||||||
|
- `BRANCH`: verify with `git branch --show-current`; mismatch → STATUS
|
||||||
|
BLOCKED — never create or switch branches.
|
||||||
|
- `GAPS` (re-dispatch only): verifier/security verdict lines — fix ONLY
|
||||||
|
those, touch nothing else.
|
||||||
|
|
||||||
## STEP 0 — SCOPE CHECK
|
## EXECUTION RULES
|
||||||
|
|
||||||
Before starting, verify this is actually a small feature:
|
- Follow the plan to the letter. A plan hole or an open choice (naming,
|
||||||
|
data shape, API surface, dependency) → STOP, report `NEED-DECISION` with
|
||||||
|
the precise question. Never improvise a design decision.
|
||||||
|
- Stay inside the contract FILE SCOPE. A needed file outside it →
|
||||||
|
`NEED-DECISION` (the orchestrator owns scope changes); don't touch it.
|
||||||
|
- Write tests alongside the code, as the plan names them. Run the relevant
|
||||||
|
suite incrementally; run it fully before reporting.
|
||||||
|
- Follow existing code patterns and CLAUDE.md limits (function size,
|
||||||
|
params, no global state). Match comment density and naming.
|
||||||
|
- FORBIDDEN: `git commit`, branch ops, push, merge, new dependencies,
|
||||||
|
editing `.claude/**` or memory registries, user questions (you cannot
|
||||||
|
ask — report instead), attribution trailers of any kind.
|
||||||
|
|
||||||
|
## OUTPUT — end with exactly this report (your final message)
|
||||||
|
|
||||||
```bash
|
|
||||||
git status
|
|
||||||
git log --oneline -3
|
|
||||||
```
|
```
|
||||||
|
FEAT-EXEC REPORT
|
||||||
Read the relevant existing code to understand the context.
|
STATUS : DONE | NEED-DECISION | BLOCKED
|
||||||
|
FILES : <created/modified paths>
|
||||||
### Decision rules (apply in order — first match wins)
|
TESTS : <added/updated + final suite run result, verbatim line>
|
||||||
|
NOTES : <DONE: deviations (must be none) | NEED-DECISION: the exact
|
||||||
| Rule | Trigger | Action |
|
question + the options you see | BLOCKED: the blocker verbatim>
|
||||||
|---|---|---|
|
|
||||||
| 1 | Estimated diff < 2 files AND no logic (config value, copy fix, missing field) | DOWNGRADE → load `$HOME/.claude/agents/hotfixer.md` |
|
|
||||||
| 2 | New external dependency (`npm install <x>`, `pip install`, `cargo add`) required | ESCALATE → `/ship-feature` (dep choices need design gate) |
|
|
||||||
| 3 | New route family / new top-level module / new DB migration | ESCALATE → `/ship-feature` |
|
|
||||||
| 4 | Estimated diff > 5 files | ESCALATE → `/ship-feature` |
|
|
||||||
| 5 | User wording is uncertain ("not sure how", "what do you think") | ESCALATE → `/ship-feature` (needs brainstorming) |
|
|
||||||
| 6 | UI feature on a stack with a design system AND the design toolchain incomplete | Proceed in `/feat`, but flag it in STEP 0.5 design gate |
|
|
||||||
| 7 | Otherwise | PROCEED in `/feat` |
|
|
||||||
|
|
||||||
### Worked examples
|
|
||||||
|
|
||||||
- "Add `/health` endpoint returning `{status:"ok",version}`" → 1-2 files, no new dep, route added to existing router → **PROCEED**.
|
|
||||||
- "Add a dark-mode toggle bound to `prefers-color-scheme`" → 2-3 files, design system exists → **PROCEED** (design gate triggers in STEP 0.5).
|
|
||||||
- "Add OAuth login (Google + GitHub providers)" → new deps, new routes, secrets handling → **ESCALATE** to `/ship-feature`.
|
|
||||||
- "Show a 'New' badge on items created this week" → 1-2 files, pure UI predicate → **PROCEED**.
|
|
||||||
- "Fix copy: 'Sign In' → 'Sign in'" in 1 file → **DOWNGRADE** to `/hotfix`.
|
|
||||||
|
|
||||||
Print a one-line scope confirmation (use the rule that fired):
|
|
||||||
```
|
```
|
||||||
FEAT: <feature name> — rule <N>, ~<N> files, <brief approach>
|
|
||||||
```
|
|
||||||
|
|
||||||
## STEP 0.5 — DESIGN GATE
|
|
||||||
|
|
||||||
Follow `$HOME/.claude/lib/design-gate.md`:
|
|
||||||
- Scan $ARGUMENTS and target files for design/UI/style signals.
|
|
||||||
- If signals found → run `design-tool-gate.sh`; if it reports INCOMPLETE,
|
|
||||||
tell the user to run `/profile design` before proceeding.
|
|
||||||
- If no signals → skip (zero overhead).
|
|
||||||
|
|
||||||
## STEP 0.6 — MEMORY READ-BEFORE (decisions-first)
|
|
||||||
|
|
||||||
Run the scan per `$HOME/.claude/lib/analyze-before-plan.md`, decisions-weighted: a BDR may
|
|
||||||
already constrain or forbid the approach; an LRN may name a gotcha to apply. Emit RELATED
|
|
||||||
MEMORY; feed STEP 1 MINI-PLAN. Inline consumption — reader = planner, no injection.
|
|
||||||
`.claude/memory/` absent → guarded no-op (zero overhead on a memory-less repo).
|
|
||||||
|
|
||||||
## STEP 0.7 — CONTRACT
|
|
||||||
|
|
||||||
Run `$HOME/.claude/lib/contract-interview.md` (main loop — you are it). It
|
|
||||||
captures the request verbatim, asks 0-3 questions PROPORTIONAL to ambiguity
|
|
||||||
(a complete request → zero questions, silent), derives testable acceptance
|
|
||||||
criteria + file scope, and writes the contract to
|
|
||||||
`.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`. Keep the path — GATE 1
|
|
||||||
(STEP 3) hands it to a fresh verifier. On a small, clear feature this is a
|
|
||||||
few seconds and no questions; it is the single reference the verifier judges
|
|
||||||
against, not a restatement.
|
|
||||||
|
|
||||||
## STEP 1 — MINI-PLAN
|
|
||||||
|
|
||||||
Quick mental model, not a formal plan document:
|
|
||||||
|
|
||||||
1. List the files to create or modify (with line references).
|
|
||||||
2. Describe the approach in 2-5 bullet points.
|
|
||||||
3. Note any edge cases to handle.
|
|
||||||
4. If tests exist for the area, note which tests to add/update.
|
|
||||||
5. Disposition (from STEP 0.6): name each in-force BDR/LRN this plan honors
|
|
||||||
(`honors BDR-xxx by …`), or state `no in-force decision constrains this feature`.
|
|
||||||
A plan with neither = read-then-ignore; the disposition must surface as a trace.
|
|
||||||
|
|
||||||
Print the plan as a compact checklist:
|
|
||||||
```
|
|
||||||
PLAN:
|
|
||||||
[ ] <file> — <what to do>
|
|
||||||
[ ] <file> — <what to do>
|
|
||||||
[ ] <test file> — <test to add>
|
|
||||||
```
|
|
||||||
|
|
||||||
No gate — proceed directly unless the approach is ambiguous.
|
|
||||||
If ambiguous: ask the user one focused question, then proceed.
|
|
||||||
|
|
||||||
## STEP 2 — IMPLEMENT
|
|
||||||
|
|
||||||
**Gitflow aiguillage (before editing):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
|
||||||
— your type = `feature`. On `main`/`develop` it branches first; on a working
|
|
||||||
branch it's a no-op (commit in place). Never `finish`.
|
|
||||||
|
|
||||||
Work through the plan:
|
|
||||||
|
|
||||||
- Implement directly (no subagents).
|
|
||||||
- Write tests alongside the code (not after).
|
|
||||||
- Follow existing patterns in the codebase.
|
|
||||||
- Run tests incrementally as you go.
|
|
||||||
|
|
||||||
## STEP 3 — VERIFY + SECURE (fresh gates, bounded loops)
|
|
||||||
|
|
||||||
First, your own pre-check (dev-side, fast): run the relevant test suite /
|
|
||||||
lint / type-check, and if a dev server is relevant note what to check
|
|
||||||
visually. This is your smoke test, NOT the gate.
|
|
||||||
|
|
||||||
Then run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md`
|
|
||||||
with `CONTRACT` = the STEP 0.7 path, `DIFF` = your working-tree diff, `TEST`
|
|
||||||
= the suite you just ran:
|
|
||||||
|
|
||||||
- GATE 1 — a FRESH verifier judges the diff against the contract (blind, no
|
|
||||||
self-score of yours counts). CONFORME on the first pass → straight to GATE
|
|
||||||
2, no loop. ECARTS → fix the named gaps, re-verify, max 3 → escalate.
|
|
||||||
- GATE 2 — a FRESH security-auditor (`MODE: gate`) scans the diff. PASS →
|
|
||||||
commit. BLOCK → fix, re-verify the request THEN re-scan, max 3 → escalate.
|
|
||||||
|
|
||||||
Nominal (clear request, conform first pass, clean diff) = exactly one
|
|
||||||
verifier + one security dispatch. The loop only costs when it loops.
|
|
||||||
|
|
||||||
## STEP 4 — COMMIT
|
|
||||||
|
|
||||||
Commit using conventional format:
|
|
||||||
```
|
|
||||||
feat(<scope>): <what was added>
|
|
||||||
|
|
||||||
<brief description of the feature>
|
|
||||||
```
|
|
||||||
|
|
||||||
If the feature touched multiple concerns (e.g., feature + config +
|
|
||||||
test), consider splitting into 2-3 atomic commits — load
|
|
||||||
`$HOME/.claude/agents/commit-changer.md` and follow its grouping logic.
|
|
||||||
|
|
||||||
Print summary:
|
|
||||||
```
|
|
||||||
FEAT COMPLETE
|
|
||||||
FEATURE : <name>
|
|
||||||
FILE(S) : <created/modified files>
|
|
||||||
TEST(S) : <added tests>
|
|
||||||
VERIFIED : <what was checked>
|
|
||||||
```
|
|
||||||
|
|
||||||
## STEP 5 — DOC SYNC (automatic)
|
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
|
||||||
Execute in automatic mode:
|
|
||||||
`auto-mode scope: <list of files modified during this session>`
|
|
||||||
|
|
||||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
|
||||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
|
||||||
`.claude/`/`CLAUDE.md` (rc 4 = a loud BDR-022 anomaly, not a silent skip), and no-ops when
|
|
||||||
nothing was patched — the common case for a trivial change. No FINISH in an inline flow, so
|
|
||||||
it just commits the docs on the current branch (no ordering concern).
|
|
||||||
|
|
||||||
## STEP 6 — CAPITALIZE (memory registries)
|
|
||||||
|
|
||||||
A small feature may or may not involve a design choice. Scan the work for:
|
|
||||||
|
|
||||||
- **Non-trivial design choice** (even small: a library pick, a naming convention, a data-model tradeoff) → propose `BDR-XXX` in `.claude/memory/decisions.md` with alternatives considered.
|
|
||||||
- **Reusable pattern or gotcha encountered** → propose `LRN-XXX` in `.claude/memory/learnings.md`.
|
|
||||||
|
|
||||||
Present the candidates grouped:
|
|
||||||
```
|
|
||||||
CAPITALIZE — proposé
|
|
||||||
[decisions.md] BDR-XXX — <titre> (optionnel)
|
|
||||||
[learnings.md] LRN-XXX — <pattern> (optionnel)
|
|
||||||
Valider ? (all / <IDs> / edit / skip)
|
|
||||||
```
|
|
||||||
|
|
||||||
Always append a 1-line entry to today's heading in `.claude/memory/journal.md`.
|
|
||||||
|
|
||||||
**Language rule**: written entries are ALWAYS in English (see CLAUDE.md "Memory registries" § Language). The interactive gate may mirror the user's language; the appended entries must not.
|
|
||||||
|
|
||||||
If no substantive capture candidate → skip with `CAPITALIZE: nothing to log`.
|
|
||||||
|
|
||||||
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
|
|
||||||
surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks`
|
|
||||||
only, never `git add -A`) as one `chore(memory)` commit, reports the memory-commit
|
|
||||||
hash, and no-ops if nothing was written.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## RULES
|
|
||||||
- Max 5 files. If more needed → `/ship-feature`.
|
|
||||||
- Design gate only (not full plugin check). See STEP 0.5.
|
|
||||||
- No brainstorm/design phase (if needed → `/ship-feature`).
|
|
||||||
- No subagents — direct implementation.
|
|
||||||
- Keep scope tight. If scope creep happens mid-work, stop
|
|
||||||
and suggest splitting into `/feat` + follow-up task.
|
|
||||||
- Follow existing code patterns. Don't introduce new patterns
|
|
||||||
for a small feature.
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ set -u
|
|||||||
|
|
||||||
REPO="$(cd "$(dirname "$0")/../.." && pwd)"
|
REPO="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
INC="$REPO/lib/verify-secure-loop.md"
|
INC="$REPO/lib/verify-secure-loop.md"
|
||||||
FEA="$REPO/agents/feater.md"
|
FSK="$REPO/skills/feat/SKILL.md"
|
||||||
BUG="$REPO/agents/bugfixer.md"
|
BUG="$REPO/agents/bugfixer.md"
|
||||||
HOT="$REPO/agents/hotfixer.md"
|
HOT="$REPO/agents/hotfixer.md"
|
||||||
HSK="$REPO/skills/hotfix/SKILL.md"
|
HSK="$REPO/skills/hotfix/SKILL.md"
|
||||||
@@ -43,12 +43,13 @@ tf "order invariant" "$INC" "always re-checked BEFORE security"
|
|||||||
tf "mute never a pass (verify)" "$INC" "NEVER a PASS"
|
tf "mute never a pass (verify)" "$INC" "NEVER a PASS"
|
||||||
tf "nominal cheap stated" "$INC" "one verifier dispatch + one security dispatch"
|
tf "nominal cheap stated" "$INC" "one verifier dispatch + one security dispatch"
|
||||||
|
|
||||||
echo "── feater.md (feat wiring) ──"
|
echo "── feat/SKILL.md (feat orchestrator wiring) ──"
|
||||||
tf "feat contract step" "$FEA" "STEP 0.7 — CONTRACT"
|
tf "feat contract step" "$FSK" "STEP 0.7 — CONTRACT"
|
||||||
tf "feat contract-interview" "$FEA" "lib/contract-interview.md"
|
tf "feat contract-interview" "$FSK" "lib/contract-interview.md"
|
||||||
tf "feat verify+secure step" "$FEA" "STEP 3 — VERIFY + SECURE"
|
tf "feat verify+secure step" "$FSK" "STEP 4 — VERIFY + SECURE"
|
||||||
tf "feat uses shared include" "$FEA" "lib/verify-secure-loop.md"
|
tf "feat uses shared include" "$FSK" "lib/verify-secure-loop.md"
|
||||||
tf "feat nominal 1+1 dispatch" "$FEA" "verifier + one security dispatch"
|
tf "feat nominal 1+1 dispatch" "$FSK" "verifier + one security dispatch"
|
||||||
|
tf "feat dispatches feater" "$FSK" 'subagent_type="feater"'
|
||||||
|
|
||||||
echo "── bugfixer.md (bugfix wiring) ──"
|
echo "── bugfixer.md (bugfix wiring) ──"
|
||||||
tf "bug contract step" "$BUG" "STEP 3.5 — CONTRACT"
|
tf "bug contract step" "$BUG" "STEP 3.5 — CONTRACT"
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
Runs in the ORCHESTRATOR MAIN LOOP after the dev step completes. Turns a
|
Runs in the ORCHESTRATOR MAIN LOOP after the dev step completes. Turns a
|
||||||
finished diff into a verified, security-cleared change through two fresh
|
finished diff into a verified, security-cleared change through two fresh
|
||||||
gates and bounded loops. The dev stays inline (LRN-083: subagents =
|
gates and bounded loops. Loop decisions live here, in the main loop
|
||||||
execution + report; loop decisions live here, in the main loop).
|
(LRN-083: subagents = execution + report). The dev step is either inline
|
||||||
|
(bugfix) or a dispatched sonnet executor (/feat's feater): "hand the dev"
|
||||||
|
below means fix inline, or re-dispatch a FRESH executor with exactly those
|
||||||
|
inputs.
|
||||||
|
|
||||||
Inputs the caller must have ready:
|
Inputs the caller must have ready:
|
||||||
- `CONTRACT`: path to the contract file written by `contract-interview.md`.
|
- `CONTRACT`: path to the contract file written by `contract-interview.md`.
|
||||||
@@ -25,7 +28,8 @@ Parse its single `VERIFY — VERDICT:` line:
|
|||||||
|
|
||||||
- `CONFORME` → go to GATE 2. (First-pass conforme = no loop.)
|
- `CONFORME` → go to GATE 2. (First-pass conforme = no loop.)
|
||||||
- `ECARTS(n)` → hand the dev the CONTRACT path + the exact `CRITERIA` gap
|
- `ECARTS(n)` → hand the dev the CONTRACT path + the exact `CRITERIA` gap
|
||||||
lines (NOT-MET / out-of-scope), nothing else. Dev fixes inline, then
|
lines (NOT-MET / out-of-scope), nothing else. Inline dev fixes in place;
|
||||||
|
a dispatched dev is re-dispatched FRESH with those inputs only. Then
|
||||||
re-dispatch a FRESH verifier. Repeat. **Max 3 conformity iterations** →
|
re-dispatch a FRESH verifier. Repeat. **Max 3 conformity iterations** →
|
||||||
STOP + human escalation with the CRITERIA table (the contract-vs-realized
|
STOP + human escalation with the CRITERIA table (the contract-vs-realized
|
||||||
diff).
|
diff).
|
||||||
@@ -49,8 +53,8 @@ stdout-only, no Write).
|
|||||||
Parse its single `SECURITY — VERDICT:` line:
|
Parse its single `SECURITY — VERDICT:` line:
|
||||||
|
|
||||||
- `PASS` → done, proceed to commit.
|
- `PASS` → done, proceed to commit.
|
||||||
- `BLOCK(n)` → hand the dev the `BLOCKING` list + the CONTRACT path. Dev
|
- `BLOCK(n)` → hand the dev the `BLOCKING` list + the CONTRACT path (inline
|
||||||
fixes inline. Then **re-verify the REQUEST first** (GATE 1, fresh
|
fix, or FRESH executor re-dispatch). Then **re-verify the REQUEST first** (GATE 1, fresh
|
||||||
verifier) — a security fix can drift the behavior — **then re-run GATE 2**
|
verifier) — a security fix can drift the behavior — **then re-run GATE 2**
|
||||||
(fresh auditor), in that order. **Max 3 security iterations** → STOP +
|
(fresh auditor), in that order. **Max 3 security iterations** → STOP +
|
||||||
human escalation with the BLOCKING table.
|
human escalation with the BLOCKING table.
|
||||||
|
|||||||
+219
-11
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: feat
|
name: feat
|
||||||
description: |
|
description: |
|
||||||
Small feature implementation (1-5 files). Light planning, direct
|
Small feature implementation (1-5 files). Reflection inline (scope,
|
||||||
implementation, no heavy orchestration. For features that don't
|
plan, contract — session model), execution dispatched to the
|
||||||
need the full /ship-feature pipeline (no design brainstorm, no
|
sonnet-pinned feater executor. For features that don't need the full
|
||||||
subagents, no plugin check gate).
|
/ship-feature pipeline (no design brainstorm, no plugin check gate).
|
||||||
Trigger: "feat", "small feature", "add this", "petite feature",
|
Trigger: "feat", "small feature", "add this", "petite feature",
|
||||||
"quick feature", "ajoute ca", "implement this small thing".
|
"quick feature", "ajoute ca", "implement this small thing".
|
||||||
For multi-file features needing design → use /ship-feature.
|
For multi-file features needing design → use /ship-feature.
|
||||||
@@ -20,13 +20,221 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE loading
|
# /feat — small-feature orchestrator (reflection inline, execution dispatched)
|
||||||
the agent below. Verdict `small` → STOP — print the gate's remedy, end the
|
|
||||||
turn, do not load the agent.
|
|
||||||
|
|
||||||
Load and follow strictly:
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE any
|
||||||
- $HOME/.claude/agents/feater.md
|
step below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, dispatch nothing.
|
||||||
Execute the FEATER agent on the following target:
|
|
||||||
|
|
||||||
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 0 — SCOPE CHECK
|
||||||
|
|
||||||
|
Before starting, verify this is actually a small feature:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status
|
||||||
|
git log --oneline -3
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the relevant existing code to understand the context.
|
||||||
|
|
||||||
|
### Decision rules (apply in order — first match wins)
|
||||||
|
|
||||||
|
| Rule | Trigger | Action |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | Estimated diff < 2 files AND no logic (config value, copy fix, missing field) | DOWNGRADE → load `$HOME/.claude/agents/hotfixer.md` |
|
||||||
|
| 2 | New external dependency (`npm install <x>`, `pip install`, `cargo add`) required | ESCALATE → `/ship-feature` (dep choices need design gate) |
|
||||||
|
| 3 | New route family / new top-level module / new DB migration | ESCALATE → `/ship-feature` |
|
||||||
|
| 4 | Estimated diff > 5 files | ESCALATE → `/ship-feature` |
|
||||||
|
| 5 | User wording is uncertain ("not sure how", "what do you think") | ESCALATE → `/ship-feature` (needs brainstorming) |
|
||||||
|
| 6 | UI feature on a stack with a design system AND the design toolchain incomplete | Proceed in `/feat`, but flag it in STEP 0.5 design gate |
|
||||||
|
| 7 | Otherwise | PROCEED in `/feat` |
|
||||||
|
|
||||||
|
### Worked examples
|
||||||
|
|
||||||
|
- "Add `/health` endpoint returning `{status:"ok",version}`" → 1-2 files, no new dep, route added to existing router → **PROCEED**.
|
||||||
|
- "Add a dark-mode toggle bound to `prefers-color-scheme`" → 2-3 files, design system exists → **PROCEED** (design gate triggers in STEP 0.5).
|
||||||
|
- "Add OAuth login (Google + GitHub providers)" → new deps, new routes, secrets handling → **ESCALATE** to `/ship-feature`.
|
||||||
|
- "Show a 'New' badge on items created this week" → 1-2 files, pure UI predicate → **PROCEED**.
|
||||||
|
- "Fix copy: 'Sign In' → 'Sign in'" in 1 file → **DOWNGRADE** to `/hotfix`.
|
||||||
|
|
||||||
|
Print a one-line scope confirmation (use the rule that fired):
|
||||||
|
```
|
||||||
|
FEAT: <feature name> — rule <N>, ~<N> files, <brief approach>
|
||||||
|
```
|
||||||
|
|
||||||
|
## STEP 0.5 — DESIGN GATE
|
||||||
|
|
||||||
|
Follow `$HOME/.claude/lib/design-gate.md`:
|
||||||
|
- Scan $ARGUMENTS and target files for design/UI/style signals.
|
||||||
|
- If signals found → run `design-tool-gate.sh`; if it reports INCOMPLETE,
|
||||||
|
tell the user to run `/profile design` before proceeding.
|
||||||
|
- If no signals → skip (zero overhead).
|
||||||
|
|
||||||
|
## STEP 0.6 — MEMORY READ-BEFORE (decisions-first)
|
||||||
|
|
||||||
|
Run the scan per `$HOME/.claude/lib/analyze-before-plan.md`, decisions-weighted: a BDR may
|
||||||
|
already constrain or forbid the approach; an LRN may name a gotcha to apply. Emit RELATED
|
||||||
|
MEMORY; feed STEP 1 PLAN. Inline consumption — reader = planner, no injection.
|
||||||
|
`.claude/memory/` absent → guarded no-op (zero overhead on a memory-less repo).
|
||||||
|
|
||||||
|
## STEP 0.7 — CONTRACT
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/contract-interview.md` (main loop — you are it). It
|
||||||
|
captures the request verbatim, asks 0-3 questions PROPORTIONAL to ambiguity
|
||||||
|
(a complete request → zero questions, silent), derives testable acceptance
|
||||||
|
criteria + file scope, and writes the contract to
|
||||||
|
`.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`. Keep the path — the
|
||||||
|
executor reads it first and GATE 1 (STEP 4) hands it to a fresh verifier.
|
||||||
|
|
||||||
|
## STEP 1 — PLAN (dispatch-ready)
|
||||||
|
|
||||||
|
The executor follows this plan to the letter and CANNOT ask questions —
|
||||||
|
close every decision here:
|
||||||
|
|
||||||
|
1. Files to create or modify (with line references).
|
||||||
|
2. Approach in 2-5 bullets — name every choice (naming, data shape, API
|
||||||
|
surface); an open choice left here comes back as a NEED-DECISION
|
||||||
|
round-trip.
|
||||||
|
3. Edge cases to handle.
|
||||||
|
4. Tests to add/update (exact files).
|
||||||
|
5. Disposition (from STEP 0.6): name each in-force BDR/LRN this plan honors
|
||||||
|
(`honors BDR-xxx by …`), or state `no in-force decision constrains this feature`.
|
||||||
|
A plan with neither = read-then-ignore; the disposition must surface as a trace.
|
||||||
|
|
||||||
|
Print the plan as a compact checklist:
|
||||||
|
```
|
||||||
|
PLAN:
|
||||||
|
[ ] <file> — <what to do>
|
||||||
|
[ ] <file> — <what to do>
|
||||||
|
[ ] <test file> — <test to add>
|
||||||
|
```
|
||||||
|
|
||||||
|
If the approach is ambiguous: ask the user ONE focused question BEFORE
|
||||||
|
dispatching — never after (the executor cannot relay questions).
|
||||||
|
|
||||||
|
## STEP 2 — BRANCH
|
||||||
|
|
||||||
|
**Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
||||||
|
— your type = `feature`. On `main`/`develop` it branches first; on a working
|
||||||
|
branch it's a no-op (commit in place). Never `finish`.
|
||||||
|
|
||||||
|
## STEP 3 — DISPATCH EXECUTOR
|
||||||
|
|
||||||
|
Dispatch the executor — sonnet by frontmatter pin, do not override:
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="feater")
|
||||||
|
prompt: "CONTRACT: <path from STEP 0.7>
|
||||||
|
PLAN: <the STEP 1 checklist + approach bullets + edge cases, verbatim>
|
||||||
|
BRANCH: <current branch — verify with git branch --show-current, never switch>
|
||||||
|
Implement the plan to the letter. Tests alongside code. No commit, no
|
||||||
|
branch ops, no new dependencies, no files outside the contract FILE SCOPE.
|
||||||
|
Finish with the FEAT-EXEC REPORT."
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the `FEAT-EXEC REPORT`:
|
||||||
|
- `STATUS : DONE` → STEP 4.
|
||||||
|
- `STATUS : NEED-DECISION` → make the decision HERE (that is reflection),
|
||||||
|
append it to the plan, re-dispatch a FRESH feater with plan + decision.
|
||||||
|
Max 2 decision round-trips → escalate to the user.
|
||||||
|
- `STATUS : BLOCKED` → surface the blocker to the user, stop.
|
||||||
|
|
||||||
|
## STEP 4 — VERIFY + SECURE (fresh gates, bounded loops)
|
||||||
|
|
||||||
|
Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with
|
||||||
|
`CONTRACT` = the STEP 0.7 path, `DIFF` = the working-tree diff the executor
|
||||||
|
produced, `TEST` = the suite named in its report:
|
||||||
|
|
||||||
|
- GATE 1 — a FRESH verifier judges the diff against the contract (blind).
|
||||||
|
CONFORME on the first pass → straight to GATE 2, no loop. ECARTS → the
|
||||||
|
"dev" of the loop is the dispatched executor: re-dispatch a FRESH feater
|
||||||
|
with the CONTRACT path + the exact gap lines, nothing else. Max 3 →
|
||||||
|
escalate.
|
||||||
|
- GATE 2 — a FRESH security-auditor (`MODE: gate`) scans the diff. PASS →
|
||||||
|
STEP 5. BLOCK → re-dispatch a FRESH feater with the BLOCKING list + the
|
||||||
|
CONTRACT path; re-verify the request THEN re-scan, max 3 → escalate.
|
||||||
|
|
||||||
|
Loop decisions stay HERE, in the main loop (LRN-083). Nominal (clear
|
||||||
|
request, conform first pass, clean diff) = one executor + one
|
||||||
|
verifier + one security dispatch.
|
||||||
|
|
||||||
|
## STEP 5 — COMMIT
|
||||||
|
|
||||||
|
Commit using conventional format:
|
||||||
|
```
|
||||||
|
feat(<scope>): <what was added>
|
||||||
|
|
||||||
|
<brief description of the feature>
|
||||||
|
```
|
||||||
|
|
||||||
|
If the feature touched multiple concerns (e.g., feature + config +
|
||||||
|
test), consider splitting into 2-3 atomic commits — load
|
||||||
|
`$HOME/.claude/agents/commit-changer.md` and follow its grouping logic.
|
||||||
|
|
||||||
|
Print summary:
|
||||||
|
```
|
||||||
|
FEAT COMPLETE
|
||||||
|
FEATURE : <name>
|
||||||
|
FILE(S) : <created/modified files>
|
||||||
|
TEST(S) : <added tests>
|
||||||
|
VERIFIED : <what was checked>
|
||||||
|
```
|
||||||
|
|
||||||
|
## STEP 6 — DOC SYNC (automatic)
|
||||||
|
|
||||||
|
Load `$HOME/.claude/agents/doc-syncer.md`.
|
||||||
|
Execute in automatic mode:
|
||||||
|
`auto-mode scope: <list of files modified during this session>`
|
||||||
|
|
||||||
|
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||||
|
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
||||||
|
`.claude/`/`CLAUDE.md` (rc 4 = a loud BDR-022 anomaly, not a silent skip), and no-ops when
|
||||||
|
nothing was patched — the common case for a trivial change. No FINISH in an inline flow, so
|
||||||
|
it just commits the docs on the current branch (no ordering concern).
|
||||||
|
|
||||||
|
## STEP 7 — CAPITALIZE (memory registries)
|
||||||
|
|
||||||
|
A small feature may or may not involve a design choice. Scan the work for:
|
||||||
|
|
||||||
|
- **Non-trivial design choice** (even small: a library pick, a naming convention, a data-model tradeoff) → propose `BDR-XXX` in `.claude/memory/decisions.md` with alternatives considered.
|
||||||
|
- **Reusable pattern or gotcha encountered** → propose `LRN-XXX` in `.claude/memory/learnings.md`.
|
||||||
|
|
||||||
|
Present the candidates grouped:
|
||||||
|
```
|
||||||
|
CAPITALIZE — proposé
|
||||||
|
[decisions.md] BDR-XXX — <titre> (optionnel)
|
||||||
|
[learnings.md] LRN-XXX — <pattern> (optionnel)
|
||||||
|
Valider ? (all / <IDs> / edit / skip)
|
||||||
|
```
|
||||||
|
|
||||||
|
Always append a 1-line entry to today's heading in `.claude/memory/journal.md`.
|
||||||
|
|
||||||
|
**Language rule**: written entries are ALWAYS in English (see CLAUDE.md "Memory registries" § Language). The interactive gate may mirror the user's language; the appended entries must not.
|
||||||
|
|
||||||
|
If no substantive capture candidate → skip with `CAPITALIZE: nothing to log`.
|
||||||
|
|
||||||
|
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
|
||||||
|
surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks`
|
||||||
|
only, never `git add -A`) as one `chore(memory)` commit, reports the memory-commit
|
||||||
|
hash, and no-ops if nothing was written.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RULES
|
||||||
|
- Max 5 files. If more needed → `/ship-feature`.
|
||||||
|
- Reflection (scope, plan, contract, loop decisions) NEVER leaves this main
|
||||||
|
loop; execution NEVER stays in it — the executor is the sonnet-pinned
|
||||||
|
feater subagent (BDR-066).
|
||||||
|
- The executor is dispatched FRESH on every round-trip — feedback travels
|
||||||
|
as contract path + named gaps/decisions, never as transcript.
|
||||||
|
- Design gate only (not full plugin check). See STEP 0.5.
|
||||||
|
- No brainstorm/design phase (if needed → `/ship-feature`).
|
||||||
|
- Keep scope tight. If scope creep happens mid-work, stop
|
||||||
|
and suggest splitting into `/feat` + follow-up task.
|
||||||
|
- Follow existing code patterns. Don't introduce new patterns
|
||||||
|
for a small feature.
|
||||||
|
|||||||
Reference in New Issue
Block a user