Compare commits
39
Commits
166faa1da5
...
5f159f38d2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f159f38d2 | ||
|
|
890e55f789 | ||
|
|
d8917bff4c | ||
|
|
c43f89cede | ||
|
|
1947a21237 | ||
|
|
fe1d60fccb | ||
|
|
1dcda2702b | ||
|
|
1ec032d2af | ||
|
|
a98610f676 | ||
|
|
872225f7d1 | ||
|
|
e5c7c516d2 | ||
|
|
30f732c08f | ||
|
|
4294bc2af5 | ||
|
|
bed695a6c6 | ||
|
|
a7d4df8704 | ||
|
|
1f7afc1d49 | ||
|
|
152da63624 | ||
|
|
2136953b2a | ||
|
|
bc8eede090 | ||
|
|
dd7868fc1c | ||
|
|
da50c38be9 | ||
|
|
4217fcfe35 | ||
|
|
ab0fafc0ef | ||
|
|
29fa962e43 | ||
|
|
45cd86810a | ||
|
|
f36aec370b | ||
|
|
89093a7835 | ||
|
|
2ad712cfd4 | ||
|
|
97088fe59b | ||
|
|
bd5a603567 | ||
|
|
e955c4d050 | ||
|
|
0fbe3103cb | ||
|
|
56c451ea25 | ||
|
|
1ed77cb3fb | ||
|
|
06413d9eb5 | ||
|
|
f2dd361bd5 | ||
|
|
9984b75f90 | ||
|
|
e5dd804e7e | ||
|
|
2864635087 |
@@ -86,6 +86,7 @@ rules:
|
|||||||
| BDR-063 | 2026-07-10 | GSC multi-account: OAuth2 installed-app flow + label-keyed token store, explicit (account,property) args, no global state | accepted |
|
| BDR-063 | 2026-07-10 | GSC multi-account: OAuth2 installed-app flow + label-keyed token store, explicit (account,property) args, no global state | accepted |
|
||||||
| BDR-064 | 2026-07-14 | global memory split: repo file → CLAUDE.global.md (deployed name unchanged), CLAUDE.md freed for project scope; consumer/maintainer wording rule | accepted |
|
| BDR-064 | 2026-07-14 | global memory split: repo file → CLAUDE.global.md (deployed name unchanged), CLAUDE.md freed for project scope; consumer/maintainer wording rule | accepted |
|
||||||
| BDR-065 | 2026-07-14 | transient planning artifacts (superpowers spec/plan): committed during run, deleted post-merge; git history = archive; codified in project CLAUDE.md | accepted |
|
| BDR-065 | 2026-07-14 | transient planning artifacts (superpowers spec/plan): committed during run, deleted post-merge; git history = archive; codified in project CLAUDE.md | accepted |
|
||||||
|
| BDR-066 | 2026-07-15 | Model routing: reflection inline (session big model) + sonnet-pinned executors + blocking gate | accepted |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -975,3 +976,19 @@ rules:
|
|||||||
- **Why**: user call 2026-07-14 — registries already capture decisions; a stale plan describes a superseded intermediate state and misleads future readers; accumulation pollutes the repo. Precedent: gsc-crux cleanup (8a1fac0, 2026-07-10) did the same — this makes it law, not habit.
|
- **Why**: user call 2026-07-14 — registries already capture decisions; a stale plan describes a superseded intermediate state and misleads future readers; accumulation pollutes the repo. Precedent: gsc-crux cleanup (8a1fac0, 2026-07-10) did the same — this makes it law, not habit.
|
||||||
- **Alternatives rejected**: never-commit (gitignore docs/superpowers) — breaks mid-run: briefs, reviewers, other-machine checkouts need the files; superpowers brainstorming commits the spec by convention. Keep-forever — the drift + pollution complained about.
|
- **Alternatives rejected**: never-commit (gitignore docs/superpowers) — breaks mid-run: briefs, reviewers, other-machine checkouts need the files; superpowers brainstorming commits the spec by convention. Keep-forever — the drift + pollution complained about.
|
||||||
- **Reference**: project CLAUDE.md; cleanup commit this chore; precedent 8a1fac0. Linked [[BDR-064]], [[LRN-124]].
|
- **Reference**: project CLAUDE.md; cleanup commit this chore; precedent 8a1fac0. Linked [[BDR-064]], [[LRN-124]].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## BDR-066 — Model routing: reflection inline (session big model), executors pinned sonnet, blocking gate
|
||||||
|
|
||||||
|
- **Date**: 2026-07-15
|
||||||
|
- **Status**: accepted (partial supersede of BDR-050: /feat dev no longer inline; bugfix/hotfix dev-inline CONSERVED)
|
||||||
|
- **Decision**: reflection (brainstorm, plan, contract, audit judgment, loop decisions) runs on session model (Fable; Opus fallback) — inline or inherit subagents, never pinned down. Execution (code from closed plan, fix-bundle application) runs sonnet-pinned subagents: feater + hotfixer pinned sonnet; SDD implementation+review subagents dispatched `model: "sonnet"` (ship-feature/init-project); web-validate fixes via hotfixer L1 (was inline Edit). analyzer haiku pin REMOVED (digest feeds plan = reflection tier). verifier + security-auditor STAY sonnet (job9 confirmed — procedural gates, ≤3×/loop). Blocking gate `lib/model-gate.md` (self-check + witness `lib/model-check.sh`) wired in 12 reflection orchestrators; small → STOP, unknown → fail-visible; census guard `lib/tests/model-routing.test.sh` flip-tested.
|
||||||
|
- **Why**: big-model quota burned on mechanical execution (Fable exhausted mid-job8); plan closed at dispatch → executor needs obedience not judgment; fresh sonnet gates catch executor drift.
|
||||||
|
- **Alternatives rejected**: opus pins on audit agents (session-independent) — rejected: session assumed big + blocking gate as backstop, one tier fewer; advisory gate — rejected by user, blocking; split bugfix/hotfix too — rejected: bugfix investigation interleaved w/ fix, hotfix gain marginal vs dispatch overhead.
|
||||||
|
- **Caveats**: client-handover-writer conversion (inline-load → sonnet dispatch, 11 human-gate sites to relocate) DEFERRED to own plan — its opus pin stays inert meanwhile; feater cannot ask → NEED-DECISION report = escalation valve, plan must close decisions; witness reads settings.json — lags `--model`-launched sessions (self-check compensates).
|
||||||
|
- **Caveat (execution)**: /feat re-arch broke 5 stale assertions in lib/tests/loops-light.test.sh (locked OLD feater architecture) — repointed to skills/feat/SKILL.md (FSK, mirrors HOT/HSK split) + new dispatch lock + 1-line reflow in feat SKILL for single-line grep lock (LRN-093 class).
|
||||||
|
- **Wave 2 (2026-07-15, user directive)**: wave-1 exclusion list left execution running on the big session model = the waste this split kills. REVERSES the "split hotfix rejected" alternative above (reason held for bugfix — investigation interleaved w/ fix — but NOT hotfix: LOCATE→apply is linear/separable). Changes: /hotfix split like /feat (LOCATE reflection inline + MODEL GATE, hotfixer sonnet EXECUTOR — rewritten dual-use: also the seo/geo/web-validate L1 applier; revert-not-loop preserved) → hotfix JOINS gated group, census 12→13. /commit-change dispatches sonnet commit-changer (propose→dispatcher gates→apply; grouping ON sonnet so NO model gate; AskUserQuestion dropped from agent). /release-candidate dispatches new sonnet release-executor (2 spans prep/finish; when-to-release + push + version-number decision STAY in dispatcher). /doc → doc-syncer (sonnet) dispatch; /status → status-reporter (kept HAIKU — right tier for read-only collection; win = off big model, not the tier). Gate exclusion list now = commit-change/doc/status/release-candidate. Consumer-staleness swept (LRN-113): feat Rule 1 DOWNGRADE + feat commit-split both repointed off the bare executor agents to the /hotfix + /commit-change skills.
|
||||||
|
- **Wave 3 (2026-07-15/16, user directive)**: split the last two inline execution-carrying agents like /feat. /bugfix: investigation+diagnosis+contract inline behind the gate; bugfixer = sonnet EXECUTOR (fix + regression test from a closed FIX PLAN; no Agent/AskUserQuestion; BUGFIX-EXEC REPORT). verify+secure loop stays in main loop, executor = its re-dispatched dev (verify-secure-loop.md intro now: BOTH consumers dispatched, no inline branch). FINISHES reversing the "split bugfix rejected" carve-out (hotfix went wave 2, bugfix now) — investigation↔fix coupling accepted, mitigated by structured DIAGNOSIS + verify loop. /code-clean: PHASE-1 audit + validation gate inline (reflection); code-cleaner = sonnet PHASE-2 EXECUTOR (delete approved dead code, inline-load refactorer, re-audit) — refactor NOW on sonnet (inline-load pin was inert on big model). exported-symbol per-item consent stays AT THE GATE. Consumer-staleness swept: hotfix deeper-bug escalation → /bugfix skill (not bare agent); onboard STEP 6 + tour Phase B read-only-audit → general-purpose/analyzer (big model, NEVER the sonnet executor — audit stays big). Both skills STAY gated. Also: Explore built-in kept inheriting session (search feeds reflection = big deserved; custom sonnet override created then reverted — built-in already inherits + no owned prompt). census 36→42, loops-light repointed 35/0.
|
||||||
|
- **Wave 4 (2026-07-16)**: client-handover doc-gen → sonnet, REDACTION-ONLY (user flipped from whole-writer after the full read). Key finding: nested audits (/seo,/harden,/web-validate — gated wave 1) must run BIG either way → whole-writer = ~7 extra gate-yields + resumable state machine on a CLIENT deliverable for ~0 extra sonnet work. Design: client-handover-writer TRIMMED to ship pipeline (STEP 1-8, all interactive gates native on big, nested audits inherit big) + doc-gen orchestration (resolve questions/NAP/precheck/overwrite/client-name inline → PACKAGE) → dispatches NEW sonnet handover-doc-writer (STEP 9-16: reads memory+git, synthesizes 6-chapter doc, word-count/skill-leak/anchor gates, renders HTML+PDF; GATE-FREE, no AskUserQuestion/Agent). client-handover JOINS gated group (orchestrates audits = reflection); its opus pin dropped (inherits big via inline-load). census 42→46. Branch feature/client-handover-dispatch (off develop, waves 1-3 merged first).
|
||||||
|
- **Reference**: spec `docs/superpowers/specs/2026-07-15-model-routing-design.md` + plan `docs/superpowers/plans/2026-07-15-model-routing.md` (transient, BDR-065 lifecycle), branches `feature/model-routing` (waves 1-3, merged), `feature/client-handover-dispatch` (wave 4).
|
||||||
|
|||||||
@@ -381,3 +381,12 @@ rules:
|
|||||||
## 2026-07-14
|
## 2026-07-14
|
||||||
- `/ship-feature` feature/claude-global-md-rename (unmerged, human GO pending): global memory → CLAUDE.global.md + project-scope CLAUDE.md, 8 commits (a4ee7e1 docs → e9a38a0 guards). Full pipeline: analyzer + contract (17 criteria), brainstorm/spec/plan gates, SDD 5 tasks (all task reviews Approved), verifier CONFORME 17/17 (after user-arbitrated criterion-9 consumer-wording + FILE-SCOPE [gated] enrichment), security PASS (semgrep 43 rules, 0), final review "Yes" after 2 Important fixes (guard-test drift → 7/7; doctor exact-target check). Decided [[BDR-064]]; learned [[LRN-122]] (2-commit rename split), [[LRN-123]] (exact symlink target). `make test` green throughout. settings.json plugin toggles = session-scoped, NOT committed — restore (gstack/ui-ux-pro-max/frontend-design/emil-design-eng/darwin-skill/magic ON) after merge.
|
- `/ship-feature` feature/claude-global-md-rename (unmerged, human GO pending): global memory → CLAUDE.global.md + project-scope CLAUDE.md, 8 commits (a4ee7e1 docs → e9a38a0 guards). Full pipeline: analyzer + contract (17 criteria), brainstorm/spec/plan gates, SDD 5 tasks (all task reviews Approved), verifier CONFORME 17/17 (after user-arbitrated criterion-9 consumer-wording + FILE-SCOPE [gated] enrichment), security PASS (semgrep 43 rules, 0), final review "Yes" after 2 Important fixes (guard-test drift → 7/7; doctor exact-target check). Decided [[BDR-064]]; learned [[LRN-122]] (2-commit rename split), [[LRN-123]] (exact symlink target). `make test` green throughout. settings.json plugin toggles = session-scoped, NOT committed — restore (gstack/ui-ux-pro-max/frontend-design/emil-design-eng/darwin-skill/magic ON) after merge.
|
||||||
- Merges to develop: feature/claude-global-md-rename (2d54df5), chore/untrack-audit-reports (d557ee9), chore/post-merge-cleanup. /cso triage: 75 gitleaks findings → 0 real (60 git SHAs vs sourcegraph rule; gitflow-test AWS fixture; expired GitHub image JWT; presigned-URL key ids; doc placeholders; job7-purged artifacts). .gitleaks.toml → [[allowlists]] format + 8 targeted entries; `make scan-secrets` green 0+0. Makefile "safe to commit" hint root-caused → [[LRN-124]]. Transient spec+plan deleted per [[BDR-065]] (user decree, gsc-crux precedent). Mid-merge discovery: user commit 5842119 (gitignore `.audit/` + model pin fable-5) — explains the .audit-in-diff question. cso report: .gstack/security-reports/2026-07-14-secrets-triage.json.
|
- Merges to develop: feature/claude-global-md-rename (2d54df5), chore/untrack-audit-reports (d557ee9), chore/post-merge-cleanup. /cso triage: 75 gitleaks findings → 0 real (60 git SHAs vs sourcegraph rule; gitflow-test AWS fixture; expired GitHub image JWT; presigned-URL key ids; doc placeholders; job7-purged artifacts). .gitleaks.toml → [[allowlists]] format + 8 targeted entries; `make scan-secrets` green 0+0. Makefile "safe to commit" hint root-caused → [[LRN-124]]. Transient spec+plan deleted per [[BDR-065]] (user decree, gsc-crux precedent). Mid-merge discovery: user commit 5842119 (gitignore `.audit/` + model pin fable-5) — explains the .audit-in-diff question. cso report: .gstack/security-reports/2026-07-14-secrets-triage.json.
|
||||||
|
|
||||||
|
## 2026-07-15
|
||||||
|
- model routing shipped on feature/model-routing: BDR-066 (reflection inline big / executors sonnet / blocking gate), /feat re-arch, census guard. client-handover conversion deferred to plan 2.
|
||||||
|
- model routing WAVE 2 (same branch, user directive): doc/status dispatch their agent (sonnet/haiku pins effective); /hotfix split like /feat (joins gated group 12→13, hotfixer dual-use executor); /commit-change → sonnet commit-changer (propose/apply, gates relocated); /release-candidate → sonnet release-executor (human gates + version decision kept in dispatcher). Consumer-staleness swept (feat Rule 1 + commit-split). census 36/0, make test green. Branch still unmerged.
|
||||||
|
- model routing WAVE 3 (same branch): /bugfix + /code-clean split like /feat — reflection inline, sonnet executors (bugfixer, code-cleaner). code-clean refactor now runs on sonnet (inline-load pin was inert). consumers rerouted (hotfix deeper-bug→/bugfix skill; onboard/tour read-only audit→big-model agent). Explore kept built-in (inherits big). census 42/0, loops-light 35/0. Branch still unmerged.
|
||||||
|
- model routing waves 1-3 MERGED into develop (e5c7c51); LRN-125 added. WAVE 4 started on feature/client-handover-dispatch (off develop): client-handover doc-gen → sonnet. REDACTION-ONLY (user flipped from whole-writer — nested audits must run big either way). client-handover-writer trimmed to ship pipeline (STEP 1-8 preserved byte-for-byte) + delegates writing to NEW sonnet handover-doc-writer (gate-free, STEP 9-16). client-handover joins gated group. census 46/0. NOTE: a Task-20 implementer ran `git checkout -- settings.json`, discarding user /model=opus working-tree state (LRN-098) — flagged to user (re-run /model). Lesson worth an LRN: constrain SDD implementers from git ops on files outside their task.
|
||||||
|
- wave-4 FINAL REVIEW (opus whole-branch): all 7 deliverable invariants hold, child gate-free, PACKAGE complete. Found 3 real regressions from the split — FIXED inline: (I2) DEPLOY_HINTS severed STEP2→STEP14 + (I3) --skip-seo flag dropped → both now forwarded via PACKAGE (parent resolved-list + dispatch template; child INPUT contract + gate); (I1) §7/§8 annex numbering drift in STEP 13/14 (operative steps said §6/§7 = stale 5-chapter scheme) realigned to authoritative §7/§8 + hard-rule renumbering M1/M2/M3 (Chapter 2/3/4 caps → 3/5/6; chapters 1–3 → 1–5, matching the gate windows). census lock added: lacks 'Agent(' on child (M5). census 47/0, shellcheck clean. Branch NOT merged (awaiting human signal).
|
||||||
|
- waves 1-4 MERGED to develop (d8917bf). LRN-126/127 added.
|
||||||
|
- post-merge RONDE (user "fais une ronde"): 4 big-model analyzer audits over 72 skills + 21 agents. Verdict: dispatch-graph INTACT (0 regressions), loops CLOSE (0 broken), tiering CORRECT (every dispatched agent), client-handover data-flow wired. The refactor preserved/improved everything it touched. NOTE: darwin-skill is a skill-PROMPT optimizer (mutates SKILL.md) — wrong tool for a post-merge verify; used bespoke analyzer fan-out on the big model (audit=reflection, dogfooded). Ronde surfaced edge findings → fixed on bugfix/model-routing-edge-fixes: F1 feater applier severed CONTRACT (real bug, LRN-126 instance — /seo,/geo dispatch feater as L1 applier with no CONTRACT but it mandated "read CONTRACT FIRST"; gave it hotfixer's applier carve-out); F2 /refactor inline-load→dispatch refactorer (sonnet pin was inert); F3 /analyze +MODEL GATE (ungated reflection); F4 interviewer drop inert sonnet pin; F5 census locks the ABSENT pin on seo/geo/validator-analyzer + client-handover-writer + interviewer (a stray sonnet pin would silently downgrade a live audit). census 47→57. Branch NOT merged.
|
||||||
|
|||||||
@@ -1241,3 +1241,23 @@ rules:
|
|||||||
- **why**: redaction removes VALUES, not INTELLIGENCE. And tool output is instruction — a hint that says "safe to commit" will eventually be obeyed by a human or an agent.
|
- **why**: redaction removes VALUES, not INTELLIGENCE. And tool output is instruction — a hint that says "safe to commit" will eventually be obeyed by a human or an agent.
|
||||||
- **future application**: derived security artifacts (scan reports, triage JSONs, audit findings) stay local/ignored; only the allowlist CONFIG (reviewable rules) is committed. When auditing tooling, grep its user-facing hints for wording that invites committing outputs.
|
- **future application**: derived security artifacts (scan reports, triage JSONs, audit findings) stay local/ignored; only the allowlist CONFIG (reviewable rules) is committed. When auditing tooling, grep its user-facing hints for wording that invites committing outputs.
|
||||||
- **cousin**: [[BDR-057]] (secrets by reference, redact at capture), [[BDR-065]] (transient planning artifacts — same "process artifacts ≠ repo content" family), [[LRN-103]] (re-probe before acting).
|
- **cousin**: [[BDR-057]] (secrets by reference, redact at capture), [[BDR-065]] (transient planning artifacts — same "process artifacts ≠ repo content" family), [[LRN-103]] (re-probe before acting).
|
||||||
|
|
||||||
|
## LRN-125 — don't make an agent dual-use across model tiers; route the audit consumer to a big-model agent, not the sonnet executor
|
||||||
|
|
||||||
|
- **pattern**: splitting `code-cleaner` into a sonnet PHASE-2 executor broke its OTHER consumers (onboard STEP 6, tour Phase B) which dispatched it read-only AUDIT-only. Reflex "keep it dual-use (audit-only OR execute)" would have run an AUDIT on the sonnet-pinned executor = silent violation of the audit=big-model principle. Fix: reroute the audit consumers to a big-model agent (general-purpose/analyzer, inherits session), never the sonnet executor.
|
||||||
|
- **why**: a dual-use agent inherits ONE pinned model. If its two uses sit on different tiers (audit=big, execution=sonnet), the pin silently mis-tiers one of them. hotfixer dual-use is fine because BOTH its uses are execution (same tier); code-cleaner's would have straddled tiers.
|
||||||
|
- **future application**: before making an agent dual-use, check both consumers are on the SAME tier. Audit/reflection consumer + execution consumer → split the routing (audit → big-model agent, execution → sonnet executor); never overload one pinned agent. Distinct from [[LRN-113]] (sweep ALL consumers on a pattern fix) — this is WHICH agent a consumer routes to, not whether you found them all.
|
||||||
|
- **cousin**: [[BDR-066]] (model routing: reflection/audit big, execution sonnet), [[LRN-113]] (consumer-staleness sweep on a pattern fix).
|
||||||
|
|
||||||
|
## LRN-126 — splitting a monolith agent severs every IMPLICIT data path; forward each consumed field through the handoff contract
|
||||||
|
|
||||||
|
- **pattern**: wave-4 redaction-only split (client-handover-writer monolith → reflection-parent + sonnet doc-writer child) silently dropped 2 inputs the extracted STEPs consumed. `DEPLOY_HINTS` (detected in parent STEP 2, consumed by child STEP 14) + `--skip-seo` flag (parsed from `$ARGUMENTS`, gated child STEP 13) worked in the monolith by shared scope; after the split they were dead — never added to the PACKAGE. Child rendered a §8 without platform tailoring; `--skip-seo` became a silent no-op. Caught only by the opus whole-branch review, not the census.
|
||||||
|
- **why**: in a monolith, `$ARGUMENTS`, detected vars, and STEP-N side-outputs are all in one scope — a later STEP reads them for free. The split turns that free read into a data path that MUST cross the parent→child contract explicitly. Every implicit read becomes a severed wire unless forwarded.
|
||||||
|
- **future application**: when splitting an agent, enumerate EVERY field the child reads (grep child for its input vocabulary — `PACKAGE.`, bare var names, `$ARGUMENTS` flags) and diff against what the parent SETS before dispatch. Any child-consumed field the parent never populates = severed path = renders a hole or a silent no-op. A census that checks shape (model pin, gate-free) will NOT catch this — needs a data-flow read.
|
||||||
|
- **cousin**: [[LRN-125]] (route consumer to right tier on a split), [[BDR-066]] (reflection/execution split), [[LRN-113]] (sweep ALL consumers). Distinct: 113/125 = WHICH agent/tier a consumer routes to; this = WHICH fields must cross the contract.
|
||||||
|
|
||||||
|
## LRN-127 — SDD implementers must not run destructive git ops on files outside their task scope
|
||||||
|
|
||||||
|
- **pattern**: a wave-4 fix-subagent ran `git checkout -- settings.json`, believing the model-value diff was a "test side-effect." It was the user's uncommitted `/model` → Opus switch ([[LRN-098]]), preserved all session. The checkout DISCARDED it — settings.json reverted to committed `claude-fable-5[1m]`. Implementer had no task-reason to touch settings.json; it acted on a file outside its diff.
|
||||||
|
- **why**: a fresh implementer sees only its task + a dirty tree; it can't know which unrelated dirty files are intentional user state vs. cruft. Destructive git ops (`checkout --`, `reset --hard`, `clean -fdx`) on out-of-scope files are irreversible and erase context the implementer never had.
|
||||||
|
- **future application**: dispatch briefs for SDD implementers / fix-subagents MUST bar destructive git ops outside the named task files. If the tree is dirty with unrelated changes, leave them — flag to controller, never revert. Controller owns cross-file git state; the executor touches only its own paths. Pairs with [[LRN-125]]/[[LRN-126]] as the "executor stays in its lane" family.
|
||||||
|
|||||||
@@ -1,5 +1,59 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
## 2026-07-16 — model-routing edge fixes (bugfix/model-routing-edge-fixes)
|
||||||
|
Post-merge ronde (4 big-model audits: dispatch-graph INTACT, loops CLOSE,
|
||||||
|
tiering CORRECT, data-flow client-handover wired). Fixing the edge findings
|
||||||
|
the ronde surfaced. Branch off develop, unmerged — human gate.
|
||||||
|
- [x] F1 (real bug) feater applier carve-out — /seo,/geo dispatch feater as
|
||||||
|
L1 applier with NO CONTRACT, but feater mandates "read CONTRACT FIRST"
|
||||||
|
(hotfixer has the carve-out, feater didn't) → mirror hotfixer.md:16-45.
|
||||||
|
- [x] F5 (guard) census: lock the ABSENT model: pin on seo/geo/validator-
|
||||||
|
analyzer + client-handover-writer (stray sonnet pin would silently
|
||||||
|
downgrade a live audit, uncaught).
|
||||||
|
- [x] F4 (cleanup) drop interviewer's inert `model: sonnet` (reflection role,
|
||||||
|
inline-loaded by gated init-project) + census guard.
|
||||||
|
- [x] F2 (tier) /refactor inline-load → true-dispatch refactorer (sonnet pin
|
||||||
|
was inert). refactorer verified dispatch-safe (no Ask/Agent, input=target).
|
||||||
|
- [x] F3 (gate) /analyze add MODEL GATE (inline-loads the analyzer reflection
|
||||||
|
agent, was ungated + undocumented). census: +analyze gated, +refactor excluded.
|
||||||
|
- [x] verify: census 57/0, shellcheck clean (my files), full suite green; NO merge.
|
||||||
|
|
||||||
|
## 2026-07-15 — model routing (feature/model-routing)
|
||||||
|
Spec + plan in docs/superpowers/ (transient, BDR-065). BDR-066. Branch
|
||||||
|
unmerged — human gate.
|
||||||
|
- [x] gate lib/model-check.sh + lib/model-gate.md (flip-tested) wired ×12
|
||||||
|
- [x] pins: hotfixer/feater sonnet, analyzer un-pinned; SDD model:"sonnet";
|
||||||
|
web-validate → hotfixer L1; census guard model-routing.test.sh
|
||||||
|
- [x] /feat re-arch: reflection inline → feater sonnet executor (partial
|
||||||
|
supersede BDR-050)
|
||||||
|
- [x] WAVE 2 (user directive): doc/status dispatch (sonnet/haiku pins
|
||||||
|
effective); /hotfix split like /feat (joins gated 12→13, hotfixer
|
||||||
|
dual-use executor); /commit-change → sonnet commit-changer
|
||||||
|
(propose/apply, gates relocated); /release-candidate → sonnet
|
||||||
|
release-executor (human gates + version decision kept in dispatcher);
|
||||||
|
census 36/0. Exclusion list now commit-change/doc/status/release-candidate.
|
||||||
|
- [ ] DOGFOOD (manual, next sessions): /feat live run — plan closes
|
||||||
|
decisions, dispatch carries sonnet, verify loop in main loop; gate
|
||||||
|
STOP on a sonnet session (LRN-079 class, not automatable here). Also
|
||||||
|
dogfood /hotfix split + /commit-change propose/apply + /release-candidate spans.
|
||||||
|
- [x] Explore agent: kept as built-in (inherits session = opus/fable). User
|
||||||
|
call — search feeds reflection, silent-incompleteness risk → deserves the
|
||||||
|
big model. Custom sonnet Explore.md created then reverted (built-in already
|
||||||
|
inherits + no owned prompt).
|
||||||
|
- [x] WAVE 3 (user directive): /bugfix split + /code-clean split → reflection
|
||||||
|
inline (behind existing gate), execution → sonnet executors. bugfixer =
|
||||||
|
pure fix+regression exec (BUGFIX-EXEC REPORT, no Agent/AskUserQuestion);
|
||||||
|
code-cleaner = PHASE-2 exec (refactor now runs on sonnet — inline-load pin
|
||||||
|
was inert). Both skills STAY gated. census wave-3 + loops-light repoint
|
||||||
|
(guarded). Supersedes BDR-050 bugfix carve-out.
|
||||||
|
- [x] WAVE 4 — client-handover (branch feature/client-handover-dispatch, off
|
||||||
|
develop). Shape FLIPPED to REDACTION-ONLY (full read: nested audits must
|
||||||
|
run big either way since /seo,/harden,/web-validate are gated → whole-writer
|
||||||
|
buys ~0 extra sonnet work for ~7 extra gate-yields). Design: parent
|
||||||
|
(client-handover-writer, inline=big) keeps STEP 1-8 pipeline + ALL gates
|
||||||
|
native + builds a PACKAGE; new sonnet handover-doc-writer does STEP 9-16
|
||||||
|
pure write+render, gate-free. Tasks 19-22 in plan. + MODEL GATE on skill.
|
||||||
|
|
||||||
## 2026-07-08 — full back-merge release/1.0.0→develop (chore/backmerge-release-full)
|
## 2026-07-08 — full back-merge release/1.0.0→develop (chore/backmerge-release-full)
|
||||||
Genèse : la revue avait porté ~5/19 commits ; back-merge complet demandé. Cherry-pick par
|
Genèse : la revue avait porté ~5/19 commits ; back-merge complet demandé. Cherry-pick par
|
||||||
catégorie, 1 commit atomique/item, make test après chaque code. Branche non mergée (gate humain).
|
catégorie, 1 commit atomique/item, make test après chaque code. Branche non mergée (gate humain).
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|||||||
- `/deploy` checklist reshaped on first-real-run feedback, in two passes: runbook steps are **one command per line, interactive-session style** (an early step opens the ssh session; later lines run on the box; local steps say "from your machine") instead of folded `ssh host "cd … && …"` one-liners — step = comment header + command lines up to the next blank line, a `@delta:` directive governs the whole block; and the checklist is now **display-only** — `NEXT.sh` is no longer written at all (throwaway artifact; `PENDING.json` + the live runbook regenerate it in any session) and every hand-back **ends the turn with the full checklist as the final text, no tool call after it** (a checklist printed above a blocking question tool was observed never reaching the user). Template `templates/deploy/PROCEDURE.md` restyled to match.
|
- `/deploy` checklist reshaped on first-real-run feedback, in two passes: runbook steps are **one command per line, interactive-session style** (an early step opens the ssh session; later lines run on the box; local steps say "from your machine") instead of folded `ssh host "cd … && …"` one-liners — step = comment header + command lines up to the next blank line, a `@delta:` directive governs the whole block; and the checklist is now **display-only** — `NEXT.sh` is no longer written at all (throwaway artifact; `PENDING.json` + the live runbook regenerate it in any session) and every hand-back **ends the turn with the full checklist as the final text, no tool call after it** (a checklist printed above a blocking question tool was observed never reaching the user). Template `templates/deploy/PROCEDURE.md` restyled to match.
|
||||||
- `settings.json`: `inputNeededNotifEnabled: true` adopted (harness notification toggle); committed layout otherwise unchanged.
|
- `settings.json`: `inputNeededNotifEnabled: true` adopted (harness notification toggle); committed layout otherwise unchanged.
|
||||||
- gsd-pi upgraded 2.64.0 → 3.0.0 — `status-reporter` output parser adapted to the ADR-013 cutover.
|
- gsd-pi upgraded 2.64.0 → 3.0.0 — `status-reporter` output parser adapted to the ADR-013 cutover.
|
||||||
|
- `hotfixer` pinned `model: sonnet` (seo/geo/web-validate L1 applier); `analyzer` haiku pin removed (inherits the session model).
|
||||||
|
- ship-feature / init-project: SDD implementation + review subagents dispatched with `model: "sonnet"`.
|
||||||
|
- web-validate `--fix`: bundle applied via `hotfixer` at L1 instead of inline Edit (BDR-061 alignment).
|
||||||
|
- Model routing wave 2 — the pure-execution + reflection-split skills stop running execution on the big session model. `/doc` and `/status` now **dispatch** their agent (doc-syncer sonnet, status-reporter haiku) instead of inline-loading it, so the pin takes effect. `/hotfix` split like `/feat`: reflection (LOCATE root cause) inline behind the model gate, the fix applied by a `hotfixer` sonnet executor (rewritten dual-use — it is also the seo/geo/web-validate L1 applier); revert-not-loop preserved; hotfix joins the gated group (13th). `/commit-change` dispatches a sonnet `commit-changer` (propose → dispatcher-owned approval gates → apply; grouping runs on sonnet, `AskUserQuestion` removed from the agent). `/release-candidate` dispatches a new sonnet `release-executor` for the mechanical spans (prep / finish+tag), the two human gates (when-to-release, push) and the version-number decision staying in the dispatcher.
|
||||||
|
- Model routing wave 3 — the last two inline execution-carrying skills split like `/feat`. `/bugfix`: root-cause investigation, diagnosis and contract run inline behind the model gate; the fix + regression test are applied by a `bugfixer` sonnet executor (was a single inline agent), with the verify+secure loop staying in the main loop and the executor as its re-dispatched dev. `/code-clean`: the dead-code / style / structural audit and the approval gate run inline; a `code-cleaner` sonnet PHASE-2 executor then applies the approved scope — and the style/structural refactor (which inline-loads `refactorer`) now finally runs on sonnet, its pin having been inert under the old inline-load. Both skills stay gated (they keep reflection); their read-only-audit consumers (`onboard`, `tour`) reroute to a big-model agent so an audit never runs on the sonnet executor. Supersedes the BDR-050 "bugfix stays inline" carve-out. The built-in `Explore` search agent is deliberately left inheriting the session (search feeds reflection).
|
||||||
|
- Model routing wave 4 — client-handover doc-generation moved to sonnet (redaction-only). The ship-and-handover pipeline (baseline audits, fix loops, commit/push, deploy pause, live validate, gate) stays inline on the big session model in `client-handover-writer` — its interactive gates work natively and its nested `/seo`/`/harden`/`/web-validate` audits inherit the big model — and only the deliverable writing is delegated to a new sonnet `handover-doc-writer` (gate-free: reads memory + git, synthesizes the 6-chapter doc from a resolved PACKAGE, runs the word-count / skill-leak / anchor gates, renders branded HTML+PDF). `client-handover` joins the gated group (it orchestrates audits = reflection). Chosen over the whole-writer dispatch: the nested audits must run big either way, so whole-writer would have added ~7 gate-yields + a resumable state machine on a client deliverable for ~zero extra sonnet work.
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
- **Magic MCP fully ask-gated** — all four `mcp__magic__*` tools (builder, refiner, inspiration, logo_search) moved to `permissions.ask` in `settings.json`; no magic call can auto-execute. The builder opens an unauthenticated local callback server (`127.0.0.1:9221+`, `Access-Control-Allow-Origin: *`, no token check) whose POST body is injected verbatim into the tool result the model consumes — the ask-gate is the mitigation on our side (BDR-059).
|
- **Magic MCP fully ask-gated** — all four `mcp__magic__*` tools (builder, refiner, inspiration, logo_search) moved to `permissions.ask` in `settings.json`; no magic call can auto-execute. The builder opens an unauthenticated local callback server (`127.0.0.1:9221+`, `Access-Control-Allow-Origin: *`, no token check) whose POST body is injected verbatim into the tool result the model consumes — the ask-gate is the mitigation on our side (BDR-059).
|
||||||
@@ -23,6 +29,8 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|||||||
- **GSC + CrUX data layer for `/seo` FULL** — `lib/seo-data/` engine pulls real Google Search Console (Search Analytics + URL Inspection) and Chrome UX Report field data into the `/seo` FULL audit: CrUX p75 field metrics become the primary Core Web Vitals signal (anonymous PageSpeed lab stays the fallback), and a "Performance GSC (90 j)" section flags position 4-10 quick wins. Multi-account via OAuth2 (`make seo-connect`, one-time consent, `webmasters.readonly` scope only) with a per-label token store (0600 file / 0700 dir, atomic write, refresh tokens redacted, gitleaks-allowlisted) so two concurrent site audits never conflict. Absent credentials degrade gracefully to anonymous PageSpeed — the audit never fails. Config: `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` / `CRUX_API_KEY` in `~/.claude/.env`. Engine contract documented in `lib/seo-data/README.md`.
|
- **GSC + CrUX data layer for `/seo` FULL** — `lib/seo-data/` engine pulls real Google Search Console (Search Analytics + URL Inspection) and Chrome UX Report field data into the `/seo` FULL audit: CrUX p75 field metrics become the primary Core Web Vitals signal (anonymous PageSpeed lab stays the fallback), and a "Performance GSC (90 j)" section flags position 4-10 quick wins. Multi-account via OAuth2 (`make seo-connect`, one-time consent, `webmasters.readonly` scope only) with a per-label token store (0600 file / 0700 dir, atomic write, refresh tokens redacted, gitleaks-allowlisted) so two concurrent site audits never conflict. Absent credentials degrade gracefully to anonymous PageSpeed — the audit never fails. Config: `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` / `CRUX_API_KEY` in `~/.claude/.env`. Engine contract documented in `lib/seo-data/README.md`.
|
||||||
- **impeccable** (pbakaus, Apache-2.0) wired into the toolchain as the design counterpart of semgrep: the `/impeccable` skill (23 verbs under one command: audit, polish, bolder, quieter…) plus the 45-rule deterministic anti-pattern detector (`npx impeccable detect`, exit 0/2, `--json`). Complementary to `frontend-design` (kept — aesthetic direction at build time); impeccable adds the deterministic audit floor and per-project design context (`/impeccable init`). CLI pinned in `plugins.lock.json` (3.2.0 — a silent rules update would change audit output on unchanged code); dist is machine-owned under `skills-external/impeccable/` (gitignored, ctx7 pattern), staged-installed by `install-plugins.sh` Step 8d, refreshed pin-honored by `update-all.sh`, symlinked by `link.sh`, listed in the design/web/web-full/full profiles and the design-work routing. Requires Node ≥ 24: the install baseline is bumped from 22 to 24 LTS (NodeSource `setup_24.x` / brew `node@24`), so `make plugin` upgrades a too-old host in place; the impeccable steps still skip gracefully if Node stays below 24. Not in the design gate's GATE-BLOCK list yet — promotion deliberate, after first dogfood.
|
- **impeccable** (pbakaus, Apache-2.0) wired into the toolchain as the design counterpart of semgrep: the `/impeccable` skill (23 verbs under one command: audit, polish, bolder, quieter…) plus the 45-rule deterministic anti-pattern detector (`npx impeccable detect`, exit 0/2, `--json`). Complementary to `frontend-design` (kept — aesthetic direction at build time); impeccable adds the deterministic audit floor and per-project design context (`/impeccable init`). CLI pinned in `plugins.lock.json` (3.2.0 — a silent rules update would change audit output on unchanged code); dist is machine-owned under `skills-external/impeccable/` (gitignored, ctx7 pattern), staged-installed by `install-plugins.sh` Step 8d, refreshed pin-honored by `update-all.sh`, symlinked by `link.sh`, listed in the design/web/web-full/full profiles and the design-work routing. Requires Node ≥ 24: the install baseline is bumped from 22 to 24 LTS (NodeSource `setup_24.x` / brew `node@24`), so `make plugin` upgrades a too-old host in place; the impeccable steps still skip gracefully if Node stays below 24. Not in the design gate's GATE-BLOCK list yet — promotion deliberate, after first dogfood.
|
||||||
- `/tour` skill — grouped all-axes sweep over one or several projects: security (pinned-semgrep `security-auditor` agent + `/cso` posture when gstack is ON) → cleanup → re-verify → reconcile (report-only, never edits the target TODO/registries) → doc sync, looping until a full pass applies zero fixes (bounded at 3 iterations). Fixes land on a `chore/tour-<date>` branch the skill never merges; each project gets an append-only `.claude/audits/TOUR.md` report with BREAKING tags on contract-changing security fixes. Built TDD (superpowers:writing-skills): baseline run showed silent TODO rewrites, autonomous registry writes, grep-as-security-pass, no persistent report, scope creep and an unbounded loop — each countered and verified on a seeded fixture.
|
- `/tour` skill — grouped all-axes sweep over one or several projects: security (pinned-semgrep `security-auditor` agent + `/cso` posture when gstack is ON) → cleanup → re-verify → reconcile (report-only, never edits the target TODO/registries) → doc sync, looping until a full pass applies zero fixes (bounded at 3 iterations). Fixes land on a `chore/tour-<date>` branch the skill never merges; each project gets an append-only `.claude/audits/TOUR.md` report with BREAKING tags on contract-changing security fixes. Built TDD (superpowers:writing-skills): baseline run showed silent TODO rewrites, autonomous registry writes, grep-as-security-pass, no persistent report, scope creep and an unbounded loop — each countered and verified on a seeded fixture.
|
||||||
|
- Model routing (BDR-066): blocking model gate (`lib/model-gate.md` + `lib/model-check.sh`, flip-tested) wired into 12 reflection orchestrators; census guard `lib/tests/model-routing.test.sh`.
|
||||||
|
- `/feat` re-architected: reflection inline (scope/plan/contract), execution dispatched to the sonnet-pinned `feater` executor; verify+secure loop decided in the main loop with fresh executor re-dispatches.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- `lib/detect-plugins.sh`: `detect_security_guidance` — dead since its re-add at `45c3507`; zero callers on any surface, including the dynamic `session-start.sh` detection loop (the banner's row derives from `enabledPlugins` instead). Nothing invokes it — removal, not a breaking change.
|
- `lib/detect-plugins.sh`: `detect_security_guidance` — dead since its re-add at `45c3507`; zero callers on any surface, including the dynamic `session-start.sh` detection loop (the banner's row derives from `enabledPlugins` instead). Nothing invokes it — removal, not a breaking change.
|
||||||
|
|||||||
@@ -37,6 +37,30 @@ claude-config/
|
|||||||
- `templates/` = symlinked to `~/.claude/templates/` — copy into projects via `/onboard` or manually
|
- `templates/` = symlinked to `~/.claude/templates/` — copy into projects via `/onboard` or manually
|
||||||
- **Graphify** builds a knowledge graph of any codebase (`/graphify query`), producing a navigable wiki in `graphify-out/wiki/`. This map helps Claude understand project structure, find relevant code faster, and reason across files. Essential for large-scope tasks (multi-file features, complex bugs, architectural changes). Small tasks should skip it and read files directly.
|
- **Graphify** builds a knowledge graph of any codebase (`/graphify query`), producing a navigable wiki in `graphify-out/wiki/`. This map helps Claude understand project structure, find relevant code faster, and reason across files. Essential for large-scope tasks (multi-file features, complex bugs, architectural changes). Small tasks should skip it and read files directly.
|
||||||
|
|
||||||
|
### Agent model routing (BDR-066)
|
||||||
|
|
||||||
|
Reflection (brainstorm, plan, contract, audit judgment, loop decisions) runs
|
||||||
|
INLINE on the session model — assumed Fable/Opus, enforced by a blocking
|
||||||
|
gate (`lib/model-gate.md` + `lib/model-check.sh`) at the entry of the 13
|
||||||
|
reflection orchestrators. Execution runs on pinned subagents:
|
||||||
|
|
||||||
|
| Agent | Model | Tier |
|
||||||
|
|---|---|---|
|
||||||
|
| feater, hotfixer, bugfixer | sonnet (pinned) | executors — code from a closed plan (feat), fix from a closed diagnosis (bugfix), fix-bundle appliers |
|
||||||
|
| verifier, security-auditor | sonnet (pinned) | fresh gates (≤3×/loop) |
|
||||||
|
| commit-changer, release-executor, code-cleaner | sonnet (pinned) | dispatched execution — grouping+commit / release spans / approved cleanup (the audit + approval gate stay in the dispatcher) |
|
||||||
|
| doc-syncer, onboarder, scaffolder, refactorer, interviewer, plugin-advisor | sonnet (pinned) | workers |
|
||||||
|
| status-reporter | haiku (pinned) | mechanical collector |
|
||||||
|
| handover-doc-writer | sonnet (pinned) | deliverable writer — synthesizes + renders the client doc from a resolved PACKAGE (dispatched by client-handover) |
|
||||||
|
| analyzer, seo-analyzer, geo-analyzer, validator-analyzer, client-handover-writer | inherit session (Fable/Opus) | reflection / audit / inline playbooks / ship-and-handover pipeline |
|
||||||
|
| Explore (built-in) | inherit session (Fable/Opus) | search feeds reflection — kept on the big model, not pinned down |
|
||||||
|
|
||||||
|
The pure-execution skills `/doc`, `/status`, `/commit-change`,
|
||||||
|
`/release-candidate` **dispatch** their agent (instead of inline-loading it)
|
||||||
|
so the pin takes effect and the work leaves the big session model; `/hotfix`
|
||||||
|
was split like `/feat` (reflection inline + gate, `hotfixer` executor) and so
|
||||||
|
joins the gated group (13th).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Fresh install (new machine)
|
## Fresh install (new machine)
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ cd mon-projet-existant/
|
|||||||
| 4 | Graphify (si complexity ≥ 30%) | graphify-out/GRAPH_REPORT.md |
|
| 4 | Graphify (si complexity ≥ 30%) | graphify-out/GRAPH_REPORT.md |
|
||||||
| 5 | Analyze read-only (analyzer agent) | .onboard-audit/analyze.md |
|
| 5 | Analyze read-only (analyzer agent) | .onboard-audit/analyze.md |
|
||||||
| 6 | Audits parallèles selon archétype : | .onboard-audit/*.md (9 fichiers max) |
|
| 6 | Audits parallèles selon archétype : | .onboard-audit/*.md (9 fichiers max) |
|
||||||
| | — dette tech (code-cleaner) |
|
| | — dette tech (general-purpose, audit read-only) |
|
||||||
| | — sécurité (cso si gstack ON, sinon OWASP fallback) |
|
| | — sécurité (cso si gstack ON, sinon OWASP fallback) |
|
||||||
| | — docs drift (doc-syncer) |
|
| | — docs drift (doc-syncer) |
|
||||||
| | — SEO + GEO (si public) |
|
| | — SEO + GEO (si public) |
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
name: analyzer
|
name: analyzer
|
||||||
description: Analyze code, codebase, or problem before any modification. Produces a factual report without proposing solutions. Use proactively before any refactoring, design, or implementation.
|
description: Analyze code, codebase, or problem before any modification. Produces a factual report without proposing solutions. Use proactively before any refactoring, design, or implementation.
|
||||||
tools: Read, Grep, Glob, Bash
|
tools: Read, Grep, Glob, Bash
|
||||||
model: haiku
|
|
||||||
memory: project
|
memory: project
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+40
-232
@@ -1,245 +1,53 @@
|
|||||||
---
|
---
|
||||||
name: bugfixer
|
name: bugfixer
|
||||||
description: Root-cause bug-fix executor — dispatched by /bugfix. Hypothesis-driven investigation, diagnosis, minimal scoped fix with regression test.
|
description: Bug-fix EXECUTOR — dispatched by /bugfix with a closed DIAGNOSIS + FIX PLAN + contract. Applies the fix and a regression test, runs the suite, reports. No investigation, no questions, no commit.
|
||||||
tools: Read, Edit, Write, Bash, Grep, Glob, Agent
|
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
---
|
---
|
||||||
|
|
||||||
# BUGFIX — Structured Bug Fix
|
# BUGFIXER — fix executor
|
||||||
|
|
||||||
Investigate, understand, plan, fix. No guessing. The iron law:
|
You receive a CLOSED diagnosis + fix plan from the /bugfix orchestrator. The
|
||||||
understand the root cause before writing a single fix.
|
investigation already happened; your job is faithful execution, not analysis.
|
||||||
|
Every choice was 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 (symptom reproduced-then-gone + a regression test present) + FILE
|
||||||
|
SCOPE bound everything you do.
|
||||||
|
- `DIAGNOSIS`: root cause + evidence, from the orchestrator's investigation.
|
||||||
|
- `FIX PLAN`: the exact edits (file:line → change) + the regression test to add.
|
||||||
|
- `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 1 — GATHER CONTEXT
|
## EXECUTION RULES
|
||||||
|
|
||||||
Understand the current state:
|
- Apply the FIX PLAN to the letter — fix the ROOT CAUSE named in DIAGNOSIS,
|
||||||
|
not the symptom. A plan hole or an open choice (naming, data shape, API
|
||||||
|
surface, dependency) → STOP, report `NEED-DECISION` with the precise
|
||||||
|
question. Never re-investigate or improvise a different fix.
|
||||||
|
- Stay inside the contract FILE SCOPE. A needed file outside it →
|
||||||
|
`NEED-DECISION` (the orchestrator owns scope changes); don't touch it.
|
||||||
|
- Add or update the regression test the plan names — it must fail before the
|
||||||
|
fix and pass after. Run the relevant suite incrementally; run it fully
|
||||||
|
before reporting.
|
||||||
|
- Follow existing code patterns and CLAUDE.md limits (function size, params,
|
||||||
|
no global state). Keep the fix minimal — no "while we're here" cleanups.
|
||||||
|
- FORBIDDEN: `git commit`, branch ops, push, merge, new dependencies,
|
||||||
|
security/verifier dispatch, editing `.claude/**` or memory registries, user
|
||||||
|
questions (you cannot ask — report instead), attribution trailers of any kind.
|
||||||
|
|
||||||
```bash
|
## OUTPUT — end with exactly this report (your final message)
|
||||||
git status
|
|
||||||
git log --oneline -5
|
|
||||||
```
|
|
||||||
|
|
||||||
Read the error message, stack trace, or bug description.
|
|
||||||
Identify:
|
|
||||||
- **What** is broken (symptom)
|
|
||||||
- **Where** it manifests (file, line, endpoint, UI element)
|
|
||||||
- **When** it started (recent commit? always? after a deploy?)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# If the user mentions "it was working before":
|
|
||||||
git log --oneline -20 --all -- <suspected files>
|
|
||||||
```
|
|
||||||
|
|
||||||
## STEP 1.5 — DESIGN GATE
|
|
||||||
|
|
||||||
Follow `$HOME/.claude/lib/design-gate.md`:
|
|
||||||
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, layout, animation).
|
|
||||||
- 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 2 — INVESTIGATE
|
|
||||||
|
|
||||||
Trace the bug from symptom to root cause:
|
|
||||||
|
|
||||||
1. Read the code path involved (follow the data flow).
|
|
||||||
2. Check recent changes to the affected files:
|
|
||||||
```bash
|
|
||||||
git log --oneline -10 -- <file>
|
|
||||||
git diff HEAD~5 -- <file> # if recent regression suspected
|
|
||||||
```
|
|
||||||
3. Look for related tests — do they pass? Do they cover
|
|
||||||
the broken case?
|
|
||||||
4. Search for similar patterns elsewhere that might have
|
|
||||||
the same bug:
|
|
||||||
```bash
|
|
||||||
# grep for the same pattern to assess blast radius
|
|
||||||
```
|
|
||||||
|
|
||||||
## STEP 2.5 — MEMORY READ-BEFORE (blockers-first)
|
|
||||||
|
|
||||||
Run the scan per `$HOME/.claude/lib/analyze-before-plan.md`, blockers-weighted: a resolved
|
|
||||||
BLK may already name THIS exact root cause; an in-force BDR may constrain the fix. Emit
|
|
||||||
RELATED MEMORY. Consumption is NATURAL — the agent emitting this IS the one writing STEP 3's
|
|
||||||
diagnosis (reader = planner, no external skill to inject into).
|
|
||||||
|
|
||||||
TEETH: STEP 3's DIAGNOSIS must name any binding prior (`PRIOR: BLK-xxx — known cause/fix`,
|
|
||||||
or `honors BDR-xxx`) OR the RELATED MEMORY line states none bears. Reading blockers then
|
|
||||||
diagnosing without naming a match is the read-then-ignore failure this prevents.
|
|
||||||
`.claude/memory/` absent → guarded no-op, proceed.
|
|
||||||
|
|
||||||
## STEP 3 — HYPOTHESIZE + PLAN
|
|
||||||
|
|
||||||
Present findings before fixing:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
BUGFIX — DIAGNOSIS
|
BUGFIX-EXEC REPORT
|
||||||
BUG : <one-line symptom>
|
STATUS : DONE | NEED-DECISION | BLOCKED
|
||||||
ROOT CAUSE: <what is actually wrong and why>
|
FILE(S) : <created/modified paths>
|
||||||
EVIDENCE: <what confirmed it — test, trace, diff>
|
TEST(S) : <regression test added/updated + final suite run result, verbatim line>
|
||||||
BLAST RADIUS: <other places affected, or "isolated">
|
SMOKE : <build/typecheck result if run, or n/a>
|
||||||
|
NOTES : <DONE: deviations (must be none) | NEED-DECISION: the exact
|
||||||
FIX PLAN:
|
question + the options you see | BLOCKED: the blocker verbatim>
|
||||||
1. <file:line> — <what to change>
|
|
||||||
2. <file:line> — <what to change>
|
|
||||||
[3. <test file> — add/update test for this case]
|
|
||||||
|
|
||||||
RISK: <low/medium — what could go wrong>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- If the root cause is still unclear after investigation,
|
|
||||||
say so explicitly. List remaining hypotheses ranked by
|
|
||||||
probability. Ask the user before proceeding.
|
|
||||||
- If the fix is trivial after investigation (1-2 lines):
|
|
||||||
proceed directly — no need to wait for approval on an
|
|
||||||
obvious fix.
|
|
||||||
- If the fix is significant (>10 lines, multiple files,
|
|
||||||
behavior change): wait for user approval.
|
|
||||||
|
|
||||||
## STEP 3.5 — CONTRACT
|
|
||||||
|
|
||||||
Run `$HOME/.claude/lib/contract-interview.md` (main loop). The DIAGNOSIS
|
|
||||||
feeds it: REQUEST verbatim = the bug report as received; ACCEPTANCE CRITERIA
|
|
||||||
= the symptom reproduced-then-gone + a regression test present and passing;
|
|
||||||
FILE SCOPE = the FIX PLAN files. Questions stay proportional (a clear,
|
|
||||||
reproduced bug → zero). It writes the contract to
|
|
||||||
`.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`; keep the path for GATE 1
|
|
||||||
(STEP 5).
|
|
||||||
|
|
||||||
## STEP 4 — FIX
|
|
||||||
|
|
||||||
**Gitflow aiguillage (before editing):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
|
||||||
— your type = `bugfix`. On `main`/`develop` it branches first; on a working
|
|
||||||
branch it's a no-op (commit in place). Never `finish`.
|
|
||||||
|
|
||||||
Apply the fix following the plan:
|
|
||||||
|
|
||||||
- Fix the root cause, not the symptom.
|
|
||||||
- Add or update tests to cover the bug case (regression test).
|
|
||||||
- If no test framework exists: document what you verified.
|
|
||||||
- Keep changes minimal — fix the bug, nothing else.
|
|
||||||
|
|
||||||
## STEP 5 — VERIFY + COMMIT
|
|
||||||
|
|
||||||
1. Run the full relevant test suite. Detection cascade (run the first that resolves):
|
|
||||||
```bash
|
|
||||||
# JS/TS — package.json scripts.test
|
|
||||||
test -f package.json && jq -r '.scripts.test // empty' package.json | head -1
|
|
||||||
# Python — pytest config
|
|
||||||
( test -f pyproject.toml && grep -qE '^\[tool\.pytest' pyproject.toml ) && echo "pytest"
|
|
||||||
test -f pytest.ini && echo "pytest"
|
|
||||||
# Rust
|
|
||||||
test -f Cargo.toml && echo "cargo test"
|
|
||||||
# Go
|
|
||||||
test -f go.mod && echo "go test ./..."
|
|
||||||
# Make
|
|
||||||
test -f Makefile && grep -qE '^test:' Makefile && echo "make test"
|
|
||||||
```
|
|
||||||
2. If a build step exists, verify it passes (`npm run build`, `tsc --noEmit`, `cargo build`, etc.).
|
|
||||||
3. Check for regressions in related functionality.
|
|
||||||
4. **Fresh gates (verify + secure), bounded loops.** Steps 1-3 are your
|
|
||||||
dev-side smoke test, NOT the gate. Run the two fresh gates per
|
|
||||||
`$HOME/.claude/lib/verify-secure-loop.md` with `CONTRACT` = the STEP 3.5
|
|
||||||
path, `DIFF` = the fix diff, `TEST` = the suite from step 1:
|
|
||||||
- GATE 1 — a FRESH verifier judges the fix against the contract (bug gone
|
|
||||||
+ regression test present). CONFORME → GATE 2. ECARTS → fix, re-verify,
|
|
||||||
max 3 → escalate.
|
|
||||||
- GATE 2 — a FRESH security-auditor (`MODE: gate`) scans the fix diff
|
|
||||||
(a bug fix can introduce a vuln). PASS → commit gate. BLOCK → fix,
|
|
||||||
re-verify request THEN re-scan, max 3 → escalate.
|
|
||||||
|
|
||||||
Nominal = one verifier + one security dispatch. Only then the commit gate.
|
|
||||||
5. **Pre-commit confirmation gate.** Before running `git commit`, present the diff
|
|
||||||
summary and the proposed message, then wait for approval:
|
|
||||||
|
|
||||||
```
|
|
||||||
BUGFIX — READY TO COMMIT
|
|
||||||
FILE(S) : <list>
|
|
||||||
DIFF : <git diff --stat>
|
|
||||||
MESSAGE :
|
|
||||||
fix(<scope>): <root cause description>
|
|
||||||
|
|
||||||
<what was wrong and why>
|
|
||||||
<what the fix does>
|
|
||||||
|
|
||||||
Commit now? (yes / edit message / skip / amend last)
|
|
||||||
```
|
|
||||||
|
|
||||||
- `yes` → run `git commit`.
|
|
||||||
- `edit message` → user provides corrected message; redraw gate.
|
|
||||||
- `skip` → leave changes uncommitted, exit cleanly.
|
|
||||||
- `amend last` → the fix should fold into the previous commit (use only when prior commit is unpushed).
|
|
||||||
|
|
||||||
6. Commit using conventional format (after approval):
|
|
||||||
```
|
|
||||||
fix(<scope>): <root cause description>
|
|
||||||
|
|
||||||
<what was wrong and why>
|
|
||||||
<what the fix does>
|
|
||||||
```
|
|
||||||
7. Print summary:
|
|
||||||
```
|
|
||||||
BUGFIX COMPLETE
|
|
||||||
BUG : <symptom>
|
|
||||||
ROOT CAUSE : <one-line>
|
|
||||||
FILE(S) : <changed files>
|
|
||||||
TEST(S) : <added/updated tests, or "none — verified manually">
|
|
||||||
REGRESSION : <checked areas>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 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 bugfix with an understood root cause is almost always worth one entry:
|
|
||||||
|
|
||||||
1. Propose a `BLK-XXX` entry in `.claude/memory/blockers.md` pre-filled from STEP 3 diagnosis:
|
|
||||||
- `friction` = symptom
|
|
||||||
- `real_cause` = root cause identified
|
|
||||||
- `solution` = the fix applied
|
|
||||||
- `status` = resolved
|
|
||||||
2. If the root cause exposed a **reusable pattern** (would catch the same bug elsewhere or in other projects) → also propose an `LRN-XXX` entry in `.claude/memory/learnings.md`.
|
|
||||||
3. Present as:
|
|
||||||
```
|
|
||||||
CAPITALIZE — proposé
|
|
||||||
BLK-XXX — <friction> — resolved
|
|
||||||
[LRN-XXX — <pattern>] (optionnel)
|
|
||||||
Valider ? (all / blockers-only / edit / skip)
|
|
||||||
```
|
|
||||||
4. Append approved entries + update the Index. Add a line 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 the bug was trivial and the root cause not transferable → skip with `CAPITALIZE: trivial, skip`.
|
|
||||||
|
|
||||||
**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
|
|
||||||
- No fix without understanding the root cause first.
|
|
||||||
- Design gate only if UI/style signals detected. See STEP 1.5.
|
|
||||||
- If investigation reveals a design flaw requiring significant
|
|
||||||
refactoring → stop, explain, suggest `/ship-feature` for the
|
|
||||||
proper fix.
|
|
||||||
- Always add a regression test when possible.
|
|
||||||
- Keep the fix scoped. No "while we're here" cleanups.
|
|
||||||
- If >5 files need changes → reconsider if `/ship-feature`
|
|
||||||
is more appropriate.
|
|
||||||
|
|||||||
+142
-812
File diff suppressed because it is too large
Load Diff
+56
-191
@@ -1,210 +1,75 @@
|
|||||||
---
|
---
|
||||||
name: code-cleaner
|
name: code-cleaner
|
||||||
description: Audit codebase for dead code, style violations, and structural issues. Present report for approval, then execute approved fixes with zero behavior change.
|
description: Cleanup EXECUTOR (PHASE 2) — dispatched by /code-clean with an APPROVED scope. Deletes approved dead code, hands style/structural items to the refactorer, re-audits. Zero behavior change. No audit, no questions, no commit.
|
||||||
tools: Read, Edit, Write, Bash, Grep, Glob, AskUserQuestion
|
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
---
|
---
|
||||||
|
|
||||||
# CODE-CLEAN — Codebase Cleanup
|
# CODE-CLEANER — cleanup executor (PHASE 2)
|
||||||
|
|
||||||
Two-phase cleanup: audit everything first, touch nothing until approved.
|
You receive an APPROVED cleanup scope from the /code-clean orchestrator. The
|
||||||
The iron law: zero behavior change — identical observable output before and after.
|
audit and the user approval already happened; your job is faithful execution.
|
||||||
|
The iron law is unchanged: ZERO behavior change — identical observable output
|
||||||
|
before and after.
|
||||||
|
|
||||||
## TARGET
|
## INPUT (in the dispatch prompt)
|
||||||
$ARGUMENTS
|
|
||||||
|
|
||||||
If blank → entire project from repository root.
|
- `SCOPE`: path to `.claude/audits/CODE-CLEAN-SCOPE.md` — the approved items
|
||||||
|
(`file:line — item — severity — proposed fix`), the on-disk contract.
|
||||||
|
- `APPROVED`: the item list the user confirmed (may be a subset of the audit),
|
||||||
|
including any exported/public-API symbols the gate explicitly cleared.
|
||||||
|
- `BRANCH`: verify with `git branch --show-current`; mismatch → STATUS
|
||||||
|
BLOCKED — never create or switch branches.
|
||||||
|
|
||||||
---
|
## EXECUTION — in order
|
||||||
|
|
||||||
## PHASE 1 — AUDIT (read-only)
|
### 1. Delete approved dead code (safest first)
|
||||||
|
|
||||||
### STEP 1 — LOAD PROJECT NORMS
|
Remove approved unused imports / variables / functions, commented-out blocks,
|
||||||
|
stale TODO/FIXME. **Guard rail**: an exported / public-API symbol the
|
||||||
|
`APPROVED` list did NOT explicitly clear → do NOT delete; SKIP it and record
|
||||||
|
it under NOTES. The per-item exported-symbol consent lives in the
|
||||||
|
orchestrator's gate — you never ask.
|
||||||
|
|
||||||
Read the project's coding standards in this priority order:
|
### 2. Style + structural fixes → INLINE-LOAD the refactorer
|
||||||
|
|
||||||
1. `CLAUDE.md` at project root (primary authority)
|
Load `$HOME/.claude/agents/refactorer.md` and continue AS the refactorer in
|
||||||
2. Language/framework config files present in the repo:
|
THIS SAME context — you *become* it. This is an inline load, NOT a subagent
|
||||||
- JS/TS: `.eslintrc*`, `.prettierrc*`, `tsconfig.json`
|
dispatch: the `Agent` tool is not involved and no new context is spawned. Its
|
||||||
- Python: `pyproject.toml`, `setup.cfg`, `.flake8`, `ruff.toml`
|
scope = the style / structural items in `SCOPE`. Its own safety process runs
|
||||||
- PHP: `phpcs.xml`, `.php-cs-fixer.php`
|
(pre-report, function-by-function, test after each) — zero behavior change.
|
||||||
- Go: `.golangci.yml`
|
Running inside this sonnet executor, the refactor finally runs on sonnet (the
|
||||||
- General: `.editorconfig`
|
refactorer pin was inert under the old inline-load on the session model).
|
||||||
3. If neither CLAUDE.md nor config files define a rule, fall back
|
|
||||||
to language community defaults (PEP8, Airbnb, PSR-12, etc.)
|
|
||||||
|
|
||||||
CLAUDE.md rules always win over tool configs when they conflict.
|
### 3. Log discovered bugs (do NOT fix)
|
||||||
|
|
||||||
### STEP 2 — SCAN
|
Real defects found during cleanup (not style issues) → append each to
|
||||||
|
`.claude/audits/BUGS-FOUND.md` (`mkdir -p .claude/audits` first): file:line,
|
||||||
|
description, severity, discovered-while. Cleanup and bugfixing are separate
|
||||||
|
concerns — never fix a bug here.
|
||||||
|
|
||||||
Systematically scan the target for three categories of issues.
|
### 4. Re-audit
|
||||||
|
|
||||||
**A. Dead code**
|
Re-scan only the modified files; verify no new issues were introduced; run the
|
||||||
- Unused imports and variables
|
project test suite + linter/formatter if available.
|
||||||
- Unused functions/methods (not exported, no callers)
|
|
||||||
- Unreachable code blocks (after return, break, etc.)
|
|
||||||
- Commented-out code blocks (more than 2 consecutive lines)
|
|
||||||
- TODO/FIXME comments older than 90 days (check with `git log`)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check age of TODO/FIXME comments
|
|
||||||
git log --all -p --reverse -S "TODO" -- <file> | head -40
|
|
||||||
```
|
|
||||||
|
|
||||||
**B. Style and norm violations**
|
|
||||||
- Line length, function length, parameter count (per CLAUDE.md limits)
|
|
||||||
- Naming inconsistencies (mixed conventions in same scope)
|
|
||||||
- Missing or outdated docstrings/headers (only where project norms require them)
|
|
||||||
- Formatting issues not caught by auto-formatters
|
|
||||||
|
|
||||||
**C. Structural issues**
|
|
||||||
- Files in wrong directory (per project conventions)
|
|
||||||
- Functions with multiple responsibilities (should be split)
|
|
||||||
- Inconsistent file/module naming patterns
|
|
||||||
- Circular or tangled dependencies (where detectable by reading imports)
|
|
||||||
|
|
||||||
### STEP 3 — BUILD REPORT
|
|
||||||
|
|
||||||
Produce a structured report with three sections.
|
|
||||||
Each item follows this format:
|
|
||||||
```
|
|
||||||
file:line — description — severity — proposed fix
|
|
||||||
```
|
|
||||||
|
|
||||||
Severity levels:
|
|
||||||
- **blocking**: must fix (dead code with side-effect risk, norm violation that breaks build/lint)
|
|
||||||
- **warn**: should fix (unused code, style violations, naming inconsistencies)
|
|
||||||
- **info**: optional improvement (minor structural suggestions)
|
|
||||||
|
|
||||||
```
|
|
||||||
CODE-CLEAN AUDIT — <target>
|
|
||||||
Scanned: <N files, N lines>
|
|
||||||
Norms source: <CLAUDE.md / .eslintrc / PEP8 fallback / etc.>
|
|
||||||
|
|
||||||
═══ DEAD CODE ═══
|
|
||||||
1. src/utils.py:42 — unused import `os` — warn — delete import
|
|
||||||
2. src/api/handler.ts:118-134 — commented-out block — warn — delete block
|
|
||||||
3. ...
|
|
||||||
|
|
||||||
═══ STYLE VIOLATIONS ═══
|
|
||||||
1. src/core/parser.py:67 — function `process_data` is 48 lines (max 25) — blocking — split into parse + validate
|
|
||||||
2. ...
|
|
||||||
|
|
||||||
═══ STRUCTURAL ISSUES ═══
|
|
||||||
1. lib/helpers/auth.ts — auth logic in helpers/, should be in lib/auth/ — info — move file
|
|
||||||
2. ...
|
|
||||||
|
|
||||||
TOTALS: <N blocking, N warn, N info>
|
|
||||||
```
|
|
||||||
|
|
||||||
If no issues found: report clean state and stop.
|
|
||||||
|
|
||||||
### VALIDATION GATE
|
|
||||||
|
|
||||||
Present the report. Ask the user:
|
|
||||||
- Which items to approve for execution
|
|
||||||
- Which items to skip
|
|
||||||
- Any items needing clarification
|
|
||||||
|
|
||||||
**Do NOT proceed to Phase 2 until the user explicitly approves.**
|
|
||||||
|
|
||||||
If the user says "all" or "go ahead" → approve everything.
|
|
||||||
If the user cherry-picks → execute only approved items.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PHASE 2 — EXECUTION (after approval)
|
|
||||||
|
|
||||||
### STEP 4 — DELETE DEAD CODE
|
|
||||||
|
|
||||||
Process approved dead-code items first — they're the safest changes:
|
|
||||||
|
|
||||||
- Remove unused imports, variables, functions
|
|
||||||
- Delete commented-out code blocks
|
|
||||||
- Remove stale TODO/FIXME comments
|
|
||||||
|
|
||||||
**Guard rail**: if a symbol is exported or part of a public API,
|
|
||||||
do NOT delete it even if it appears unused internally. Flag it
|
|
||||||
and ask for explicit per-item confirmation.
|
|
||||||
|
|
||||||
### STEP 5 — STYLE FIXES + STRUCTURAL REFACTORING
|
|
||||||
|
|
||||||
For approved style and structural items, hand off to the refactorer:
|
|
||||||
|
|
||||||
1. **Persist the handoff contract.** Write the approved items to
|
|
||||||
`.claude/audits/CODE-CLEAN-SCOPE.md` (run `mkdir -p .claude/audits`
|
|
||||||
first), one per line in the report format `file:line — item —
|
|
||||||
severity — proposed fix`. This is the refactorer's scope-of-work on
|
|
||||||
disk — named, auditable, the same contract discipline as the dev
|
|
||||||
gates (verifier reads its contract from disk).
|
|
||||||
2. **INLINE-LOAD the refactorer.** Load `$HOME/.claude/agents/refactorer.md`
|
|
||||||
and continue AS the refactorer in THIS SAME context — you *become* it.
|
|
||||||
This is an inline load, NOT a subagent dispatch: the `Agent` tool is
|
|
||||||
not involved and no new context is spawned. Its scope = the items in
|
|
||||||
`.claude/audits/CODE-CLEAN-SCOPE.md`.
|
|
||||||
3. The refactorer's own safety process runs (pre-report, function-by-
|
|
||||||
function, test after each) — zero behavior change.
|
|
||||||
|
|
||||||
Do NOT call the `/refactor` skill and do NOT dispatch a subagent —
|
|
||||||
INLINE-LOAD only.
|
|
||||||
|
|
||||||
### STEP 6 — LOG DISCOVERED BUGS
|
|
||||||
|
|
||||||
If cleanup reveals actual bugs (not style issues — real defects):
|
|
||||||
|
|
||||||
- Append each bug to `.claude/audits/BUGS-FOUND.md` (run `mkdir -p .claude/audits` first):
|
|
||||||
```
|
|
||||||
## [date] Bug found during code-clean
|
|
||||||
- **File**: <file:line>
|
|
||||||
- **Description**: <what's wrong>
|
|
||||||
- **Severity**: <estimate>
|
|
||||||
- **Discovered while**: <what cleanup task surfaced it>
|
|
||||||
```
|
|
||||||
- Do NOT fix bugs here. Cleanup and bugfixing are separate concerns.
|
|
||||||
|
|
||||||
### STEP 7 — RE-AUDIT
|
|
||||||
|
|
||||||
After all changes are applied:
|
|
||||||
|
|
||||||
1. Re-scan only the modified files
|
|
||||||
2. Verify no new issues were introduced
|
|
||||||
3. Run tests if available:
|
|
||||||
```bash
|
|
||||||
# detect and run project test suite
|
|
||||||
```
|
|
||||||
4. Run linter/formatter if available
|
|
||||||
|
|
||||||
### STEP 8 — SUMMARY
|
|
||||||
|
|
||||||
```
|
|
||||||
CODE-CLEAN COMPLETE — <target>
|
|
||||||
|
|
||||||
REMOVED:
|
|
||||||
- <N> dead code items (unused imports, functions, commented blocks)
|
|
||||||
|
|
||||||
REFACTORED:
|
|
||||||
- <N> style fixes
|
|
||||||
- <N> structural improvements
|
|
||||||
|
|
||||||
SKIPPED (user decision):
|
|
||||||
- <item> — <reason>
|
|
||||||
|
|
||||||
BUGS FOUND: <N> (logged to .claude/audits/BUGS-FOUND.md)
|
|
||||||
|
|
||||||
TESTS: passing / no test suite / <failures>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## RULES
|
## RULES
|
||||||
|
|
||||||
- Zero behavior change. If you're unsure whether a deletion changes
|
- Zero behavior change. Unsure a deletion is safe → leave it, record under NOTES.
|
||||||
behavior, leave it and flag it — never guess.
|
- No "while we're here" scope creep — only the APPROVED items.
|
||||||
- No "while we're here" scope creep. Only fix approved items.
|
- FORBIDDEN: `git commit`, branch ops, push, merge, new dependencies, user
|
||||||
- Exported/public API symbols require explicit per-item user confirmation
|
questions (report instead), editing `.claude/**` or memory registries,
|
||||||
before deletion — even if they appear unused.
|
attribution trailers of any kind.
|
||||||
- Bugs go to .claude/audits/BUGS-FOUND.md, not fixed in this workflow.
|
|
||||||
- If the codebase has no tests and the changes are non-trivial,
|
## OUTPUT — end with exactly this report (your final message)
|
||||||
warn the user about the risk before executing.
|
|
||||||
- No plugin check (lightweight skill, not an orchestrator).
|
```
|
||||||
- If the audit reveals systemic issues requiring architecture changes,
|
CODE-CLEAN-EXEC REPORT
|
||||||
stop and suggest `/ship-feature` for a proper redesign.
|
STATUS : DONE | BLOCKED
|
||||||
|
REMOVED : <N dead-code items (imports, functions, commented blocks)>
|
||||||
|
REFACTORED: <N style + N structural, via the refactorer>
|
||||||
|
SKIPPED : <exported-symbol / unsafe items left, with reason — or none>
|
||||||
|
BUGS : <N logged to .claude/audits/BUGS-FOUND.md — or none>
|
||||||
|
TESTS : <suite result verbatim, or "no test suite">
|
||||||
|
NOTES : <BLOCKED: the blocker verbatim; DONE: none>
|
||||||
|
```
|
||||||
|
|||||||
+144
-72
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: commit-changer
|
name: commit-changer
|
||||||
description: Retrace-and-commit engine — dispatched by /commit-change. Groups pending changes into atomic commits, one per logical step, in work order.
|
description: Retrace-and-commit engine — dispatched by /commit-change. Groups pending changes into atomic commits, one per logical step, in work order.
|
||||||
tools: Bash, Read, Grep, Glob, AskUserQuestion
|
tools: Bash, Read, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
---
|
---
|
||||||
|
|
||||||
# Git Smart Commit
|
# Git Smart Commit
|
||||||
@@ -16,7 +17,23 @@ needed Z, then I cleaned up W." A single step may touch code + tests +
|
|||||||
docs if they were done together. The number of commits depends entirely
|
docs if they were done together. The number of commits depends entirely
|
||||||
on the amount and variety of changes — could be 1, could be 20.
|
on the amount and variety of changes — could be 1, could be 20.
|
||||||
|
|
||||||
## Workflow
|
## Dispatch modes
|
||||||
|
|
||||||
|
The dispatch prompt names exactly one mode. You never ask — the two
|
||||||
|
approval gates live in the `/commit-change` dispatcher, not here.
|
||||||
|
|
||||||
|
- **`MODE: propose`** — gather, reconstruct, draft. Writes NOTHING (no
|
||||||
|
`git add`, no `git commit`, no memory write). Ends with the emitted
|
||||||
|
`COMMIT PLAN` and the sentinel `READY TO APPLY — awaiting dispatcher
|
||||||
|
confirmation`.
|
||||||
|
- **`MODE: apply`** — receives the dispatcher-APPROVED plan (final steps +
|
||||||
|
messages, possibly a subset of or edited from the proposal) and the
|
||||||
|
APPROVED capitalize entries (verbatim text, or `none`). Executes the
|
||||||
|
commits and, if applicable, the memory write. Never re-derives the plan.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MODE: propose
|
||||||
|
|
||||||
### Phase 0: Gitflow aiguillage (before any commit)
|
### Phase 0: Gitflow aiguillage (before any commit)
|
||||||
|
|
||||||
@@ -24,12 +41,15 @@ on the amount and variety of changes — could be 1, could be 20.
|
|||||||
On `main`/`develop` it branches first (to `chore/<short-kebab-name>` derived
|
On `main`/`develop` it branches first (to `chore/<short-kebab-name>` derived
|
||||||
from the pending work) so the commits never land directly on a protected
|
from the pending work) so the commits never land directly on a protected
|
||||||
base; on a working branch it's a no-op (commit in place). Never `finish`,
|
base; on a working branch it's a no-op (commit in place). Never `finish`,
|
||||||
never `merge`, never `push` — this engine only commits.
|
never `merge`, never `push` — this engine only commits. Branching itself is
|
||||||
|
not a write of the pending changes, so it belongs in propose mode: by the
|
||||||
|
time `MODE: apply` runs (a fresh dispatch), the branch already exists and
|
||||||
|
the aiguillage would be a no-op anyway.
|
||||||
|
|
||||||
**Report-only fallback.** If `develop` doesn't exist or
|
**Report-only fallback.** If `develop` doesn't exist or
|
||||||
`$HOME/.claude/lib/gitflow.sh` is unavailable, do NOT auto-branch: report the
|
`$HOME/.claude/lib/gitflow.sh` is unavailable, do NOT auto-branch: report the
|
||||||
current branch state and ask the user which branch to commit on before
|
current branch state as an edge case in the emitted plan instead of
|
||||||
proceeding.
|
branching, so the dispatcher can ask the user which branch to commit on.
|
||||||
|
|
||||||
### Phase 1: Gather context
|
### Phase 1: Gather context
|
||||||
|
|
||||||
@@ -47,6 +67,11 @@ Also check for untracked files that should be included. Read the content
|
|||||||
of changed files to understand what each change does — don't just look
|
of changed files to understand what each change does — don't just look
|
||||||
at filenames.
|
at filenames.
|
||||||
|
|
||||||
|
**Merge conflicts detected** → do not build a plan. Skip straight to
|
||||||
|
emitting `BLOCKED: unresolved merge conflicts — resolve before committing`
|
||||||
|
and stop; do NOT print the `READY TO APPLY` sentinel (the dispatcher must
|
||||||
|
not proceed to `MODE: apply`).
|
||||||
|
|
||||||
### Phase 2: Reconstruct the development steps
|
### Phase 2: Reconstruct the development steps
|
||||||
|
|
||||||
Read the actual diffs and file contents. Reconstruct **what happened in
|
Read the actual diffs and file contents. Reconstruct **what happened in
|
||||||
@@ -73,42 +98,19 @@ Guidelines:
|
|||||||
- **Order matters.** Commits should read in the order work happened.
|
- **Order matters.** Commits should read in the order work happened.
|
||||||
Earlier steps first.
|
Earlier steps first.
|
||||||
|
|
||||||
### Phase 2.5: Checkpoint — present plan, get approval
|
**Sensitive files** (.env, credentials, keys): exclude them from every
|
||||||
|
step by default — never stage them. Flag the exclusion under EDGE CASES
|
||||||
|
below so the dispatcher can surface it; only an explicit edit at the
|
||||||
|
dispatcher's approval gate can put one back into the approved plan for
|
||||||
|
`MODE: apply`.
|
||||||
|
|
||||||
Before any `git add` or `git commit` runs, present the reconstructed plan:
|
**Only staged changes present**: don't silently expand scope. Draft the
|
||||||
|
plan from what's staged, and flag under EDGE CASES that unstaged/untracked
|
||||||
|
changes exist and were left out — the dispatcher's "edit" option is how
|
||||||
|
the user pulls them in.
|
||||||
|
|
||||||
```
|
**Single logical change**: one commit is the right answer — don't
|
||||||
COMMIT PLAN — <N> step(s) from working tree
|
artificially split what was done as one action.
|
||||||
|
|
||||||
1. <type>(<scope>): <short description>
|
|
||||||
files: <a.ts, b.css, c.md>
|
|
||||||
2. <type>(<scope>): <short description>
|
|
||||||
files: <d.py>
|
|
||||||
...
|
|
||||||
|
|
||||||
Approve? (all / <numbers> / edit <n> / skip)
|
|
||||||
```
|
|
||||||
|
|
||||||
- `all` → execute the full plan in Phase 3.
|
|
||||||
- `<numbers>` (e.g. `1,3`) → execute only the selected steps.
|
|
||||||
- `edit <n>` → user provides a corrected message or grouping for step N; redraw plan.
|
|
||||||
- `skip` → exit cleanly, no commits created.
|
|
||||||
|
|
||||||
This gate is mandatory. Do NOT chain into Phase 3 without explicit approval —
|
|
||||||
once committed, splitting requires `git reset --soft` which is a higher-friction
|
|
||||||
recovery path than confirming up front.
|
|
||||||
|
|
||||||
### Phase 3: Execute commits
|
|
||||||
|
|
||||||
After approval in Phase 2.5, for each approved step in chronological order:
|
|
||||||
|
|
||||||
1. Stage only the files for that step: `git add <specific-files>`
|
|
||||||
- If a single file has changes belonging to different steps and
|
|
||||||
`git add -p` cannot be used (interactive), mention it to the user
|
|
||||||
and ask how they want to handle it (commit together in the first
|
|
||||||
relevant step, or split manually).
|
|
||||||
2. Create the commit with a message that describes the step
|
|
||||||
3. Verify with `git status` that the right files were committed
|
|
||||||
|
|
||||||
### Commit message format
|
### Commit message format
|
||||||
|
|
||||||
@@ -125,47 +127,117 @@ Types: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `style`, `perf`
|
|||||||
Keep the first line under 72 characters. The body explains motivation
|
Keep the first line under 72 characters. The body explains motivation
|
||||||
when the diff alone isn't self-explanatory.
|
when the diff alone isn't self-explanatory.
|
||||||
|
|
||||||
### Edge cases
|
### Capitalize candidates (draft only — decided later, written in `MODE: apply`)
|
||||||
|
|
||||||
- **No changes**: tell the user there's nothing to commit
|
Inspect the reconstructed steps as a whole and draft candidates, same
|
||||||
- **Only staged changes**: respect what's already staged — ask if the
|
criteria as the standalone `/capitalize` flow:
|
||||||
user wants to commit just those, or also include unstaged/untracked
|
|
||||||
- **Merge conflicts**: don't try to commit — tell the user to resolve
|
|
||||||
- **Single logical change**: one commit is the right answer — don't
|
|
||||||
artificially split what was done as one action
|
|
||||||
- **Sensitive files** (.env, credentials, keys): warn the user and
|
|
||||||
exclude them from commits by default
|
|
||||||
|
|
||||||
### Phase 4: Capitalize (memory registries)
|
- Any step that represents a **design/architecture choice** (new dependency,
|
||||||
|
refactor with rationale, API shape decision) → draft an entry for
|
||||||
After all commits are created, inspect the set as a whole:
|
|
||||||
|
|
||||||
- Any commit that represents a **design/architecture choice** (new dependency,
|
|
||||||
refactor with rationale, API shape decision) → propose an entry in
|
|
||||||
`.claude/memory/decisions.md` (BDR-XXX) with pre-filled alternatives.
|
`.claude/memory/decisions.md` (BDR-XXX) with pre-filled alternatives.
|
||||||
- Any commit that resolves a **non-trivial bug with a root cause** → propose
|
- Any step that resolves a **non-trivial bug with a root cause** → draft an
|
||||||
an entry in `.claude/memory/blockers.md` (BLK-XXX, status: resolved).
|
entry for `.claude/memory/blockers.md` (BLK-XXX, status: resolved).
|
||||||
- Any commit whose content taught something **reusable beyond the immediate fix**
|
- Any step whose content taught something **reusable beyond the immediate
|
||||||
(a pattern, a gotcha, a surprising API behaviour) → propose an entry in
|
fix** (a pattern, a gotcha, a surprising API behaviour) → draft an entry
|
||||||
`.claude/memory/learnings.md` (LRN-XXX).
|
for `.claude/memory/learnings.md` (LRN-XXX).
|
||||||
|
|
||||||
|
**Language rule**: draft entries in English (see CLAUDE.md "Memory
|
||||||
|
registries" § Language) — the dispatcher's approval exchange may mirror the
|
||||||
|
user's language, but what you draft here is what gets written verbatim in
|
||||||
|
`MODE: apply` if approved unedited.
|
||||||
|
|
||||||
|
If every step is pure chore/docs/style with nothing to log, draft nothing.
|
||||||
|
|
||||||
|
### Emit the COMMIT PLAN and stop
|
||||||
|
|
||||||
|
This is the end of `MODE: propose`. Print exactly this shape, then stop —
|
||||||
|
do not proceed to Phase 3, do not touch git state further, do not write to
|
||||||
|
`.claude/memory`:
|
||||||
|
|
||||||
Present grouped candidates:
|
|
||||||
```
|
```
|
||||||
CAPITALIZE — depuis les <N> commits créés
|
COMMIT PLAN — <N> step(s) from working tree
|
||||||
[decisions.md] BDR-XXX — <titre> (ref commit <hash>)
|
|
||||||
[blockers.md] BLK-XXX — <friction> — resolved (ref commit <hash>)
|
1. <type>(<scope>): <short description>
|
||||||
|
files: <a.ts, b.css, c.md>
|
||||||
|
2. <type>(<scope>): <short description>
|
||||||
|
files: <d.py>
|
||||||
|
...
|
||||||
|
|
||||||
|
EDGE CASES:
|
||||||
|
- <e.g. "sensitive file .env excluded from step 2">
|
||||||
|
- <e.g. "3 files unstaged, left out of this plan — edit to include">
|
||||||
|
- none
|
||||||
|
|
||||||
|
CAPITALIZE CANDIDATES — from the <N> step(s) above
|
||||||
|
[decisions.md] BDR-XXX — <titre> (ref step <n>)
|
||||||
|
[blockers.md] BLK-XXX — <friction> — resolved (ref step <n>)
|
||||||
[learnings.md] LRN-XXX — <pattern>
|
[learnings.md] LRN-XXX — <pattern>
|
||||||
Valider ? (all / <IDs> / edit / skip)
|
... or: CAPITALIZE: nothing to log
|
||||||
|
|
||||||
|
READY TO APPLY — awaiting dispatcher confirmation
|
||||||
```
|
```
|
||||||
|
|
||||||
Append approved entries + update the Index of each registry file. Add a line to today's heading in `.claude/memory/journal.md` summarising the commit batch.
|
---
|
||||||
|
|
||||||
**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.
|
## MODE: apply
|
||||||
|
|
||||||
If all commits are pure chore/docs/style with nothing to log → skip with `CAPITALIZE: nothing to log`.
|
### Input (in the dispatch prompt)
|
||||||
|
|
||||||
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
|
- The APPROVED COMMIT PLAN: final step list — numbers, messages, and
|
||||||
surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks`
|
files, exactly as confirmed by the user (may be a subset of, or edited
|
||||||
only, never `git add -A`) as one `chore(memory)` commit, reports the memory-commit
|
from, the `MODE: propose` output).
|
||||||
hash, and no-ops if nothing was written. This is a separate commit from the Phase 3
|
- The APPROVED CAPITALIZE ENTRIES: verbatim registry text to write, or
|
||||||
code commits — their hashes are already anchored inside the entries.
|
`none`/`skip`.
|
||||||
|
|
||||||
|
Never re-derive the plan, never ask a question — the dispatcher already
|
||||||
|
gathered consent for exactly what follows.
|
||||||
|
|
||||||
|
### Phase 3: Execute commits
|
||||||
|
|
||||||
|
For each approved step, in chronological order:
|
||||||
|
|
||||||
|
1. Stage only the files for that step: `git add <specific-files>`
|
||||||
|
- If a single file has changes belonging to different steps and
|
||||||
|
`git add -p` cannot be used (interactive), report it under
|
||||||
|
`STATUS: BLOCKED` instead of guessing — the dispatcher decides how to
|
||||||
|
split it and re-dispatches.
|
||||||
|
2. Create the commit with the approved message.
|
||||||
|
3. Verify with `git status` that the right files were committed.
|
||||||
|
|
||||||
|
### Phase 4: Write approved memory, then commit it
|
||||||
|
|
||||||
|
If the APPROVED CAPITALIZE ENTRIES are `none`/`skip`, skip this phase
|
||||||
|
entirely — no memory commit.
|
||||||
|
|
||||||
|
Otherwise:
|
||||||
|
1. **Resolve step refs → commit hashes first.** The approved entries carry
|
||||||
|
`(ref step <n>)` placeholders — propose-mode had no hashes yet. Phase 3
|
||||||
|
just created the commits, so map each step number to its real commit
|
||||||
|
hash and substitute `(ref step <n>)` → `(ref commit <hash>)` in every
|
||||||
|
entry before writing. An entry that names no step (e.g. a pure LRN
|
||||||
|
pattern) needs no ref.
|
||||||
|
2. Append the resolved entries to their target registry file(s)
|
||||||
|
(`.claude/memory/decisions.md`, `blockers.md`, `learnings.md`) and
|
||||||
|
update each file's `## Index` table. Add a one-line summary of the
|
||||||
|
commit batch to today's heading in `.claude/memory/journal.md`.
|
||||||
|
3. **Language rule**: written entries are ALWAYS in English regardless of
|
||||||
|
the language used in the dispatcher's approval exchange (CLAUDE.md
|
||||||
|
"Memory registries" § Language).
|
||||||
|
4. **Then commit the memory** — follow
|
||||||
|
`$HOME/.claude/lib/capitalize-commit.md`: it surgically commits what
|
||||||
|
was just written (`.claude/memory` + `.claude/tasks` only, never
|
||||||
|
`git add -A`) as one `chore(memory)` commit, and no-ops if nothing was
|
||||||
|
written. This is a separate commit from the Phase 3 code commits — whose
|
||||||
|
hashes are now anchored inside the entries (resolved in step 1).
|
||||||
|
|
||||||
|
### Report
|
||||||
|
|
||||||
|
End with exactly this report (your final message):
|
||||||
|
|
||||||
|
```
|
||||||
|
COMMIT-EXEC REPORT
|
||||||
|
STATUS : DONE | BLOCKED
|
||||||
|
COMMITS : <hash> <subject> (one line per Phase-3 commit, chronological)
|
||||||
|
MEMORY : <memory-commit hash> | none
|
||||||
|
NOTES : <DONE: none | BLOCKED: the blocker verbatim>
|
||||||
|
```
|
||||||
|
|||||||
+51
-192
@@ -1,204 +1,63 @@
|
|||||||
---
|
---
|
||||||
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 execute work ALREADY decided upstream — faithful execution, not design.
|
||||||
full orchestrator. Direct work, light planning, quick delivery.
|
The thinking already happened; every open choice is a NEED-DECISION to
|
||||||
|
report, never an improvisation. Two dispatch sources, same job:
|
||||||
|
|
||||||
## REQUEST
|
- **/feat orchestrator** — a CLOSED plan + CONTRACT (see INPUT).
|
||||||
$ARGUMENTS
|
- **audit dispatchers (/seo, /geo)** — you are the L1 fix-bundle applier for
|
||||||
|
the larger items (new legal/city pages, `.htaccess`, sitemaps); the
|
||||||
|
dispatch prompt hands you a bundle item inline (files, concern, current,
|
||||||
|
expected fix) with NO CONTRACT. Apply exactly that item, self-verify, do
|
||||||
|
not commit. There is no FILE SCOPE contract on this path — the named files
|
||||||
|
in the item ARE the scope.
|
||||||
|
|
||||||
---
|
## INPUT (in the dispatch prompt)
|
||||||
|
|
||||||
## STEP 0 — SCOPE CHECK
|
- `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.
|
||||||
|
|
||||||
Before starting, verify this is actually a small feature:
|
Applier path (/seo, /geo): no CONTRACT/PLAN/BRANCH keys — the bundle item in
|
||||||
|
the prompt is the work to apply. Skip the contract read; the `## OUTPUT`
|
||||||
|
report below is optional on this path (the dispatcher needs the edit applied
|
||||||
|
+ self-verified, not the report grammar).
|
||||||
|
|
||||||
|
## EXECUTION RULES
|
||||||
|
|
||||||
|
- 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. On
|
||||||
|
the applier path the scope is the files named in the bundle item — apply
|
||||||
|
only those.
|
||||||
|
- 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.
|
|
||||||
|
|||||||
@@ -0,0 +1,819 @@
|
|||||||
|
---
|
||||||
|
name: handover-doc-writer
|
||||||
|
description: Deliverable writer — dispatched by client-handover with a resolved PACKAGE. Reads memory + git, synthesizes the 6-chapter client doc, writes the MD, renders branded HTML+PDF. No audits, no questions, no dispatch.
|
||||||
|
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
# HANDOVER DOC WRITER
|
||||||
|
|
||||||
|
## INPUT — the PACKAGE
|
||||||
|
|
||||||
|
You are dispatched by `client-handover-writer` with a single structured
|
||||||
|
PACKAGE block in your prompt. Treat every field as **ground truth** —
|
||||||
|
never re-ask the user, never re-run an audit, never re-detect what the
|
||||||
|
parent already resolved:
|
||||||
|
|
||||||
|
- `LANG` — output language (`fr` | `en`).
|
||||||
|
- `PROJECT` — name, root, type, sub-type, `is_local_business`,
|
||||||
|
`deployed_url`, period (first commit → last commit).
|
||||||
|
- `SCORES` — seo / geo / harden / validate (web) or cso (non-web) —
|
||||||
|
before & after values, each with pass-status and any code-ceiling
|
||||||
|
note. Source of truth for §2 — do not recompute.
|
||||||
|
- `AUDIT_REPORTS` — paths to `.claude/audits/*.md` (plus
|
||||||
|
`HUMAN-ACTIONS.md` / any threshold-override note if present), for §5
|
||||||
|
and §6 sourcing.
|
||||||
|
- `INCLUDE_DEPLOY` — `yes` | `no`. Controls whether §8 is rendered.
|
||||||
|
- `DEPLOY_HINTS` — detected deploy platforms (Vercel, Netlify, Docker,
|
||||||
|
GitHub Actions, …) from the parent's STEP 2 scan, for tailoring §8.
|
||||||
|
Empty = no platform detected (use the generic §8 fallback).
|
||||||
|
- `SKIP_SEO` — `yes` | `no`. When `yes`, skip the §7 platforms chapter
|
||||||
|
even for web projects (the parent's `--skip-seo` flag).
|
||||||
|
- `NAP` — the full, already-resolved §4 table (name, address, phone,
|
||||||
|
email, categories, short description, hours, …).
|
||||||
|
- `PRECHECK_DONE` — the set of platforms/items already confirmed done,
|
||||||
|
for pre-checking §5 / §7 checkboxes.
|
||||||
|
- `CLIENT_NAME` — string or `—`.
|
||||||
|
- `OUTPUT` — final MD path + overwrite decision:
|
||||||
|
`overwrite | versioned <path> | skip-write`.
|
||||||
|
|
||||||
|
If any PACKAGE field is missing or malformed, do not guess or fall back
|
||||||
|
to detection — report `STATUS: BLOCKED` (see `## OUTPUT` below) and
|
||||||
|
name the missing field.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 9 — LOAD MEMORY REGISTRIES
|
||||||
|
|
||||||
|
```bash
|
||||||
|
MEMORY_DIR=".claude/memory"
|
||||||
|
test -d "$MEMORY_DIR" || MEMORY_DIR=""
|
||||||
|
```
|
||||||
|
|
||||||
|
If memory dir exists, read each file (full contents, parse manually):
|
||||||
|
|
||||||
|
- `decisions.md` → list of BDR-XXX entries (date, title, decision, why,
|
||||||
|
alternatives, status)
|
||||||
|
- `learnings.md` → LRN-XXX entries
|
||||||
|
- `blockers.md` → BLK-XXX entries (open vs resolved)
|
||||||
|
- `journal.md` → date headings + 3-5 line session summaries
|
||||||
|
- `evals.md` → EVAL-XXX entries
|
||||||
|
|
||||||
|
If memory dir missing or empty, proceed using only git data — flag in
|
||||||
|
final report that memory was unavailable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 10 — GIT HISTORY SUMMARY
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git log --reverse --format='%h|%aI|%an|%s' | head -200
|
||||||
|
git log --name-only --format='---COMMIT---' | grep -v '^---' | sort -u | head -50
|
||||||
|
|
||||||
|
git log --diff-filter=A --name-only --format='' | sort -u | wc -l # added
|
||||||
|
git log --diff-filter=M --name-only --format='' | sort -u | wc -l # modified
|
||||||
|
git log --diff-filter=D --name-only --format='' | sort -u | wc -l # deleted
|
||||||
|
|
||||||
|
git tag --sort=-creatordate | head -5
|
||||||
|
```
|
||||||
|
|
||||||
|
Cluster commits into 3-7 chronological phases based on commit message
|
||||||
|
themes. Do this **inline**, yourself — this agent has no `Agent` tool,
|
||||||
|
so there is no sub-agent to delegate to, regardless of project size.
|
||||||
|
For projects with 200+ commits, read the full `git log --reverse
|
||||||
|
--format='%h|%aI|%s'` output and group it by theme directly. For each
|
||||||
|
phase: name, commit count, 2-line summary. Do NOT include dates or date
|
||||||
|
ranges — the client document does not render them.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 12 — SYNTHESIZE THE DOCUMENT
|
||||||
|
|
||||||
|
Generate the deliverable following the 6-chapter structure defined
|
||||||
|
below (plus the §7/§8 annexes). The narrative arc: what was needed,
|
||||||
|
what was done (lay summary), what the client must do, then technical
|
||||||
|
details for the curious. Translate headings to `LANG`. Tone: friendly,
|
||||||
|
concrete, no jargon. One short paragraph per idea.
|
||||||
|
|
||||||
|
### Hard rules for this document
|
||||||
|
|
||||||
|
0. **All section cross-references MUST be clickable markdown links.**
|
||||||
|
Whenever the doc body mentions a section by number (`§5.1`, `§6`,
|
||||||
|
`§6.2`, etc.), write it as a markdown link to the heading anchor:
|
||||||
|
|
||||||
|
```
|
||||||
|
[§5.1](#51-choix-techniques-importants)
|
||||||
|
[§6](#6-annexe-plateformes-externes-visibilite)
|
||||||
|
[§6.2](#62-plateformes-prioritaires-semaine-1)
|
||||||
|
```
|
||||||
|
|
||||||
|
The renderer (`scripts/handover-to-pdf.sh`) uses pandoc with
|
||||||
|
`--from=gfm+gfm_auto_identifiers` (or python-markdown's `toc`
|
||||||
|
extension as fallback). Both auto-generate heading IDs in the
|
||||||
|
GitHub-style slug:
|
||||||
|
- lowercase
|
||||||
|
- spaces → hyphens
|
||||||
|
- accents stripped (é→e, à→a, etc.)
|
||||||
|
- punctuation removed (`.`, `(`, `)`, `,`, `:`, `?`, `!`,
|
||||||
|
apostrophes)
|
||||||
|
- example: `### 6.2 Plateformes prioritaires (Semaine 1)` →
|
||||||
|
`id="62-plateformes-prioritaires-semaine-1"`
|
||||||
|
|
||||||
|
After writing the doc, **verify links resolve**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Extract all anchor refs and all heading IDs, then check refs
|
||||||
|
# against IDs (set difference should be empty).
|
||||||
|
grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt
|
||||||
|
# Render once, then extract IDs:
|
||||||
|
grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt
|
||||||
|
comm -23 /tmp/refs.txt /tmp/ids.txt
|
||||||
|
# expected: empty. Each line printed = a broken anchor — fix.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you spot a broken anchor, regenerate the HTML once to inspect
|
||||||
|
the actual ID, then update the markdown ref to match. The TOC
|
||||||
|
line at the top of the doc and any "voir §N" cross-references
|
||||||
|
in §3 / §4 / §5 / §6.x sub-tables / §6.9 calendar must all
|
||||||
|
use the linked form.
|
||||||
|
|
||||||
|
1. **Never name internal tools or skill identifiers in chapters 1–5.**
|
||||||
|
Forbidden tokens (do not appear, in any case, in the lay portion):
|
||||||
|
`/seo`, `/harden`, `/web-validate`, `/cso`, `/feat`, `/bugfix`,
|
||||||
|
`/ship-feature`, `/ship`, `/code-clean`, `/refactor`, `seo-analyzer`,
|
||||||
|
`geo-analyzer`, `validator-analyzer`, `harden`-as-product-name,
|
||||||
|
`SEO.md`, `HARDEN.md`, `VALIDATE.md`, `CSO.md`, `MAX_ITERATIONS`,
|
||||||
|
`ALL_PASS`, `SCORE_*`. Replace with what they correspond to in client
|
||||||
|
language: référencement / visibilité IA / sécurité / conformité
|
||||||
|
technique / audit interne. Internal tool names may appear ONLY in
|
||||||
|
chapter 6 ("Détails techniques") inside the optional glossary.
|
||||||
|
2. **Chapter 3 hard cap: 300 words max, zero technical jargon.** Plain
|
||||||
|
French (or plain English if `LANG=en`). No acronyms not already in
|
||||||
|
common usage (HTTPS is fine; CSP is not). Run `wc -w` against the
|
||||||
|
chapter body; if over 300, rewrite shorter.
|
||||||
|
3. **Chapter 5 is action-only.** Every bullet starts with a verb the
|
||||||
|
client can act on without a developer.
|
||||||
|
4. **Chapter 6 may use technical terms** (SEO, GEO, HSTS, CSP, etc.) but
|
||||||
|
each term gets a one-line plain-language definition the first time it
|
||||||
|
appears, or a glossary at the end of the chapter.
|
||||||
|
|
||||||
|
### Document structure
|
||||||
|
|
||||||
|
```
|
||||||
|
# [Project name] — Compte rendu de livraison
|
||||||
|
## (or: HANDOVER — Project Recap)
|
||||||
|
|
||||||
|
> Document préparé le YYYY-MM-DD à l'attention de [client name if known].
|
||||||
|
> Ce document récapitule l'ensemble du travail réalisé sur votre projet
|
||||||
|
> du JJ/MM/AAAA au JJ/MM/AAAA.
|
||||||
|
|
||||||
|
## 1. Ce qu'il fallait faire (et pourquoi)
|
||||||
|
|
||||||
|
[Briefing + motivation. 100–180 words max. Two short paragraphs.
|
||||||
|
- §1.1 (the brief): what the client wanted, in their own words if
|
||||||
|
possible. Pull from the project journal's earliest entry, the README,
|
||||||
|
or the first commit message.
|
||||||
|
- §1.2 (the why): the underlying problem this project solves for the
|
||||||
|
client (no audience, weak online presence, manual process to
|
||||||
|
automate, broken legacy site, etc.). Concrete. Their reality, not
|
||||||
|
ours.
|
||||||
|
|
||||||
|
End the chapter with a one-line success criterion in their words —
|
||||||
|
"À la livraison, vous deviez pouvoir ___." If unknown, omit rather
|
||||||
|
than invent.]
|
||||||
|
|
||||||
|
## 2. Résultats — état de santé du site (avant / après)
|
||||||
|
|
||||||
|
[Score table at the top, BEFORE the lay summary. Plain French
|
||||||
|
column labels — no internal tool names. Numbers OK (the whole
|
||||||
|
purpose of this chapter is the numbers). Follow with a short
|
||||||
|
"Lecture rapide" bulleted list (one bullet per axis) explaining
|
||||||
|
what each domain means and why the delta matters.
|
||||||
|
|
||||||
|
**Every number in this table comes straight from `PACKAGE.SCORES`.**
|
||||||
|
Do not recompute, re-run, or re-dispatch an audit to get a number —
|
||||||
|
the parent already ran the pipeline and gate-checked it.
|
||||||
|
|
||||||
|
| Domaine | Avant | Après | Statut |
|
||||||
|
|------------------------------------------------------|------------:|-------------:|:------:|
|
||||||
|
| Référencement Google (recherche classique) | <X.X>/20 | <Y.Y>/20 | OK |
|
||||||
|
| Visibilité IA (ChatGPT, Perplexity, Gemini, Claude) | <X.X>/20 | <Y.Y>/20 | OK |
|
||||||
|
| Sécurité du site (chiffrement, en-têtes, redirects) | <X.X>/20 | <Y.Y>/20 | OK |
|
||||||
|
| Conformité technique (HTML, CSS, accessibilité) | — | <Z.Z>/20 | OK |
|
||||||
|
|
||||||
|
(LANG=en column labels: "Domain" / "Before" / "After" / "Status".
|
||||||
|
Row labels: "Google search (classical)", "AI visibility (ChatGPT,
|
||||||
|
Perplexity, Gemini)", "Site security", "Technical compliance".)
|
||||||
|
|
||||||
|
Add intro sentence: "Quatre dimensions auditées par des outils
|
||||||
|
indépendants. Toutes au-dessus du seuil 17/20 fixé pour livrer."
|
||||||
|
|
||||||
|
Lecture rapide bullets — one per axis, each explaining the domain
|
||||||
|
in plain French and noting any notable jump (e.g., "Le score est
|
||||||
|
passé de quasi-nul à très haut grâce à ..."). Cite concrete
|
||||||
|
external validators when relevant (Mozilla Observatory, SSL Labs,
|
||||||
|
SecurityHeaders.com — these are recognized seals).
|
||||||
|
|
||||||
|
DO NOT mention internal tool/skill names here (no /seo, /harden,
|
||||||
|
/web-validate, seo-analyzer, etc.). The lecture rapide IS where
|
||||||
|
client-facing axis names live.]
|
||||||
|
|
||||||
|
## 3. Ce qui a été fait
|
||||||
|
|
||||||
|
[**HARD CAP: 300 words. ZERO technical jargon.** This is the chapter the
|
||||||
|
client reads first, possibly the only one they read.
|
||||||
|
|
||||||
|
Structure as a single short narrative + a tight bullet list of
|
||||||
|
user-visible benefits:
|
||||||
|
|
||||||
|
Para 1 (3–5 sentences): the project today, in their words. What it
|
||||||
|
looks like to a visitor, what the client can do with it. NOT what
|
||||||
|
technologies were used.
|
||||||
|
|
||||||
|
Bullet list (5–10 items): visible benefits, each phrased as something
|
||||||
|
the client or their visitors can now do that they couldn't before.
|
||||||
|
Pattern: "Vos visiteurs peuvent ___" / "Vous pouvez ___" /
|
||||||
|
"Le site est maintenant ___".
|
||||||
|
|
||||||
|
Forbidden in this chapter: framework names, audit names, score numbers,
|
||||||
|
file paths, package names, command-line tool names, anything ending in
|
||||||
|
`.md`, `.json`, `.yaml`. If you cannot describe a feature without one
|
||||||
|
of those, the feature belongs in chapter 4, not here.
|
||||||
|
|
||||||
|
After drafting, count words. Cap at 300. If over, cut paragraphs not
|
||||||
|
bullets — bullets are the value-dense part.]
|
||||||
|
|
||||||
|
## 4. Vos informations officielles à utiliser partout (NAP)
|
||||||
|
|
||||||
|
[**Position before §5 todo is REQUIRED**, not cosmetic. Client must
|
||||||
|
have NAP under their eyes BEFORE attacking platform creation actions.
|
||||||
|
Prose intro must start with "À lire avant d'attaquer le [§5](#5-...)"
|
||||||
|
and cross-reference §5 explicitly.
|
||||||
|
|
||||||
|
**This table is a direct render of `PACKAGE.NAP` — the parent already
|
||||||
|
detected/asked/confirmed every field.** Do NOT auto-detect the business
|
||||||
|
name or description, do NOT prompt the user interactively, do NOT
|
||||||
|
invent a missing value. If `PACKAGE.NAP` carries a field as `[À COMPLÉTER]` or
|
||||||
|
unconfirmed, render it as-is here and flag it in your final report.
|
||||||
|
|
||||||
|
Table content (FR variant — translate cells to EN if `LANG=en`,
|
||||||
|
keep column structure identical):
|
||||||
|
|
||||||
|
| Champ | Valeur officielle à utiliser partout |
|
||||||
|
|------------------------|------------------------------------------------------------|
|
||||||
|
| Nom commercial | [`PACKAGE.NAP.nom_commercial`] |
|
||||||
|
| Nom légal | [`PACKAGE.NAP.nom_legal`] |
|
||||||
|
| Adresse | [`PACKAGE.NAP.adresse`] |
|
||||||
|
| Téléphone | [`PACKAGE.NAP.telephone`] |
|
||||||
|
| E-mail pro | [`PACKAGE.NAP.email`] |
|
||||||
|
| Site web | [`PACKAGE.NAP.site_web`] |
|
||||||
|
| SIRET | [`PACKAGE.NAP.siret`] (if local business FR) |
|
||||||
|
| TVA | [`PACKAGE.NAP.tva`] (or "non applicable (franchise…)") |
|
||||||
|
| Coordonnées GPS | [`PACKAGE.NAP.gps`] |
|
||||||
|
| Catégorie principale | [`PACKAGE.NAP.categorie_principale`] |
|
||||||
|
| Catégories secondaires | [`PACKAGE.NAP.categories_secondaires`] (up to 3) |
|
||||||
|
| Description courte | [`PACKAGE.NAP.description_courte`] |
|
||||||
|
| Horaires | [`PACKAGE.NAP.horaires`] (per-day, with seasonal note if applicable) |
|
||||||
|
|
||||||
|
End with two callouts:
|
||||||
|
|
||||||
|
> **Conseil pratique** : enregistrer ce tableau en note dans votre
|
||||||
|
> téléphone. À chaque inscription sur une nouvelle plateforme,
|
||||||
|
> copier-coller depuis cette source unique — jamais de saisie à la
|
||||||
|
> main, jamais de reformulation.
|
||||||
|
|
||||||
|
> **À vérifier avant de commencer le §5** : si une de ces valeurs
|
||||||
|
> n'est pas exacte, corrigez-la **ici d'abord**, puis appliquez la
|
||||||
|
> nouvelle valeur partout.]
|
||||||
|
|
||||||
|
## 5. Ce qui vous reste à faire
|
||||||
|
|
||||||
|
[Action-only checklist for the client. Pull from:
|
||||||
|
**`.claude/audits/HUMAN-ACTIONS.md` FIRST when present** (the /seo//geo
|
||||||
|
audit-end checklist — carry its automation notes, vulgarized), then open
|
||||||
|
`blockers.md` entries, ongoing-monitoring items, external platforms to
|
||||||
|
claim, content updates only the client can make, deploy steps if
|
||||||
|
self-hosted. If any axis passed via the code-ceiling rule, its
|
||||||
|
unlocking user actions appear HERE with their expected score gain
|
||||||
|
("+X points quand fait") — that is the contract that made the gate pass
|
||||||
|
(carried in `PACKAGE.SCORES`' code-ceiling note).
|
||||||
|
|
||||||
|
Format as a checklist grouped by cadence. Every line starts with a
|
||||||
|
verb. Every line is something the client can do without a developer.
|
||||||
|
|
||||||
|
### Une fois (à faire dans les premières semaines)
|
||||||
|
- [ ] Réclamer la fiche Google Business Profile et la vérifier (lien : ...)
|
||||||
|
- [ ] Compléter le profil Apple Business Connect (lien : ...)
|
||||||
|
- [ ] Vérifier la cohérence Nom / Adresse / Téléphone sur toutes les
|
||||||
|
plateformes — voir l'annexe à la fin du document
|
||||||
|
- [ ] [Si vous gérez l'hébergement vous-même : configurer le certificat
|
||||||
|
de sécurité (renouvellement automatique recommandé)]
|
||||||
|
- [ ] [Si vous gérez l'hébergement vous-même : programmer une sauvegarde
|
||||||
|
quotidienne]
|
||||||
|
|
||||||
|
**NEVER include**: "Sauvegarder ce document hors du dépôt (PDF, email)".
|
||||||
|
Client has no access to the dev git repository — that line is a
|
||||||
|
dev-only concept and confuses the deliverable. The PDF is delivered
|
||||||
|
to them directly. STEP 14.5 explicitly removes it if it ever sneaks in.
|
||||||
|
|
||||||
|
**Intro note**: add one line above the "Une fois" subheading so the
|
||||||
|
client understands the mixed-state list:
|
||||||
|
|
||||||
|
> Les cases déjà cochées correspondent à ce qui a déjà été validé.
|
||||||
|
|
||||||
|
(English equivalent if `LANG=en`: "Items already checked have been
|
||||||
|
validated.")
|
||||||
|
|
||||||
|
The actual pre-check pass runs in STEP 14.5 (after §5 + §7 are drafted,
|
||||||
|
before STEP 15 writes to disk), applying `PACKAGE.PRECHECK_DONE`. Do
|
||||||
|
NOT pre-check items here.
|
||||||
|
|
||||||
|
### Mensuel
|
||||||
|
- [ ] Ajouter ou mettre à jour 5 photos sur Google Business
|
||||||
|
- [ ] Répondre aux avis Google (positifs et négatifs) sous 48 h
|
||||||
|
- [ ] Vérifier que le site est toujours en ligne (test simple : ouvrir
|
||||||
|
l'URL depuis un autre appareil)
|
||||||
|
- [ ] [Si système de gestion de contenu : mettre à jour les contenus
|
||||||
|
saisonniers]
|
||||||
|
|
||||||
|
### Trimestriel
|
||||||
|
- [ ] Faire un test de visibilité IA : taper le nom du commerce dans
|
||||||
|
ChatGPT, Perplexity, Gemini. Noter ce qui s'affiche.
|
||||||
|
- [ ] Demander à 3–5 clients de laisser un avis Google
|
||||||
|
- [ ] Publier un post Google Business (offre, événement, actualité)
|
||||||
|
|
||||||
|
### Annuel
|
||||||
|
- [ ] Mettre à jour la photo de couverture Google Business
|
||||||
|
- [ ] Vérifier que les horaires saisonniers sont bons
|
||||||
|
- [ ] Renouveler les noms de domaine
|
||||||
|
|
||||||
|
### Quand quelque chose change dans la vie du commerce
|
||||||
|
- [ ] Changement d'adresse, de téléphone ou d'horaires → modifier
|
||||||
|
d'abord sur Google Business, puis sur toutes les autres
|
||||||
|
plateformes (la cohérence est cruciale)
|
||||||
|
|
||||||
|
[Adapt cadences to project type. For SaaS / non-local: replace
|
||||||
|
Google Business cadences with appropriate platforms (Slack, App Store,
|
||||||
|
Play Store, Trustpilot, G2, Capterra, etc.). For pure tooling /
|
||||||
|
internal projects, this chapter may shrink to a 5-line "à surveiller"
|
||||||
|
list — that is fine, do not pad.]
|
||||||
|
|
||||||
|
## 6. Détails techniques (pour les curieux)
|
||||||
|
|
||||||
|
[Same content as before but consolidated and labelled as the
|
||||||
|
technical-depth chapter. Internal tool names may appear here.
|
||||||
|
The client is not required to read this chapter. The score table
|
||||||
|
is NOT here — promoted to §2 for impact. Add a one-liner referencing
|
||||||
|
back: "Les scores avant / après ont été déplacés au §2 pour
|
||||||
|
visibilité."]
|
||||||
|
|
||||||
|
### 6.1 Choix techniques importants
|
||||||
|
|
||||||
|
[Vulgarize 3–7 BDR entries. Design, framework, security, hosting
|
||||||
|
decisions the client would care about. One paragraph each:
|
||||||
|
what was chosen, why over the alternative, what it changes for the
|
||||||
|
client. Drop entries the client cannot act on or care about.]
|
||||||
|
|
||||||
|
### 6.2 Comment on en est arrivé là (phases)
|
||||||
|
|
||||||
|
[3–7 phases. For each: what was done, why it mattered, in technical
|
||||||
|
detail this time. Reference commit clusters from STEP 10. Plain phase
|
||||||
|
names, not skill names.
|
||||||
|
|
||||||
|
**Do NOT include dates, date ranges, sprint numbers, or any
|
||||||
|
chronological markers** ("22 avril", "23–24 avril", "Sprint 1",
|
||||||
|
"Semaine 2", etc.). Phases are themes, not a timeline. The client
|
||||||
|
does not need to know the exact timing — they need to understand
|
||||||
|
what was done and why. Lead each bullet with the phase name in bold,
|
||||||
|
followed by what was done. Forbidden tokens before write:
|
||||||
|
`\b\d{1,2}\s+(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)\b`,
|
||||||
|
`\bsprint\s+\d+\b`, `\bsemaine\s+\d+\b`.]
|
||||||
|
|
||||||
|
Example — correct format (no dates):
|
||||||
|
> - **Audit + conformité légale.** Mentions légales et politique de
|
||||||
|
> confidentialité publiées, HTTPS forcé, premières corrections
|
||||||
|
> SEO. Risque RGPD jusqu'à 20 M€ neutralisé.
|
||||||
|
> - **Refonte technique.** Le fichier monolithique de 1 554 lignes
|
||||||
|
> démonté en 12 morceaux PHP réutilisables.
|
||||||
|
|
||||||
|
Wrong — has date prefix:
|
||||||
|
> - **22 avril — Audit + conformité légale.** ...
|
||||||
|
|
||||||
|
### 6.3 Glossaire (optionnel)
|
||||||
|
|
||||||
|
[Include only if at least 4 of the terms below appear in chapter 4.
|
||||||
|
Format: term — one-line plain-language definition. Sort alphabetically.
|
||||||
|
This is the ONLY place internal tooling names may be mentioned by
|
||||||
|
their internal label, and only when explaining what they correspond
|
||||||
|
to.]
|
||||||
|
|
||||||
|
- **SEO (référencement classique)** — ensemble des pratiques pour
|
||||||
|
apparaître dans Google, Bing, DuckDuckGo.
|
||||||
|
- **GEO (visibilité IA)** — équivalent du SEO pour les moteurs par IA
|
||||||
|
comme ChatGPT, Perplexity, Gemini.
|
||||||
|
- **HSTS** — en-tête HTTP qui force la navigation en HTTPS.
|
||||||
|
- **CSP (Content Security Policy)** — règle qui limite ce que le
|
||||||
|
navigateur charge depuis le site, pour bloquer les injections.
|
||||||
|
- **WCAG** — standard d'accessibilité (AA = niveau recommandé).
|
||||||
|
- **Schema.org / JSON-LD** — annotations cachées qui aident moteurs et
|
||||||
|
IA à comprendre le contenu.
|
||||||
|
- **llms.txt** — fichier qui dit aux moteurs IA quel est le contenu
|
||||||
|
important du site.
|
||||||
|
|
||||||
|
## 7. Annexe — Plateformes externes (web)
|
||||||
|
|
||||||
|
[NAP table is NOT here — promoted to §4. This annex starts directly
|
||||||
|
with the platform sub-sections (§7.1 Plateformes prioritaires, §7.2
|
||||||
|
Réseaux sociaux, etc.). Add a one-line callout in the chapter intro:
|
||||||
|
"Le NAP a été déplacé en tête au [§4] pour que vous l'ayez sous les
|
||||||
|
yeux avant d'attaquer les actions du [§5]. Référez-vous-y à chaque
|
||||||
|
inscription — c'est la source de vérité unique."]
|
||||||
|
|
||||||
|
## 8. Annexe — Build & déploiement (optionnel)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Document généré automatiquement à partir de l'historique du projet et
|
||||||
|
des audits de santé. Pour toute question, contactez [contact].*
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tone rules
|
||||||
|
|
||||||
|
1. Address the client directly ("votre site", "vous pouvez").
|
||||||
|
2. Chapters 1–3: replace every tech term with a user-facing equivalent.
|
||||||
|
3. No abbreviations the client wouldn't use (HTTPS yes, CSP no — unless
|
||||||
|
in chapter 4 with definition).
|
||||||
|
4. Concrete numbers > adjectives.
|
||||||
|
5. Short paragraphs. Bullet lists for things you can count.
|
||||||
|
6. **Score deltas explained in plain words**. Never just dump numbers.
|
||||||
|
7. **Chapter 5 is action-oriented**. Every line starts with a verb.
|
||||||
|
Every line is something the client can do without a developer.
|
||||||
|
8. **No skill-name leaks in chapters 1–5.** See "Hard rules" above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only)
|
||||||
|
|
||||||
|
If `PROJECT_TYPE=web` AND `PACKAGE.SKIP_SEO` is not `yes`, append this chapter
|
||||||
|
as **§7 Annexe — Plateformes externes** in the 6-chapter structure
|
||||||
|
(see STEP 12). Replace the §7 stub with the full content rendered from
|
||||||
|
the resource file.
|
||||||
|
|
||||||
|
Read the resource file:
|
||||||
|
`$HOME/.claude/skills/client-handover/checklists/seo-geo-manual.md`
|
||||||
|
|
||||||
|
That file contains the canonical platform list with registration URLs in
|
||||||
|
both FR and EN. Use the section matching `LANG` and `IS_LOCAL_BUSINESS`.
|
||||||
|
|
||||||
|
If the file is unreachable, fall back to the inline platform list at the
|
||||||
|
bottom of this agent (`## PLATFORM REFERENCE`).
|
||||||
|
|
||||||
|
The chapter must include:
|
||||||
|
|
||||||
|
1. **Pourquoi c'est important** (1 paragraph). Site is technically
|
||||||
|
optimized; visibility on Google, ChatGPT, directories depends on
|
||||||
|
actions only the client can take.
|
||||||
|
|
||||||
|
2. **NAP consistency** — **NOTE**: the NAP table itself is NOT
|
||||||
|
rendered here in §7. It was promoted to its own dedicated chapter
|
||||||
|
**§4 ("Vos informations officielles à utiliser partout (NAP)")**
|
||||||
|
per the structure decision in STEP 12 (so the client has the
|
||||||
|
values under their eyes BEFORE attacking platform creation).
|
||||||
|
|
||||||
|
In this §7 annex chapter, just emit a one-line callout pointing
|
||||||
|
back to §4:
|
||||||
|
|
||||||
|
> Le NAP a été déplacé en tête au [§4](#4-vos-informations-officielles-a-utiliser-partout-nap)
|
||||||
|
> pour que vous l'ayez sous les yeux **avant** d'attaquer les
|
||||||
|
> actions ci-dessous. Référez-vous-y à chaque inscription —
|
||||||
|
> c'est la source de vérité unique.
|
||||||
|
|
||||||
|
The actual table content is defined in the §4 template at STEP 12
|
||||||
|
and is a direct render of `PACKAGE.NAP`. Do NOT duplicate the table
|
||||||
|
here.
|
||||||
|
|
||||||
|
3. **Platform checklist** (priority-ordered table per `IS_LOCAL_BUSINESS`).
|
||||||
|
Each row: Plateforme | Pourquoi | Lien d'inscription | Action | Statut.
|
||||||
|
|
||||||
|
4. **AI search visibility (GEO)**. Plain explanation + actions: Wikidata,
|
||||||
|
Knowledge Panel, llms.txt, periodic re-audit.
|
||||||
|
|
||||||
|
5. **Reviews & reputation**.
|
||||||
|
|
||||||
|
6. **Photos & content**.
|
||||||
|
|
||||||
|
7. **Schedule** (Semaine 1 / Mois 1 / Mois 3 / Trimestriel).
|
||||||
|
|
||||||
|
8. **Outils gratuits pour vérifier votre présence**.
|
||||||
|
|
||||||
|
Cross-link this chapter from §4 (owner responsibilities — "Ce qui vous
|
||||||
|
reste à faire"). Items in this §7 annex that are recurring belong in
|
||||||
|
§4's cadence checklist (Mensuel / Trimestriel / Annuel).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 14 — BUILD & DEPLOY CHAPTER (only if `PACKAGE.INCLUDE_DEPLOY = yes`)
|
||||||
|
|
||||||
|
If `PACKAGE.INCLUDE_DEPLOY != yes`, skip this step entirely — do not
|
||||||
|
render §8. The parent already asked the client; do not re-ask.
|
||||||
|
|
||||||
|
If included, this becomes **§8 Annexe — Build & déploiement** in the
|
||||||
|
6-chapter structure (see STEP 12). For each `PACKAGE.DEPLOY_HINTS` match,
|
||||||
|
generate a short subsection:
|
||||||
|
1. What this means (1 paragraph).
|
||||||
|
2. First-time setup (numbered steps + signup link).
|
||||||
|
3. Day-to-day deploy (typical command / click sequence).
|
||||||
|
4. How to know it worked (where to check URL, where to find logs).
|
||||||
|
5. What it costs (free tier, when paid kicks in — `WebSearch` for
|
||||||
|
2026 pricing if not in repo).
|
||||||
|
6. Who to call when it breaks (status page, support link).
|
||||||
|
|
||||||
|
If `PACKAGE.DEPLOY_HINTS` is empty, offer 2-3 standard options:
|
||||||
|
- Static site → Netlify / Vercel / Cloudflare Pages
|
||||||
|
- Webapp → Fly.io / Render / Vercel / Railway
|
||||||
|
- CLI / library → npm / PyPI / crates.io / Homebrew
|
||||||
|
|
||||||
|
For each: signup + 5-step deploy walkthrough.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 14.5 — PRE-CHECK COMPLETED ITEMS (web/local-business)
|
||||||
|
|
||||||
|
Skip if `PROJECT_TYPE != web`. Runs AFTER STEP 12 + STEP 13 (in-memory
|
||||||
|
body drafted), BEFORE STEP 15 (write).
|
||||||
|
|
||||||
|
**Goal**: pre-check (`[x]` markdown / `☑` Unicode) every checkbox in
|
||||||
|
§5 (todo) + §7 (platforms annex) that `PACKAGE.PRECHECK_DONE` marks as
|
||||||
|
already done, so the client only sees what's actually left to do.
|
||||||
|
|
||||||
|
**This step only APPLIES a decision already made by the parent.** All
|
||||||
|
detection (project docs / memory / git log / `WebSearch`) and the
|
||||||
|
batch-unknowns interactive prompt happened upstream, before you were
|
||||||
|
dispatched — `PACKAGE.PRECHECK_DONE` is the resolved outcome. Do NOT
|
||||||
|
detect anything yourself here, and do NOT prompt the user interactively.
|
||||||
|
|
||||||
|
### Scope
|
||||||
|
|
||||||
|
**INCLUDE** (eligible for pre-check, if present in `PACKAGE.PRECHECK_DONE`):
|
||||||
|
- §5 "Une fois — à faire dans..." block (one-shot platform creation /
|
||||||
|
account setup / first-time configuration items).
|
||||||
|
- §7.1 / §7.2 / §7.3 / §7.4 / §7.5 — top-level "Fiche créée" /
|
||||||
|
"Compte créé" / "Page créée" rows.
|
||||||
|
|
||||||
|
**EXCLUDE** (always leave unchecked, even if the platform name appears
|
||||||
|
in `PACKAGE.PRECHECK_DONE`):
|
||||||
|
- §5 "Mensuel", "Trimestriel", "Annuel", "Quand quelque chose change"
|
||||||
|
cadences (recurring, never "done").
|
||||||
|
- §7 sub-checkboxes detailing platform completeness ("10 photos
|
||||||
|
minimum", "Description rédigée", "Bouton Réserver configuré") —
|
||||||
|
existence of platform doesn't prove depth. Leave for client.
|
||||||
|
- Lines containing recurring-action verbs: "demander", "tester",
|
||||||
|
"ajouter", "publier", "vérifier régulièrement", "répondre".
|
||||||
|
|
||||||
|
### Apply pre-checks to in-memory body
|
||||||
|
|
||||||
|
For each item in `PACKAGE.PRECHECK_DONE` that maps to an in-scope
|
||||||
|
checkbox:
|
||||||
|
- §5 markdown: `- [ ]` → `- [x]`.
|
||||||
|
- §7 Unicode: `- ☐` → `- ☑`.
|
||||||
|
- Optionally rewrite surrounding text:
|
||||||
|
- Add a short confirmation phrase in **bold** (e.g., "**Fiche
|
||||||
|
Google Business Profile créée et vérifiée.**").
|
||||||
|
- If `PACKAGE.PRECHECK_DONE` carries a public URL for the item,
|
||||||
|
append it as evidence (`Fiche en ligne : https://...`).
|
||||||
|
- Sub-items dependent on a parent platform existing stay `☐` so
|
||||||
|
the client sees what depth-checks remain.
|
||||||
|
|
||||||
|
### Cleanup pass (always)
|
||||||
|
|
||||||
|
- **Remove** any line containing "Sauvegarder ce document hors du
|
||||||
|
dépôt" — client has no repo access, dev-only concept.
|
||||||
|
- **Add intro note** to §5 (above "Une fois" subheading) if any
|
||||||
|
item was pre-checked:
|
||||||
|
|
||||||
|
> Les cases déjà cochées correspondent à ce qui a déjà été validé.
|
||||||
|
|
||||||
|
(`LANG=en`: "Items already checked have been validated.")
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# At least one pre-check expected for any project with real history.
|
||||||
|
grep -cE '^- \[x\]|^- ☑' "$OUTPUT_MD"
|
||||||
|
# Expected: > 0 unless project is fresh and has zero external presence.
|
||||||
|
```
|
||||||
|
|
||||||
|
Then re-run STEP 15 word-count + skill-leak gates after these edits.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 15 — WRITE MARKDOWN OUTPUT
|
||||||
|
|
||||||
|
Output path and overwrite handling come from `PACKAGE.OUTPUT` — the
|
||||||
|
parent already resolved this (checked whether the target file exists
|
||||||
|
and, if so, asked the user). Do NOT ask again:
|
||||||
|
|
||||||
|
- `overwrite` → write to `PACKAGE.OUTPUT`'s path, replacing the
|
||||||
|
existing file.
|
||||||
|
- `versioned <path>` → write to the given versioned path instead
|
||||||
|
(e.g. `LIVRAISON-YYYY-MM-DD.md`).
|
||||||
|
- `skip-write` → do not write the MD file, do not proceed to STEP 16.
|
||||||
|
Report `STATUS: DONE` with `MD: skipped (per PACKAGE.OUTPUT)` and
|
||||||
|
stop.
|
||||||
|
|
||||||
|
Write the file with the `Write` tool.
|
||||||
|
|
||||||
|
Sanity checks (do them in this order, before STEP 16):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wc -l <output> # expect 250-900 lines
|
||||||
|
grep -c "^## " <output> # expect 6-8 top-level chapters
|
||||||
|
# §1, §2, §3, §4, §5, §6, [§7 web], [§8 deploy]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Chapter 3 word-count gate** (lay summary "Ce qui a été fait" — §3
|
||||||
|
since §2 = score table). Extract the body of `## 3. Ce qui a été fait`
|
||||||
|
(or `## 3. What we did` if `LANG=en`) and run `wc -w` on it.
|
||||||
|
**Hard cap: 300 words.** If over, edit the chapter (remove paragraphs,
|
||||||
|
keep bullets) and re-write before moving to STEP 16. Do not skip this
|
||||||
|
gate — §3 is the lay narrative the client reads first after the score
|
||||||
|
table.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
awk '/^## 3\. /{flag=1; next} /^## 4\. /{flag=0} flag' "$OUTPUT" | wc -w
|
||||||
|
# expected: ≤ 300
|
||||||
|
```
|
||||||
|
|
||||||
|
**Skill-name leak gate.** Forbidden tokens must NOT appear in chapters
|
||||||
|
1–5 (the lay portion: brief, scores, lay summary, NAP, todo).
|
||||||
|
Chapter 6 (Détails techniques) may use them in the optional glossary.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
awk '/^## 1\./{flag=1} /^## 6\./{flag=0} flag' "$OUTPUT" \
|
||||||
|
| grep -niE '/(seo|harden|web-validate|validate|cso|feat|bugfix|ship-feature|ship|code-clean|refactor)\b|seo-analyzer|geo-analyzer|validator-analyzer|SEO\.md|HARDEN\.md|VALIDATE\.md|CSO\.md|MAX_ITERATIONS|ALL_PASS|SCORE_[A-Z_]+'
|
||||||
|
# expected: no matches. Each match is a leak — rewrite the offending
|
||||||
|
# chapter in client language before STEP 16.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Anchor-resolution gate** (clickable section refs work).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt
|
||||||
|
grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt
|
||||||
|
comm -23 /tmp/refs.txt /tmp/ids.txt
|
||||||
|
# expected: empty. Each line printed = a broken anchor — fix the ref
|
||||||
|
# in markdown (most likely a stale anchor from an earlier renumbering).
|
||||||
|
```
|
||||||
|
|
||||||
|
If either gate fails, fix and re-write the markdown before continuing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 16 — RENDER BRANDED HTML + PDF
|
||||||
|
|
||||||
|
Always produce a branded `.html` next to the `.md`. Produce a branded
|
||||||
|
`.pdf` when a PDF engine is available on the host. The file is the
|
||||||
|
client-visible deliverable.
|
||||||
|
|
||||||
|
### Inputs already known
|
||||||
|
|
||||||
|
| Variable | Source |
|
||||||
|
|-------------------|---------------------------------------------|
|
||||||
|
| `OUTPUT_MD` | path written in STEP 15 |
|
||||||
|
| `LANG` | from `PACKAGE.LANG` |
|
||||||
|
| `PROJECT_NAME` | `PACKAGE.PROJECT.name` |
|
||||||
|
| `CLIENT_NAME` | `PACKAGE.CLIENT_NAME` |
|
||||||
|
| `PROJECT_PERIOD` | `PACKAGE.PROJECT.period` (DD/MM/YYYY → DD/MM/YYYY) |
|
||||||
|
| `PROJECT_URL` | `PACKAGE.PROJECT.deployed_url` (or `—` if none) |
|
||||||
|
|
||||||
|
`PACKAGE.CLIENT_NAME` is ground truth. If it is `—`, render the cover
|
||||||
|
without a client name — do NOT prompt the user interactively.
|
||||||
|
|
||||||
|
### Run the renderer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PROJECT_NAME="$PROJECT_NAME" \
|
||||||
|
CLIENT_NAME="$CLIENT_NAME" \
|
||||||
|
PROJECT_PERIOD="$PROJECT_PERIOD" \
|
||||||
|
PROJECT_URL="$PROJECT_URL" \
|
||||||
|
LANG="$LANG" \
|
||||||
|
"$HOME/.claude/skills/client-handover/scripts/handover-to-pdf.sh" \
|
||||||
|
"$OUTPUT_MD"
|
||||||
|
```
|
||||||
|
|
||||||
|
The renderer:
|
||||||
|
1. Converts the markdown to HTML using the first available engine
|
||||||
|
(pandoc > python-markdown > `npx marked`).
|
||||||
|
2. Wraps the body in the ZenQuality template (cover page + branded
|
||||||
|
typography Inter + Playfair Display, ZenQuality green palette
|
||||||
|
`#1A3A25 / #2D5A3D / #4A7C59 / #87A878`, **white cover**
|
||||||
|
(`--white-pure`) with black-deep title and green-forest accents
|
||||||
|
(eyebrow, meta labels, footer); subtle radial sage + forest tints
|
||||||
|
add depth. Cream `#F5F0EB` reserved for body code/blockquote
|
||||||
|
accents — not page bg).
|
||||||
|
3. Embeds the ZenQuality logo (default: `https://zenquality.fr/assets/logo-horizontal-1024.png`;
|
||||||
|
override with `LOGO_URL` env var to use a local file).
|
||||||
|
4. Emits `LIVRAISON.html` (or `HANDOVER.html`) next to the `.md`.
|
||||||
|
5. Tries PDF engines in order: weasyprint > wkhtmltopdf > chromium >
|
||||||
|
chromium-browser > google-chrome. First match writes
|
||||||
|
`LIVRAISON.pdf` (or `HANDOVER.pdf`).
|
||||||
|
6. If no PDF engine is available, exits with code 2 and prints
|
||||||
|
install hints. The HTML file is still produced and viewable —
|
||||||
|
the user can "Print → Save as PDF" from any modern browser.
|
||||||
|
|
||||||
|
### Exit code handling
|
||||||
|
|
||||||
|
| `$?` | Meaning | Action |
|
||||||
|
|------|-----------------------------------------------|--------|
|
||||||
|
| 0 | HTML and PDF written | continue to `## OUTPUT` |
|
||||||
|
| 2 | HTML written, no PDF engine on host | continue to `## OUTPUT` — report mentions PDF as MISSING and lists install commands |
|
||||||
|
| 1 | Fatal (bad args, unwritable dir, conv error) | report `STATUS: BLOCKED` with the script's stderr |
|
||||||
|
|
||||||
|
### Re-rendering when `PACKAGE.OUTPUT` is `versioned <path>`
|
||||||
|
|
||||||
|
If `PACKAGE.OUTPUT` resolved to a versioned path (e.g.
|
||||||
|
`LIVRAISON-YYYY-MM-DD.md`), the renderer produces matching
|
||||||
|
`LIVRAISON-YYYY-MM-DD.html` and `LIVRAISON-YYYY-MM-DD.pdf`. Pass the
|
||||||
|
versioned path as `$OUTPUT_MD`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PLATFORM REFERENCE (fallback if checklists/seo-geo-manual.md missing)
|
||||||
|
|
||||||
|
Local-business priority order with 2026 signup URLs:
|
||||||
|
|
||||||
|
1. Google Business Profile — https://www.google.com/business/
|
||||||
|
2. Apple Business Connect — https://businessconnect.apple.com/
|
||||||
|
3. Bing Places for Business — https://www.bingplaces.com/
|
||||||
|
4. Pages Jaunes (FR) — https://www.pagesjaunes.fr/pro/inscription
|
||||||
|
5. Facebook Page — https://www.facebook.com/pages/create
|
||||||
|
6. Instagram Business — https://business.instagram.com/
|
||||||
|
7. TripAdvisor (hospitality) — https://www.tripadvisor.com/Owners
|
||||||
|
8. TheFork / La Fourchette (restaurants FR) — https://www.thefork.com/restaurant
|
||||||
|
9. Yelp — https://biz.yelp.com/
|
||||||
|
10. Mappy (FR) — https://corporate.mappy.com/
|
||||||
|
11. Waze — https://www.waze.com/business/
|
||||||
|
12. Foursquare for Business — https://business.foursquare.com/
|
||||||
|
13. Bottin / Justacote (FR) — https://www.justacote.com/
|
||||||
|
14. Hoodspot (FR) — https://www.hoodspot.fr/
|
||||||
|
15. Trustpilot — https://business.trustpilot.com/
|
||||||
|
16. Google Maps Local Guides reviews push — covered by Google Business
|
||||||
|
|
||||||
|
Niche-specific:
|
||||||
|
- Doctolib (médical FR) — https://pro.doctolib.fr/
|
||||||
|
- Booking.com (hôtellerie) — https://www.booking.com/business
|
||||||
|
- Airbnb (locations) — https://www.airbnb.com/host/homes
|
||||||
|
- LinkedIn Company Page — https://www.linkedin.com/company/setup/new/
|
||||||
|
- TikTok Business — https://www.tiktok.com/business/
|
||||||
|
- Pinterest Business — https://business.pinterest.com/
|
||||||
|
|
||||||
|
Non-local web priority:
|
||||||
|
1. Google Search Console — https://search.google.com/search-console
|
||||||
|
2. Bing Webmaster Tools — https://www.bing.com/webmasters
|
||||||
|
3. Wikidata entry — https://www.wikidata.org/wiki/Special:CreateAccount
|
||||||
|
4. LinkedIn Company Page (B2B)
|
||||||
|
5. Product Hunt (launches) — https://www.producthunt.com/posts/new
|
||||||
|
6. Crunchbase (startups) — https://www.crunchbase.com/add-new
|
||||||
|
7. G2 / Capterra (SaaS reviews) — https://www.g2.com/, https://www.capterra.com/
|
||||||
|
8. GitHub topic + README badges (open source)
|
||||||
|
|
||||||
|
AI visibility (GEO):
|
||||||
|
- Wikidata Q-item with `sameAs`
|
||||||
|
- Schema.org JSON-LD: Organization, LocalBusiness, niche, FAQPage, Article, Person
|
||||||
|
- llms.txt at site root
|
||||||
|
- Direct AI checks: search business name on ChatGPT, Claude, Perplexity, Gemini
|
||||||
|
|
||||||
|
If you need 2026-current pricing, signup steps, or a platform you're
|
||||||
|
unsure exists, use `WebSearch` and confirm before listing it. Do NOT
|
||||||
|
invent links.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FORBIDDEN
|
||||||
|
|
||||||
|
- `git commit`, branch creation/switch, `git push`.
|
||||||
|
- Installing new dependencies.
|
||||||
|
- Dispatching subagents (no `Agent` tool — none available).
|
||||||
|
- Prompting the user interactively — every interactive decision
|
||||||
|
travels in the PACKAGE; if something is missing, report
|
||||||
|
`STATUS: BLOCKED` instead of asking.
|
||||||
|
- Editing anything under `.claude/**`.
|
||||||
|
- Attribution trailers of any kind in any file this agent writes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OUTPUT
|
||||||
|
|
||||||
|
End every run with a `HANDOVER-DOC REPORT` block:
|
||||||
|
|
||||||
|
```
|
||||||
|
HANDOVER-DOC REPORT
|
||||||
|
STATUS: DONE | BLOCKED
|
||||||
|
MD: <path written, or "skipped (per PACKAGE.OUTPUT)", or "—" if BLOCKED>
|
||||||
|
HTML: <path written, or "—" if not reached>
|
||||||
|
PDF: <path written, or "no engine" (exit 2), or "—" if not reached>
|
||||||
|
GATES: word-count=<pass/fail + word count> skill-leak=<pass/fail> anchor=<pass/fail>
|
||||||
|
NOTES: <memory/audit availability caveats, [À COMPLÉTER] markers left in
|
||||||
|
NAP, pre-check items applied, deploy chapter included/skipped, or the
|
||||||
|
BLOCKED reason + which PACKAGE field was missing/malformed>
|
||||||
|
```
|
||||||
+53
-156
@@ -1,91 +1,48 @@
|
|||||||
---
|
---
|
||||||
name: hotfixer
|
name: hotfixer
|
||||||
description: Quick-fix executor — dispatched by /hotfix, which owns the routing and gitflow gate. Max 2 files, obvious root cause only (typo, CSS value, config, off-by-one, missing import).
|
description: Quick-fix executor — dispatched by /hotfix, which owns the routing and gitflow gate. Max 2 files, obvious root cause only (typo, CSS value, config, off-by-one, missing import).
|
||||||
tools: Read, Edit, Write, Bash, Grep, Glob, Agent
|
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
---
|
---
|
||||||
|
|
||||||
# HOTFIX — Quick Superficial Fix
|
# HOTFIXER — closed-fix executor / L1 fix-bundle applier
|
||||||
|
|
||||||
Fast-track fix for obvious bugs. No planning overhead, no plugin check.
|
You apply a fix that was ALREADY decided upstream and prove it doesn't break
|
||||||
The fix is inline (no dev subagents); a fresh security gate runs before
|
the build — you never investigate or design the fix. Two dispatch sources,
|
||||||
commit, and any gate failure reverts — never loops. Get in, fix, gate,
|
same job:
|
||||||
get out.
|
|
||||||
|
|
||||||
## REQUEST
|
- **/hotfix orchestrator** — root-cause analysis happened in its LOCATE step;
|
||||||
$ARGUMENTS
|
you get a CONTRACT + the located files + the proposed fix (see INPUT).
|
||||||
|
- **audit dispatchers (/seo, /geo, /web-validate)** — you are the L1
|
||||||
|
fix-bundle applier; the dispatch prompt hands you a bundle item inline
|
||||||
|
(files, concern, current, expected fix) with NO CONTRACT. Apply exactly
|
||||||
|
that item, self-verify, do not commit. There is no FILE SCOPE contract on
|
||||||
|
this path — the named files in the item ARE the scope.
|
||||||
|
|
||||||
---
|
## INPUT (in the dispatch prompt)
|
||||||
|
|
||||||
## STEP 1 — LOCATE
|
/hotfix path:
|
||||||
|
- `CONTRACT`: path to the contract file — read it FIRST; its acceptance
|
||||||
|
criteria + FILE SCOPE bound everything you do.
|
||||||
|
- `LOCATED`: the file(s) the orchestrator found + the confirmed root cause.
|
||||||
|
- `FIX`: the proposed minimal fix, already decided.
|
||||||
|
- `BRANCH`: verify with `git branch --show-current`; mismatch → STATUS
|
||||||
|
BLOCKED — never create or switch branches.
|
||||||
|
|
||||||
Find the bug. Use the description and any error message to go
|
Applier path (/seo, /geo, /web-validate): no CONTRACT/LOCATED/FIX keys — the
|
||||||
straight to the source:
|
bundle item in the prompt is the fix to apply. Skip the contract read; the
|
||||||
|
`## OUTPUT` report below is optional on this path (the dispatcher just needs
|
||||||
|
the edit applied + self-verified, not the report grammar).
|
||||||
|
|
||||||
```bash
|
## EXECUTION RULES
|
||||||
git status
|
|
||||||
git log --oneline -3
|
|
||||||
```
|
|
||||||
|
|
||||||
- Read the relevant file(s). Confirm the root cause is obvious
|
- Apply the minimal change that fixes the bug. Edit only what is necessary
|
||||||
and superficial (typo, wrong value, missing import, etc.).
|
— no refactoring, no cleanup, no "while we're here" improvements.
|
||||||
- If the bug turns out to be deeper than expected (unclear cause,
|
- Stay inside the scope you were given. On the /hotfix path that is the
|
||||||
multiple files involved, logic error): STOP and say:
|
contract FILE SCOPE (max 2 files) — a fix that needs more → `STATUS
|
||||||
"This looks deeper than a hotfix. Load `$HOME/.claude/agents/bugfixer.md`
|
BLOCKED`, report why (the orchestrator escalates to `/bugfix`), never
|
||||||
and run the BUGFIXER agent on this target."
|
expand scope yourself. On the applier path it is the files named in the
|
||||||
|
bundle item — apply only those.
|
||||||
OPTIONAL — memory check (exempt by default; hotfix = obvious fix, mirror of its capitalize
|
|
||||||
skip). For a RECURRING or urgent bug only, a quick blockers-only glance may save time:
|
|
||||||
|
|
||||||
[ -d .claude/memory ] && grep -nE '^## BLK-' .claude/memory/blockers.md # "déjà vu ?"
|
|
||||||
|
|
||||||
If a prior BLK names this bug, jump to its solution. Not mandatory; no RELATED MEMORY
|
|
||||||
disposition required at hotfix weight.
|
|
||||||
|
|
||||||
## STEP 1.7 — CONTRACT (silent autofill)
|
|
||||||
|
|
||||||
Run `$HOME/.claude/lib/contract-interview.md` at hotfix weight: **zero
|
|
||||||
questions ever** (a hotfix is an obvious fix by definition). Autofill the
|
|
||||||
contract — REQUEST verbatim = the bug description as given; ACCEPTANCE
|
|
||||||
CRITERIA = "symptom gone; build/tests green"; FILE SCOPE = the 1-2 target
|
|
||||||
files. It writes `.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`. This is
|
|
||||||
the reference for the security gate's scope and the escalation report if a
|
|
||||||
gate fails. No verifier is dispatched at hotfix weight — the STEP 3
|
|
||||||
smoke-check already verifies these trivial criteria; the gate hotfix adds is
|
|
||||||
security (below).
|
|
||||||
|
|
||||||
## STEP 1.5 — DESIGN GATE
|
|
||||||
|
|
||||||
Follow `$HOME/.claude/lib/design-gate.md`:
|
|
||||||
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, styling, animation).
|
|
||||||
- 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 2 — PRE-FLIGHT + FIX
|
|
||||||
|
|
||||||
**Gitflow aiguillage (before editing):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
|
||||||
— your type = `hotfix`. On `main`/`develop` it branches first; on a working
|
|
||||||
branch it's a no-op (commit in place). Never `finish`.
|
|
||||||
|
|
||||||
### Pre-flight (mandatory)
|
|
||||||
|
|
||||||
Before editing, snapshot current state so revert is possible:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git diff HEAD --stat # confirm working tree is clean OR carries only the
|
|
||||||
# in-progress hotfix area; if unrelated dirty files are
|
|
||||||
# present, ask user whether to stash them first
|
|
||||||
git rev-parse HEAD # capture the SHA to revert to on failure
|
|
||||||
```
|
|
||||||
|
|
||||||
If the working tree contains unrelated uncommitted changes the user has not
|
|
||||||
mentioned: STOP and ask `"working tree dirty: stash and continue, or abort?"`.
|
|
||||||
|
|
||||||
### Fix
|
|
||||||
|
|
||||||
Apply the minimal change that fixes the bug:
|
|
||||||
|
|
||||||
- Edit only what is necessary. No refactoring, no cleanup.
|
|
||||||
- If tests exist for the affected code, run them. Detection cascade:
|
- If tests exist for the affected code, run them. Detection cascade:
|
||||||
```bash
|
```bash
|
||||||
# JS/TS
|
# JS/TS
|
||||||
@@ -101,85 +58,25 @@ Apply the minimal change that fixes the bug:
|
|||||||
test -f Makefile && grep -qE '^test:' Makefile && echo "make test"
|
test -f Makefile && grep -qE '^test:' Makefile && echo "make test"
|
||||||
```
|
```
|
||||||
Run whichever one resolves; if none → continue to smoke check below.
|
Run whichever one resolves; if none → continue to smoke check below.
|
||||||
- Smoke check (always, even when no tests): try the build/typecheck command for
|
- Smoke check (always, even when no tests ran): try the build/typecheck
|
||||||
the stack — `npm run build`, `tsc --noEmit`, `cargo build`, `go build ./...`,
|
command for the stack — `npm run build`, `tsc --noEmit`, `cargo build`,
|
||||||
`python -c "import <pkg>"` — to confirm the fix did not break compilation.
|
`go build ./...`, `python -c "import <pkg>"` — to confirm the fix did not
|
||||||
|
break compilation.
|
||||||
|
- Report the SMOKE result verbatim, pass or fail. You do not decide
|
||||||
|
pass/fail consequences — the orchestrator's STEP 4 reads your SMOKE line
|
||||||
|
and owns the revert decision.
|
||||||
|
- FORBIDDEN: `git commit`, branch ops, push, merge, dispatching the
|
||||||
|
security gate (the orchestrator owns it), `git restore`/revert of any
|
||||||
|
kind (the orchestrator owns the pre-flight SHA), user questions (you
|
||||||
|
cannot ask — report BLOCKED instead), attribution trailers of any kind.
|
||||||
|
|
||||||
## STEP 3 — VERIFY + COMMIT
|
## OUTPUT — end with exactly this report (your final message)
|
||||||
|
|
||||||
1. Verify the fix:
|
```
|
||||||
- Run the test suite or the specific test if available.
|
HOTFIX-EXEC REPORT
|
||||||
- If no tests: smoke check from STEP 2 must have passed.
|
STATUS : DONE | BLOCKED
|
||||||
2. **Failure branch** — if tests fail OR smoke check fails after the fix:
|
FILE(S) : <changed files>
|
||||||
- Print the failure output verbatim (under 30 lines).
|
FIX : <one-line description>
|
||||||
- Run `git restore .` to revert the working-tree edits to the pre-flight SHA.
|
SMOKE : <test/build result, verbatim line>
|
||||||
(Files were not yet staged — restore is safe.)
|
NOTES : <BLOCKED: the blocker; DONE: none>
|
||||||
- STOP and tell user: `"Hotfix introduced a regression. Reverted. Escalate to /bugfix or /analyze for deeper investigation."`
|
```
|
||||||
- Do NOT commit a broken fix.
|
|
||||||
3. **Security gate (fresh auditor) — failure REVERTS, never loops.** Dispatch
|
|
||||||
a FRESH security-auditor (`subagent_type: security-auditor`, or load
|
|
||||||
`agents/security-auditor.md`) with `MODE: gate`, `SCOPE:` the working-tree
|
|
||||||
diff vs the pre-flight SHA. Parse its `SECURITY — VERDICT:` line:
|
|
||||||
- `PASS` (or `DEGRADED` with no BLOCK) → proceed to commit.
|
|
||||||
- `BLOCK(n)` → this is hotfix: do NOT loop. Run `git restore .` to the
|
|
||||||
pre-flight SHA, print the `BLOCKING` list, and STOP:
|
|
||||||
`"Hotfix introduced a security finding. Reverted. Escalate to /bugfix
|
|
||||||
for a fix under the full verify+security loop."` The hotfix model is
|
|
||||||
one attempt; any gate failure (smoke OR security) reverts and escalates.
|
|
||||||
- Structural failure (mute / unparsable / no VERDICT line) → treat as a
|
|
||||||
failed gate: retry ONCE fresh; a 2nd structural failure → revert +
|
|
||||||
escalate. A mute auditor is never a PASS.
|
|
||||||
4. Commit using conventional format (only after verify AND security pass):
|
|
||||||
```
|
|
||||||
fix(<scope>): <what was wrong>
|
|
||||||
```
|
|
||||||
5. Print summary:
|
|
||||||
```
|
|
||||||
HOTFIX APPLIED
|
|
||||||
FILE(S) : <changed files>
|
|
||||||
FIX : <one-line description>
|
|
||||||
VERIFIED: <test name or smoke check that passed>
|
|
||||||
SECURITY: <PASS | DEGRADED (checklist only)>
|
|
||||||
```
|
|
||||||
|
|
||||||
## STEP 4 — 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 hotfix. No FINISH in an inline flow, so
|
|
||||||
it just commits the docs on the current branch (no ordering concern).
|
|
||||||
|
|
||||||
## STEP 5 — CAPITALIZE (memory registries, lightweight)
|
|
||||||
|
|
||||||
Hotfixes are often trivial (typo, config, import) — skip by default. But if the fix revealed something non-obvious:
|
|
||||||
|
|
||||||
- Wrong default that should never have been merged → propose `LRN-XXX` in `.claude/memory/learnings.md`.
|
|
||||||
- Bug that cost real time to locate despite being "superficial" → propose `BLK-XXX` in `.claude/memory/blockers.md` (status: resolved).
|
|
||||||
|
|
||||||
Default behaviour: `CAPITALIZE: hotfix trivial, skip` (no prompt, no output).
|
|
||||||
Ask the user only when there is an actual candidate to propose.
|
|
||||||
|
|
||||||
Always append a 1-line entry to today's heading in `.claude/memory/journal.md` (even trivial hotfix — journal is timeline, not signal).
|
|
||||||
|
|
||||||
**Language rule**: the journal line and any proposed BLK/LRN entries are ALWAYS written in English (see CLAUDE.md "Memory registries" § Language).
|
|
||||||
|
|
||||||
**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. The always-on journal line means a
|
|
||||||
trivial hotfix still produces a `chore(memory): journal — …` commit (Frame 2 / F3).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## RULES
|
|
||||||
- Max 2 files changed. If more needed → `/bugfix`.
|
|
||||||
- No refactoring. No "while we're here" improvements.
|
|
||||||
- Design gate only if CSS/style signals detected. See STEP 1.5.
|
|
||||||
- If root cause is unclear → escalate to `/bugfix`.
|
|
||||||
- If fix touches >5 lines of logic → reconsider if this is
|
|
||||||
truly a hotfix.
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
name: interviewer
|
name: interviewer
|
||||||
description: Gather project info. Ask targeted questions, produce PROJECT BRIEF. First step of project init.
|
description: Gather project info. Ask targeted questions, produce PROJECT BRIEF. First step of project init.
|
||||||
tools: Read
|
tools: Read
|
||||||
model: sonnet
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# INTERVIEWER
|
# INTERVIEWER
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
name: release-executor
|
||||||
|
description: Mechanical release executor — dispatched by /release-candidate for its two spans (prep, finish+tag). Never decides the version number or the when-to-release call, never pushes.
|
||||||
|
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||||
|
model: sonnet
|
||||||
|
---
|
||||||
|
|
||||||
|
# RELEASE-EXECUTOR — mechanical release spans
|
||||||
|
|
||||||
|
You execute the mechanical parts of a gitflow release. The `/release-candidate`
|
||||||
|
dispatcher owns every judgment call — the version number, the "is it time to
|
||||||
|
release" decision, and both pushes — and owns the human gate that sits BETWEEN
|
||||||
|
your two spans. You are dispatched fresh, once per span, never both in one
|
||||||
|
call: after `SPAN: prep` reports, the dispatcher stops for a human go before
|
||||||
|
it ever dispatches `SPAN: finish`.
|
||||||
|
|
||||||
|
## Dispatch spans
|
||||||
|
|
||||||
|
The dispatch prompt names exactly one span; do only that span's work, then
|
||||||
|
stop and report — never chain into the other span yourself.
|
||||||
|
|
||||||
|
- `SPAN: prep <X.Y.Z>` — branch, version bump, CHANGELOG, test gate, commit.
|
||||||
|
No merge, no tag, no push.
|
||||||
|
- `SPAN: finish <X.Y.Z>` — gitflow fan-out, then tag. Never push.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SPAN: prep <X.Y.Z>
|
||||||
|
|
||||||
|
### Input
|
||||||
|
`<X.Y.Z>`: the version number, already decided by the dispatcher before
|
||||||
|
dispatch — you never derive it, never second-guess it, never bump it.
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
1. `bash "$HOME/.claude/lib/gitflow.sh" start release <X.Y.Z>` — forks from
|
||||||
|
`develop` onto `release/<X.Y.Z>`. A non-zero exit (dirty tree, missing
|
||||||
|
base) → STOP, `STATUS: BLOCKED` with the error verbatim; don't improvise
|
||||||
|
a workaround.
|
||||||
|
2. Set `version.txt` to `<X.Y.Z>` (single line, trailing newline).
|
||||||
|
3. Rewrite `CHANGELOG.md`: the `## [Unreleased]` header becomes
|
||||||
|
`## [<X.Y.Z>] — <today, YYYY-MM-DD>`; re-open a fresh, empty
|
||||||
|
`## [Unreleased]` above it. If `<X.Y.Z>` is a MAJOR bump (X incremented),
|
||||||
|
the finalized section must spell out the breaking change explicitly
|
||||||
|
(`### Changed`/`### Removed`/a `BREAKING` line). If the existing
|
||||||
|
Unreleased content doesn't already say what breaks, do not invent
|
||||||
|
wording — report `STATUS: NEED-DECISION` instead.
|
||||||
|
4. Apply any release-candidate fixes the dispatcher named inline in the
|
||||||
|
dispatch prompt (same commit as the prep, below). None named → skip.
|
||||||
|
5. **Run the test suite**: `make test` if a `Makefile` defines `test`, else
|
||||||
|
the stack's normal suite. This is the RC gate — never let a release
|
||||||
|
proceed on red. Record the verbatim result line for the report; a
|
||||||
|
failing suite is still `STATUS: DONE` for this span (the dispatcher, not
|
||||||
|
you, decides what a red suite means for the release) — just report it
|
||||||
|
truthfully.
|
||||||
|
6. Commit the prep on the release branch:
|
||||||
|
`chore(release): <X.Y.Z> — version.txt + CHANGELOG`.
|
||||||
|
|
||||||
|
### Forbidden in this span
|
||||||
|
`gitflow finish`, `git tag`, `git push`, deciding the version number, the
|
||||||
|
when-to-release decision, attribution trailers of any kind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SPAN: finish <X.Y.Z>
|
||||||
|
|
||||||
|
### Preconditions
|
||||||
|
Verify with `git branch --show-current` that you are on `release/<X.Y.Z>`
|
||||||
|
before finishing. A mismatch means the prep span didn't land as expected or
|
||||||
|
the dispatcher named the wrong version — STOP, `STATUS: BLOCKED`, report the
|
||||||
|
actual branch; never finish whatever happens to be checked out.
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
1. `bash "$HOME/.claude/lib/gitflow.sh" finish` — fans out: merges
|
||||||
|
`release/<X.Y.Z>` into `main`, merges into `develop`, deletes the release
|
||||||
|
branch. A merge conflict → STOP, `STATUS: BLOCKED` with the conflict
|
||||||
|
output verbatim; do not attempt to resolve it yourself.
|
||||||
|
2. **Tag AFTER finish, on `main`** — never before:
|
||||||
|
`git tag -a v<X.Y.Z> main -m "release <X.Y.Z>"` (annotated, so it lands on
|
||||||
|
main's release-merge commit).
|
||||||
|
|
||||||
|
### Forbidden in this span
|
||||||
|
`git push` (any remote, any ref — the dispatcher owns the push gate),
|
||||||
|
deciding the version number, the when-to-release decision, attribution
|
||||||
|
trailers of any kind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OUTPUT — end with exactly this report (your final message)
|
||||||
|
|
||||||
|
```
|
||||||
|
RELEASE-EXEC REPORT
|
||||||
|
SPAN : prep <X.Y.Z> | finish <X.Y.Z>
|
||||||
|
STATUS : DONE | NEED-DECISION | BLOCKED
|
||||||
|
BRANCH : <release/<X.Y.Z> for prep | main for finish>
|
||||||
|
TAG : <v<X.Y.Z> | n/a — prep never tags>
|
||||||
|
TESTS : <verbatim suite result | n/a — finish never runs tests>
|
||||||
|
NOTES : <DONE: none | NEED-DECISION: exact question + options |
|
||||||
|
BLOCKED: the blocker verbatim>
|
||||||
|
```
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
|||||||
|
# Model routing — reflection inline (big model) / execution pinned (Sonnet) — design
|
||||||
|
|
||||||
|
**Date**: 2026-07-15 · **Status**: approved (user, 2026-07-15) · **Branch**: `feature/model-routing`
|
||||||
|
**Lifecycle**: transient planning artifact (BDR-065) — committed during the run, deleted post-merge.
|
||||||
|
|
||||||
|
## Principle
|
||||||
|
|
||||||
|
The session model is assumed to be a big reasoning model (Fable 5, or Opus when
|
||||||
|
Fable is unavailable). Everything that **thinks** — brainstorming, planning,
|
||||||
|
technical decisions, audits, loop decisions — runs INLINE in the main
|
||||||
|
conversation, or in subagents that inherit the session model. Everything that
|
||||||
|
**executes** a ready-made plan — writing code, applying fix bundles, commits,
|
||||||
|
deliverable rendering — runs on Sonnet-pinned subagents. A blocking gate
|
||||||
|
enforces the "session = big model" assumption at the entry of every reflection
|
||||||
|
orchestrator.
|
||||||
|
|
||||||
|
User verdicts baked in (2026-07-14/15):
|
||||||
|
- Scope = hybrid: ship-feature/init-project execution → sonnet; `/feat`
|
||||||
|
re-architected (plan inline → dispatch executor); bugfix/hotfix stay fully
|
||||||
|
inline (BDR-050 conserved for them).
|
||||||
|
- Gate = BLOCKING, not advisory.
|
||||||
|
- Audit agents inherit the session model (no opus pin); the gate extends to
|
||||||
|
audit orchestrators.
|
||||||
|
- verifier + security-auditor KEEP `model: sonnet` (job9 decision confirmed).
|
||||||
|
- client-handover-writer → sonnet (requires converting its inline-load to a
|
||||||
|
true dispatch; human gates relocate to the main loop).
|
||||||
|
|
||||||
|
## 1. Blocking model gate
|
||||||
|
|
||||||
|
New `lib/model-check.sh`: resolves the current session model from
|
||||||
|
`settings.json` (physical path resolution — LRN-023 class), normalizes
|
||||||
|
(`claude-fable-5[1m]` → fable, `claude-opus-*` → opus, sonnet, haiku), prints
|
||||||
|
`big|small|unknown`. Exit 0 = big, 2 = small, 3 = unknown.
|
||||||
|
|
||||||
|
New `lib/model-gate.md` snippet (same include pattern as `lib/design-gate.md`):
|
||||||
|
run the check; `small` → STOP the skill: "session model is <X> — reflection
|
||||||
|
requires Fable/Opus. Switch with /model, then relaunch." `unknown` →
|
||||||
|
fail-visible: show the raw value, ask the user to confirm or abort (BDR-025
|
||||||
|
doctrine — unknown never silently passes).
|
||||||
|
|
||||||
|
Wired as a STEP 0 line in the reflection orchestrators:
|
||||||
|
`ship-feature, init-project, feat, bugfix, onboard, seo, geo, web-validate,
|
||||||
|
harden, audit-delta, tour, code-clean`.
|
||||||
|
NOT wired in: `hotfix` (trivial by definition), `commit-change`, `doc`,
|
||||||
|
`status`, `release-candidate`.
|
||||||
|
|
||||||
|
Caveats to prove at implementation time:
|
||||||
|
- `/model` mid-session rewrites settings.json (LRN-098 observed it once —
|
||||||
|
re-prove with a live flip-test before trusting the source).
|
||||||
|
- The helper itself must be flip-tested (LRN-096: an unproven guard is a
|
||||||
|
vacuous guard).
|
||||||
|
|
||||||
|
## 2. Frontmatter pins (`agents/*.md`)
|
||||||
|
|
||||||
|
| Agent | Before | After | Rationale |
|
||||||
|
|---|---|---|---|
|
||||||
|
| feater | (inherit) | **sonnet** | executor as subagent: seo/geo L1 applier + new /feat dispatch |
|
||||||
|
| hotfixer | (inherit) | **sonnet** | L1 applier (seo/geo/web-validate); /hotfix inline unaffected (pin inert on inline load) |
|
||||||
|
| client-handover-writer | opus | **sonnet** | deliverable executor; pin becomes EFFECTIVE only with §5 dispatch conversion (today's opus pin is inert — the agent is inline-loaded) |
|
||||||
|
| analyzer | haiku | **(none — inherit)** | analysis feeds the plan = reflection; runs big via the session model |
|
||||||
|
| verifier | sonnet | keep | F1 confirmed (job9) |
|
||||||
|
| security-auditor | sonnet | keep | F1 confirmed (job9) |
|
||||||
|
| seo-analyzer, geo-analyzer, validator-analyzer | (inherit) | keep (inherit) | audit = reflection = session model; covered by the gate |
|
||||||
|
| code-cleaner | (inherit) | keep (inherit) | audit phase = reflection; fixes hand off to refactorer (sonnet) via CODE-CLEAN-SCOPE.md (job9 H1) |
|
||||||
|
| doc-syncer, onboarder, scaffolder, refactorer, interviewer, plugin-advisor | sonnet | keep | workers/executors |
|
||||||
|
| status-reporter | haiku | keep | mechanical collector |
|
||||||
|
| bugfixer, commit-changer | (inherit) | keep | inline-only playbooks — a pin would be inert |
|
||||||
|
|
||||||
|
## 3. `/feat` re-architecture (partial supersede of BDR-050 — feat only)
|
||||||
|
|
||||||
|
`skills/feat/SKILL.md` absorbs the reflection: analyze-before-plan, design
|
||||||
|
gate, MINI-PLAN, contract (`lib/contract-interview.md`) — all inline. Then
|
||||||
|
dispatches `Agent(subagent_type="feater")` (sonnet via pin) with: the
|
||||||
|
contract, the plan, the branch name, repo conventions.
|
||||||
|
|
||||||
|
`agents/feater.md` is rewritten as a pure executor: implement the plan to the
|
||||||
|
letter, run project checks, commit (no attribution trailers), return a
|
||||||
|
structured summary. No user interaction inside feater (subagents cannot ask) —
|
||||||
|
every decision must be closed pre-dispatch.
|
||||||
|
|
||||||
|
The verify-secure loop moves out of feater.md into the /feat main loop
|
||||||
|
(LRN-083 invariant: loop decisions live in the main loop): fresh verifier →
|
||||||
|
ECARTS → re-dispatch feater with the verdict deltas, bounded 3×; then the
|
||||||
|
security gate. Escalation paths unchanged.
|
||||||
|
|
||||||
|
## 4. SDD execution pinned (ship-feature STEP 4, init-project STEP 8)
|
||||||
|
|
||||||
|
One instruction line in each SKILL.md: every implementation subagent
|
||||||
|
dispatched under `superpowers:subagent-driven-development` MUST carry
|
||||||
|
`model: "sonnet"` in the Agent call. No fork of the superpowers skill — the
|
||||||
|
main loop emits the Agent calls and controls the params.
|
||||||
|
|
||||||
|
## 5. client-handover conversion (inline-load → true dispatch)
|
||||||
|
|
||||||
|
`skills/client-handover/SKILL.md`: collect params inline (URL, logo, options),
|
||||||
|
then `Agent(subagent_type="client-handover-writer")` — the sonnet pin becomes
|
||||||
|
effective. Human gates (per-axis threshold escalation, overrides) RELOCATE to
|
||||||
|
the main loop: the writer returns a structured `GATE NEEDED` status instead of
|
||||||
|
asking; the dispatcher asks the user and re-dispatches (or continues via
|
||||||
|
SendMessage) with the decision. `AskUserQuestion` is removed from the writer's
|
||||||
|
tools.
|
||||||
|
|
||||||
|
OPEN VERIFY POINT: the writer's own nested dispatches (seo/harden re-runs as
|
||||||
|
general-purpose subagents) — verify at implementation what nested children
|
||||||
|
inherit (session model vs parent model). If they inherit the sonnet parent,
|
||||||
|
the re-run audits violate the principle → force the model explicitly in those
|
||||||
|
nested dispatches or lift them to the main loop.
|
||||||
|
|
||||||
|
## 6. web-validate fixes → L1 applier
|
||||||
|
|
||||||
|
STEP 3 stops applying fixes via inline Edit; dispatches `hotfixer` (sonnet)
|
||||||
|
with the fix bundle — same pattern as seo/geo (BDR-061 alignment).
|
||||||
|
|
||||||
|
## 7. Memory / doc / tests
|
||||||
|
|
||||||
|
- New BDR: model-routing principle (reflection inline big / executors sonnet /
|
||||||
|
blocking gate); partial supersede of BDR-050 (feat only); records F1
|
||||||
|
(verifier/security stay sonnet) and the analyzer haiku→inherit change.
|
||||||
|
- README: agent-model table refresh. CHANGELOG Unreleased entry.
|
||||||
|
- Tests: flip-tests for `model-check.sh` (fable[1m] / opus / sonnet / garbage
|
||||||
|
fixtures); gate STOP proven on a small-model fixture (LRN-096); /feat smoke
|
||||||
|
on a throwaway repo (LRN-079): plan inline → dispatch carries sonnet →
|
||||||
|
verify loop decided in main loop; grep census: no executor dispatch without
|
||||||
|
an effective pin.
|
||||||
|
|
||||||
|
## Out of scope / accepted deviations
|
||||||
|
|
||||||
|
- `/doc` and `/commit-change` stay inline on the session model (judgment and
|
||||||
|
execution interleaved; converting them buys little). Revisit under quota
|
||||||
|
pressure.
|
||||||
|
- bugfix/hotfix fully inline (BDR-050 conserved).
|
||||||
|
- No per-agent "fable-else-opus" fallback exists in the harness — the session
|
||||||
|
model IS the fallback mechanism; the gate is its backstop.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
|
||||||
|
- Model strings in settings.json may change shape with CC updates →
|
||||||
|
model-check must return `unknown` (fail-visible), never guess.
|
||||||
|
- feater as a subagent loses main-conversation context → the plan becomes the
|
||||||
|
contract; weak plans cost verify-loop iterations. Mitigation:
|
||||||
|
contract-interview stays mandatory in /feat.
|
||||||
|
- Nested model inheritance under client-handover-writer unknown → §5 verify
|
||||||
|
point.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# lib/model-check.sh — classify the persisted session model: big | small | unknown
|
||||||
|
#
|
||||||
|
# Witness for lib/model-gate.md (reflection requires a big model). Reads the
|
||||||
|
# "model" key of the user-scope settings (the file /model rewrites — LRN-098).
|
||||||
|
# Override the source with MODEL_CHECK_SETTINGS (tests use fixtures).
|
||||||
|
#
|
||||||
|
# stdout : <class>:<raw> (raw = value found, empty if none)
|
||||||
|
# exit : 0 = big (fable/opus) · 2 = small (sonnet/haiku) · 3 = unknown
|
||||||
|
set -u
|
||||||
|
|
||||||
|
SETTINGS="${MODEL_CHECK_SETTINGS:-$HOME/.claude/settings.json}"
|
||||||
|
|
||||||
|
raw=""
|
||||||
|
if [ -f "$SETTINGS" ]; then
|
||||||
|
raw="$(python3 - "$SETTINGS" 2>/dev/null <<'PY'
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
v = json.load(open(sys.argv[1])).get("model", "")
|
||||||
|
print(v if isinstance(v, str) else "")
|
||||||
|
except Exception:
|
||||||
|
print("")
|
||||||
|
PY
|
||||||
|
)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
norm="$(printf '%s' "$raw" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
case "$norm" in
|
||||||
|
*opusplan*) printf 'unknown:%s\n' "$raw"; exit 3 ;; # opus-for-plan, sonnet otherwise — ambiguous
|
||||||
|
*fable*|*opus*) printf 'big:%s\n' "$raw"; exit 0 ;;
|
||||||
|
*sonnet*|*haiku*) printf 'small:%s\n' "$raw"; exit 2 ;;
|
||||||
|
*) printf 'unknown:%s\n' "$raw"; exit 3 ;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Model gate — reflection requires a big model (BLOCKING)
|
||||||
|
|
||||||
|
Shared include. Runs FIRST in any orchestrator whose reflection —
|
||||||
|
brainstorming, planning, contract, audit judgment, loop decisions —
|
||||||
|
executes inline or in inherit-model subagents. Sonnet-pinned executors are
|
||||||
|
not what this gate protects; it protects the thinking around them (BDR-066).
|
||||||
|
|
||||||
|
## 1. Self-check
|
||||||
|
|
||||||
|
Your system prompt names the model powering this session. Fable or Opus →
|
||||||
|
big. Sonnet, Haiku, anything else → small.
|
||||||
|
|
||||||
|
## 2. Witness — deterministic check
|
||||||
|
|
||||||
|
bash "$HOME/.claude/lib/model-check.sh"
|
||||||
|
|
||||||
|
Output `<class>:<raw>`; exit 0 = big, 2 = small, 3 = unknown. The witness
|
||||||
|
reads the PERSISTED model (settings.json — the file `/model` rewrites,
|
||||||
|
LRN-098). It can lag reality (session launched with `--model`, settings not
|
||||||
|
yet rewritten) — that is why the self-check exists alongside it.
|
||||||
|
|
||||||
|
## 3. Verdict
|
||||||
|
|
||||||
|
| self-check | witness | action |
|
||||||
|
|---|---|---|
|
||||||
|
| big | big (0) | proceed, SILENT — the nominal path prints nothing |
|
||||||
|
| small | any | **STOP** |
|
||||||
|
| big | small (2) | disagreement — **STOP**, surface BOTH values; the user confirms or relaunches |
|
||||||
|
| big | unknown (3) | fail-visible: print `model gate: witness unknown (<raw>) — self-check says <model>` and ask the user to confirm before continuing (BDR-025: unknown never silently passes) |
|
||||||
|
|
||||||
|
**STOP means**: print exactly
|
||||||
|
|
||||||
|
⛔ MODEL GATE — session on <model>. Reflection steps of this skill
|
||||||
|
require Fable or Opus. Switch with /model, then relaunch the skill.
|
||||||
|
|
||||||
|
then end the turn. No later step runs, no agent is dispatched, nothing is
|
||||||
|
edited.
|
||||||
@@ -9,10 +9,12 @@ 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"
|
||||||
|
BSK="$REPO/skills/bugfix/SKILL.md"
|
||||||
HOT="$REPO/agents/hotfixer.md"
|
HOT="$REPO/agents/hotfixer.md"
|
||||||
HSK="$REPO/skills/hotfix/SKILL.md"
|
HSK="$REPO/skills/hotfix/SKILL.md"
|
||||||
|
HSKL="$REPO/skills/hotfix/SKILL.md"
|
||||||
PASS=0; FAIL=0
|
PASS=0; FAIL=0
|
||||||
|
|
||||||
tf() { # tf <label> <file> <fixed-string>
|
tf() { # tf <label> <file> <fixed-string>
|
||||||
@@ -29,6 +31,13 @@ tr_() { # tr_ <label> <file> <ERE>
|
|||||||
echo " FAIL $1 — no match: $3"; FAIL=$((FAIL+1))
|
echo " FAIL $1 — no match: $3"; FAIL=$((FAIL+1))
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
tn() { # tn <label> <file> <fixed-string> — PASS when ABSENT (mirror of tf, inverted)
|
||||||
|
if grep -qF -- "$3" "$2" 2>/dev/null; then
|
||||||
|
echo " FAIL $1 — present (should be absent): $3"; FAIL=$((FAIL+1))
|
||||||
|
else
|
||||||
|
echo " PASS $1"; PASS=$((PASS+1))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo "── verify-secure-loop.md (shared include) ──"
|
echo "── verify-secure-loop.md (shared include) ──"
|
||||||
if [ -f "$INC" ]; then echo " PASS include exists"; PASS=$((PASS+1)); else echo " FAIL include missing"; FAIL=$((FAIL+1)); fi
|
if [ -f "$INC" ]; then echo " PASS include exists"; PASS=$((PASS+1)); else echo " FAIL include missing"; FAIL=$((FAIL+1)); fi
|
||||||
@@ -43,27 +52,39 @@ 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 "── skills/bugfix/SKILL.md (bugfix wiring — reflection inline) ──"
|
||||||
tf "bug contract step" "$BUG" "STEP 3.5 — CONTRACT"
|
tf "bug contract step" "$BSK" "STEP 3.5 — CONTRACT"
|
||||||
tf "bug diagnosis feeds it" "$BUG" "feeds it: REQUEST verbatim"
|
tf "bug diagnosis feeds it" "$BSK" "feeds it: REQUEST verbatim"
|
||||||
tf "bug fresh gates" "$BUG" "Fresh gates (verify + secure)"
|
tf "bug fresh gates" "$BSK" "the two fresh gates per"
|
||||||
tf "bug uses shared include" "$BUG" "lib/verify-secure-loop.md"
|
tf "bug uses shared include" "$BSK" "lib/verify-secure-loop.md"
|
||||||
|
tf "bug dispatches bugfixer" "$BSK" 'subagent_type="bugfixer"'
|
||||||
|
|
||||||
echo "── hotfixer.md (hotfix wiring — revert, not loop) ──"
|
echo "── agents/bugfixer.md (bugfix executor — sonnet, no Agent) ──"
|
||||||
tr_ "hotfix has Agent tool" "$HOT" "^tools:.*Agent"
|
tn "bugfixer lacks Agent tool" "$BUG" "Agent"
|
||||||
tf "hotfix silent contract" "$HOT" "STEP 1.7 — CONTRACT (silent autofill)"
|
tf "bugfixer model sonnet" "$BUG" "model: sonnet"
|
||||||
tf "hotfix zero questions" "$HOT" "questions ever"
|
tf "bugfixer report grammar" "$BUG" "BUGFIX-EXEC REPORT"
|
||||||
tf "hotfix security gate" "$HOT" "Security gate (fresh auditor)"
|
|
||||||
tf "hotfix block reverts" "$HOT" "failure REVERTS, never loops"
|
echo "── hotfixer.md (hotfix executor — sonnet, no Agent) ──"
|
||||||
tf "hotfix no verifier" "$HOT" "No verifier is dispatched at hotfix weight"
|
tn "hotfixer lacks Agent tool" "$HOT" "Agent"
|
||||||
|
tf "hotfixer model sonnet" "$HOT" "model: sonnet"
|
||||||
|
tf "hotfixer report grammar" "$HOT" "HOTFIX-EXEC REPORT"
|
||||||
|
|
||||||
|
echo "── skills/hotfix/SKILL.md (hotfix wiring — revert, not loop) ──"
|
||||||
|
tf "hotfix silent contract" "$HSKL" "STEP 1.7 — CONTRACT (silent autofill)"
|
||||||
|
tf "hotfix zero questions" "$HSKL" "questions ever"
|
||||||
|
tf "hotfix security gate" "$HSKL" "Security gate (fresh auditor)"
|
||||||
|
tf "hotfix block reverts" "$HSKL" "failure REVERTS, never loops"
|
||||||
|
tf "hotfix no verifier" "$HSKL" "No verifier is dispatched at hotfix weight"
|
||||||
tf "hotfix skill has Agent" "$HSK" " - Agent"
|
tf "hotfix skill has Agent" "$HSK" " - Agent"
|
||||||
|
tf "hotfix dispatches hotfixer" "$HSKL" 'subagent_type="hotfixer"'
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "loops-light structure locks: $PASS pass, $FAIL fail"
|
echo "loops-light structure locks: $PASS pass, $FAIL fail"
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# lib/tests/model-check.test.sh — flip-tests for lib/model-check.sh (LRN-096)
|
||||||
|
set -u
|
||||||
|
S="$(cd "$(dirname "$0")/../.." && pwd)/lib/model-check.sh"
|
||||||
|
pass=0; fail=0
|
||||||
|
check() { if [ "$2" = "$3" ]; then pass=$((pass+1)); else fail=$((fail+1));
|
||||||
|
printf 'FAIL %s: got[%s] want[%s]\n' "$1" "$2" "$3"; fi; }
|
||||||
|
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
|
||||||
|
|
||||||
|
fx() { printf '{"model": "%s"}' "$1" > "$T/s.json"; }
|
||||||
|
run() { MODEL_CHECK_SETTINGS="$T/s.json" bash "$S" >"$T/out" 2>&1; echo "$?"; }
|
||||||
|
|
||||||
|
fx 'claude-fable-5[1m]'; check T1-fable-exit "$(run)" 0
|
||||||
|
check T1-fable-class "$(cut -d: -f1 <"$T/out")" big
|
||||||
|
fx 'claude-opus-4-8'; check T2-opus "$(run)" 0
|
||||||
|
fx 'claude-sonnet-5'; check T3-sonnet "$(run)" 2
|
||||||
|
fx 'claude-haiku-4-5-20251001'; check T4-haiku "$(run)" 2
|
||||||
|
fx 'opusplan'; check T5-opusplan "$(run)" 3
|
||||||
|
fx 'gpt-9-mega'; check T6-foreign "$(run)" 3
|
||||||
|
printf '{"no_model": true}' > "$T/s.json"; check T7-no-key "$(run)" 3
|
||||||
|
printf '{broken' > "$T/s.json"; check T8-malformed "$(run)" 3
|
||||||
|
check T9-missing-file "$(MODEL_CHECK_SETTINGS="$T/absent.json" bash "$S" >/dev/null 2>&1; echo $?)" 3
|
||||||
|
|
||||||
|
printf 'model-check: %d pass, %d fail\n' "$pass" "$fail"
|
||||||
|
[ "$fail" -eq 0 ]
|
||||||
Executable
+70
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# lib/tests/model-routing.test.sh — census: gate wiring + pins + executor shape (BDR-066)
|
||||||
|
set -u
|
||||||
|
R="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
|
pass=0; fail=0
|
||||||
|
ok() { pass=$((pass+1)); }
|
||||||
|
ko() { fail=$((fail+1)); printf 'FAIL %s\n' "$1"; }
|
||||||
|
has() { if grep -qF "$2" "$R/$1"; then ok; else ko "$1 missing: $2"; fi; }
|
||||||
|
lacks() { if grep -qF "$2" "$R/$1"; then ko "$1 must NOT contain: $2"; else ok; fi; }
|
||||||
|
fm_lacks() { if awk 'NR<=10' "$R/$1" | grep -qF "$2"; then ko "$1 frontmatter must NOT contain: $2"; else ok; fi; }
|
||||||
|
|
||||||
|
# 1) gate wired in the 15 reflection skills (orchestrators + /analyze)
|
||||||
|
for s in ship-feature init-project feat bugfix onboard seo geo web-validate harden audit-delta tour code-clean hotfix client-handover analyze; do
|
||||||
|
has "skills/$s/SKILL.md" 'lib/model-gate.md'
|
||||||
|
done
|
||||||
|
# 2) gate NOT wired in the pure-execution/read-only skills (exclusion list)
|
||||||
|
for s in commit-change doc status release-candidate refactor; do
|
||||||
|
lacks "skills/$s/SKILL.md" 'lib/model-gate.md'
|
||||||
|
done
|
||||||
|
# 3) executor + gate pins
|
||||||
|
has "agents/feater.md" 'model: sonnet'
|
||||||
|
has "agents/hotfixer.md" 'model: sonnet'
|
||||||
|
has "agents/verifier.md" 'model: sonnet'
|
||||||
|
has "agents/security-auditor.md" 'model: sonnet'
|
||||||
|
fm_lacks "agents/analyzer.md" 'model:'
|
||||||
|
# 4) /feat executor shape
|
||||||
|
has "skills/feat/SKILL.md" 'subagent_type="feater"'
|
||||||
|
has "skills/feat/SKILL.md" 'verify-secure-loop.md'
|
||||||
|
lacks "agents/feater.md" 'AskUserQuestion'
|
||||||
|
# 5) SDD execution pinned
|
||||||
|
has "skills/ship-feature/SKILL.md" 'model: "sonnet"'
|
||||||
|
has "skills/init-project/SKILL.md" 'model: "sonnet"'
|
||||||
|
# 6) web-validate applies via L1 applier
|
||||||
|
has "skills/web-validate/SKILL.md" 'subagent_type="hotfixer"'
|
||||||
|
# 7) wave-2 — pure-execution skills dispatch their agent (pin takes effect, off the big session model)
|
||||||
|
has "skills/doc/SKILL.md" 'subagent_type="doc-syncer"'
|
||||||
|
has "skills/status/SKILL.md" 'subagent_type="status-reporter"'
|
||||||
|
has "skills/commit-change/SKILL.md" 'subagent_type="commit-changer"'
|
||||||
|
has "skills/release-candidate/SKILL.md" 'subagent_type="release-executor"'
|
||||||
|
has "skills/hotfix/SKILL.md" 'subagent_type="hotfixer"'
|
||||||
|
has "agents/commit-changer.md" 'model: sonnet'
|
||||||
|
has "agents/release-executor.md" 'model: sonnet'
|
||||||
|
lacks "agents/commit-changer.md" 'AskUserQuestion'
|
||||||
|
# 8) wave-3 — bugfix/code-clean reflection-split executors (skills stay gated)
|
||||||
|
has "skills/bugfix/SKILL.md" 'subagent_type="bugfixer"'
|
||||||
|
has "agents/bugfixer.md" 'model: sonnet'
|
||||||
|
lacks "agents/bugfixer.md" 'AskUserQuestion'
|
||||||
|
has "skills/code-clean/SKILL.md" 'subagent_type="code-cleaner"'
|
||||||
|
has "agents/code-cleaner.md" 'model: sonnet'
|
||||||
|
lacks "agents/code-cleaner.md" 'AskUserQuestion'
|
||||||
|
# 9) wave-4 — client-handover: pipeline (big) inline + gated, doc-gen dispatched to sonnet
|
||||||
|
has "agents/handover-doc-writer.md" 'model: sonnet'
|
||||||
|
lacks "agents/handover-doc-writer.md" 'AskUserQuestion'
|
||||||
|
lacks "agents/handover-doc-writer.md" 'Agent('
|
||||||
|
has "agents/client-handover-writer.md" 'subagent_type="handover-doc-writer"'
|
||||||
|
# 10) post-merge edge fixes (ronde): F1 feater applier carve-out, F2 /refactor
|
||||||
|
# dispatch + pin, F3 /analyze gated (in loop 1), F4 interviewer un-pinned,
|
||||||
|
# F5 audit agents' ABSENT pin locked (a stray sonnet pin would silently
|
||||||
|
# downgrade a live audit even though the skill's gate passed)
|
||||||
|
has "agents/feater.md" 'Applier path'
|
||||||
|
has "skills/refactor/SKILL.md" 'subagent_type="refactorer"'
|
||||||
|
has "agents/refactorer.md" 'model: sonnet'
|
||||||
|
fm_lacks "agents/seo-analyzer.md" 'model:'
|
||||||
|
fm_lacks "agents/geo-analyzer.md" 'model:'
|
||||||
|
fm_lacks "agents/validator-analyzer.md" 'model:'
|
||||||
|
fm_lacks "agents/client-handover-writer.md" 'model:'
|
||||||
|
fm_lacks "agents/interviewer.md" 'model:'
|
||||||
|
|
||||||
|
printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail"
|
||||||
|
[ "$fail" -eq 0 ]
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
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 a dispatched
|
||||||
|
sonnet executor (feat's `feater`, bugfix's `bugfixer`): "hand the dev"
|
||||||
|
below means 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 +27,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 +52,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.
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ argument-hint: <file/area to analyze — OR paste error/stack trace for DEBUG mo
|
|||||||
allowed-tools: Read, Grep, Glob, Bash
|
allowed-tools: Read, Grep, Glob, Bash
|
||||||
---
|
---
|
||||||
|
|
||||||
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE anything
|
||||||
|
below. Verdict `small` → STOP — print the gate's remedy, end the turn, run
|
||||||
|
no analysis. Deep factual analysis is reflection; it needs the big model.
|
||||||
|
|
||||||
Load and follow strictly:
|
Load and follow strictly:
|
||||||
- $HOME/.claude/agents/analyzer.md
|
- $HOME/.claude/agents/analyzer.md
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /audit-delta — Incremental multi-axis code audit
|
# /audit-delta — Incremental multi-axis code audit
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
Audit only what changed since the last run, on the axes the user picks.
|
Audit only what changed since the last run, on the axes the user picks.
|
||||||
Per axis: **audit → approval gate → fix → re-verify → marker update**,
|
Per axis: **audit → approval gate → fix → re-verify → marker update**,
|
||||||
strictly in that order, one axis fully closed before the next starts.
|
strictly in that order, one axis fully closed before the next starts.
|
||||||
|
|||||||
+245
-3
@@ -20,9 +20,251 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
# /bugfix — root-cause orchestrator (reflection inline, execution dispatched)
|
||||||
- $HOME/.claude/agents/bugfixer.md
|
|
||||||
|
|
||||||
Execute the BUGFIXER agent on the following target:
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE any
|
||||||
|
step below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, dispatch nothing.
|
||||||
|
|
||||||
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 1 — GATHER CONTEXT
|
||||||
|
|
||||||
|
Understand the current state:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status
|
||||||
|
git log --oneline -5
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the error message, stack trace, or bug description.
|
||||||
|
Identify:
|
||||||
|
- **What** is broken (symptom)
|
||||||
|
- **Where** it manifests (file, line, endpoint, UI element)
|
||||||
|
- **When** it started (recent commit? always? after a deploy?)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# If the user mentions "it was working before":
|
||||||
|
git log --oneline -20 --all -- <suspected files>
|
||||||
|
```
|
||||||
|
|
||||||
|
## STEP 1.5 — DESIGN GATE
|
||||||
|
|
||||||
|
Follow `$HOME/.claude/lib/design-gate.md`:
|
||||||
|
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, layout, animation).
|
||||||
|
- 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 2 — INVESTIGATE
|
||||||
|
|
||||||
|
Trace the bug from symptom to root cause:
|
||||||
|
|
||||||
|
1. Read the code path involved (follow the data flow).
|
||||||
|
2. Check recent changes to the affected files:
|
||||||
|
```bash
|
||||||
|
git log --oneline -10 -- <file>
|
||||||
|
git diff HEAD~5 -- <file> # if recent regression suspected
|
||||||
|
```
|
||||||
|
3. Look for related tests — do they pass? Do they cover
|
||||||
|
the broken case?
|
||||||
|
4. Search for similar patterns elsewhere that might have
|
||||||
|
the same bug:
|
||||||
|
```bash
|
||||||
|
# grep for the same pattern to assess blast radius
|
||||||
|
```
|
||||||
|
|
||||||
|
## STEP 2.5 — MEMORY READ-BEFORE (blockers-first)
|
||||||
|
|
||||||
|
Run the scan per `$HOME/.claude/lib/analyze-before-plan.md`, blockers-weighted: a resolved
|
||||||
|
BLK may already name THIS exact root cause; an in-force BDR may constrain the fix. Emit
|
||||||
|
RELATED MEMORY. Consumption is NATURAL — the reflection that emits this IS what writes STEP 3's
|
||||||
|
diagnosis (reader = planner, no external skill to inject into).
|
||||||
|
|
||||||
|
TEETH: STEP 3's DIAGNOSIS must name any binding prior (`PRIOR: BLK-xxx — known cause/fix`,
|
||||||
|
or `honors BDR-xxx`) OR the RELATED MEMORY line states none bears. Reading blockers then
|
||||||
|
diagnosing without naming a match is the read-then-ignore failure this prevents.
|
||||||
|
`.claude/memory/` absent → guarded no-op, proceed.
|
||||||
|
|
||||||
|
## STEP 3 — DIAGNOSE + PLAN
|
||||||
|
|
||||||
|
Present findings before dispatching a fix:
|
||||||
|
|
||||||
|
```
|
||||||
|
BUGFIX — DIAGNOSIS
|
||||||
|
BUG : <one-line symptom>
|
||||||
|
ROOT CAUSE: <what is actually wrong and why>
|
||||||
|
EVIDENCE: <what confirmed it — test, trace, diff>
|
||||||
|
BLAST RADIUS: <other places affected, or "isolated">
|
||||||
|
|
||||||
|
FIX PLAN:
|
||||||
|
1. <file:line> — <what to change>
|
||||||
|
2. <file:line> — <what to change>
|
||||||
|
[3. <test file> — add/update test for this case]
|
||||||
|
|
||||||
|
RISK: <low/medium — what could go wrong>
|
||||||
|
```
|
||||||
|
|
||||||
|
- If the root cause is still unclear after investigation,
|
||||||
|
say so explicitly. List remaining hypotheses ranked by
|
||||||
|
probability. Ask the user before proceeding.
|
||||||
|
- If the fix is trivial after investigation (1-2 lines):
|
||||||
|
proceed directly — no need to wait for approval on an
|
||||||
|
obvious fix.
|
||||||
|
- If the fix is significant (>10 lines, multiple files,
|
||||||
|
behavior change): wait for user approval.
|
||||||
|
|
||||||
|
## STEP 3.5 — CONTRACT
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/contract-interview.md` (main loop). The DIAGNOSIS
|
||||||
|
feeds it: REQUEST verbatim = the bug report as received; ACCEPTANCE CRITERIA
|
||||||
|
= the symptom reproduced-then-gone + a regression test present and passing;
|
||||||
|
FILE SCOPE = the FIX PLAN files. Questions stay proportional (a clear,
|
||||||
|
reproduced bug → zero). It writes the contract to
|
||||||
|
`.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`; keep the path — the
|
||||||
|
executor reads it first and GATE 1 (STEP 6) hands it to a fresh verifier.
|
||||||
|
|
||||||
|
## STEP 4 — BRANCH
|
||||||
|
|
||||||
|
**Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
||||||
|
— your type = `bugfix`. On `main`/`develop` it branches first; on a working
|
||||||
|
branch it's a no-op (commit in place). Never `finish`.
|
||||||
|
|
||||||
|
## STEP 5 — DISPATCH EXECUTOR
|
||||||
|
|
||||||
|
Dispatch the executor — sonnet by frontmatter pin, do not override:
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="bugfixer")
|
||||||
|
prompt: "CONTRACT: <path from STEP 3.5>
|
||||||
|
DIAGNOSIS: <ROOT CAUSE + EVIDENCE from STEP 3>
|
||||||
|
FIX PLAN: <the STEP 3 FIX PLAN — exact edits + the regression test to add>
|
||||||
|
BRANCH: <current branch — verify with git branch --show-current, never switch>
|
||||||
|
Apply the fix to the letter + the regression test. No commit, no branch
|
||||||
|
ops, no security dispatch. Finish with the BUGFIX-EXEC REPORT."
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the `BUGFIX-EXEC REPORT`:
|
||||||
|
- `STATUS : DONE` → STEP 6.
|
||||||
|
- `STATUS : NEED-DECISION` → make the decision HERE (that is reflection),
|
||||||
|
append it to the plan, re-dispatch a FRESH bugfixer with plan + decision.
|
||||||
|
Max 2 decision round-trips → escalate to the user.
|
||||||
|
- `STATUS : BLOCKED` → surface the blocker to the user, stop.
|
||||||
|
|
||||||
|
## STEP 6 — VERIFY + SECURE + PRE-COMMIT GATE + COMMIT (main loop, LRN-083)
|
||||||
|
|
||||||
|
1. Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with
|
||||||
|
`CONTRACT` = the STEP 3.5 path, `DIFF` = the executor's working-tree diff,
|
||||||
|
`TEST` = the suite named in its report:
|
||||||
|
- GATE 1 — a FRESH verifier judges the fix against the contract (bug gone
|
||||||
|
+ regression test present). 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 bugfixer with the CONTRACT path + the
|
||||||
|
exact gap lines, nothing else. Max 3 → escalate.
|
||||||
|
- GATE 2 — a FRESH security-auditor (`MODE: gate`) scans the diff (a bug
|
||||||
|
fix can introduce a vuln). PASS → the pre-commit gate below. BLOCK →
|
||||||
|
re-dispatch a FRESH bugfixer 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 = one
|
||||||
|
executor + one verifier + one security dispatch.
|
||||||
|
|
||||||
|
2. **Pre-commit confirmation gate.** Before running `git commit`, present the diff
|
||||||
|
summary and the proposed message, then wait for approval:
|
||||||
|
|
||||||
|
```
|
||||||
|
BUGFIX — READY TO COMMIT
|
||||||
|
FILE(S) : <list>
|
||||||
|
DIFF : <git diff --stat>
|
||||||
|
MESSAGE :
|
||||||
|
fix(<scope>): <root cause description>
|
||||||
|
|
||||||
|
<what was wrong and why>
|
||||||
|
<what the fix does>
|
||||||
|
|
||||||
|
Commit now? (yes / edit message / skip / amend last)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `yes` → run `git commit`.
|
||||||
|
- `edit message` → user provides corrected message; redraw gate.
|
||||||
|
- `skip` → leave changes uncommitted, exit cleanly.
|
||||||
|
- `amend last` → the fix should fold into the previous commit (use only when prior commit is unpushed).
|
||||||
|
|
||||||
|
3. Commit using conventional format (after approval):
|
||||||
|
```
|
||||||
|
fix(<scope>): <root cause description>
|
||||||
|
|
||||||
|
<what was wrong and why>
|
||||||
|
<what the fix does>
|
||||||
|
```
|
||||||
|
4. Print summary:
|
||||||
|
```
|
||||||
|
BUGFIX COMPLETE
|
||||||
|
BUG : <symptom>
|
||||||
|
ROOT CAUSE : <one-line>
|
||||||
|
FILE(S) : <changed files>
|
||||||
|
TEST(S) : <added/updated tests, or "none — verified manually">
|
||||||
|
REGRESSION : <checked areas>
|
||||||
|
```
|
||||||
|
|
||||||
|
## STEP 7 — 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 8 — CAPITALIZE (memory registries)
|
||||||
|
|
||||||
|
A bugfix with an understood root cause is almost always worth one entry:
|
||||||
|
|
||||||
|
1. Propose a `BLK-XXX` entry in `.claude/memory/blockers.md` pre-filled from STEP 3 diagnosis:
|
||||||
|
- `friction` = symptom
|
||||||
|
- `real_cause` = root cause identified
|
||||||
|
- `solution` = the fix applied
|
||||||
|
- `status` = resolved
|
||||||
|
2. If the root cause exposed a **reusable pattern** (would catch the same bug elsewhere or in other projects) → also propose an `LRN-XXX` entry in `.claude/memory/learnings.md`.
|
||||||
|
3. Present as:
|
||||||
|
```
|
||||||
|
CAPITALIZE — proposé
|
||||||
|
BLK-XXX — <friction> — resolved
|
||||||
|
[LRN-XXX — <pattern>] (optionnel)
|
||||||
|
Valider ? (all / blockers-only / edit / skip)
|
||||||
|
```
|
||||||
|
4. Append approved entries + update the Index. Add a line 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 the bug was trivial and the root cause not transferable → skip with `CAPITALIZE: trivial, skip`.
|
||||||
|
|
||||||
|
**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
|
||||||
|
- No fix without understanding the root cause first (STEP 2/3).
|
||||||
|
- Reflection (GATHER, INVESTIGATE, DIAGNOSIS, contract, loop decisions) NEVER
|
||||||
|
leaves this main loop; execution NEVER stays in it — the executor is the
|
||||||
|
sonnet-pinned bugfixer subagent (BDR-066).
|
||||||
|
- The executor is re-dispatched FRESH on every round-trip (NEED-DECISION,
|
||||||
|
ECARTS, BLOCK) — feedback travels as contract path + named
|
||||||
|
gaps/decisions, never as transcript.
|
||||||
|
- Design gate only if UI/style signals detected. See STEP 1.5.
|
||||||
|
- If investigation reveals a design flaw requiring significant
|
||||||
|
refactoring → stop, explain, suggest `/ship-feature` for the
|
||||||
|
proper fix.
|
||||||
|
- Always add a regression test when possible.
|
||||||
|
- Keep the fix scoped. No "while we're here" cleanups.
|
||||||
|
- If >5 files need changes → reconsider if `/ship-feature`
|
||||||
|
is more appropriate.
|
||||||
|
|||||||
@@ -21,10 +21,17 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE loading
|
||||||
|
the agent below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, do not load the agent.
|
||||||
|
|
||||||
Load and follow strictly:
|
Load and follow strictly:
|
||||||
- $HOME/.claude/agents/client-handover-writer.md
|
- $HOME/.claude/agents/client-handover-writer.md
|
||||||
|
|
||||||
Execute the CLIENT HANDOVER WRITER agent on this project.
|
Execute the CLIENT HANDOVER WRITER agent on this project. It runs the
|
||||||
|
audit/fix/gate pipeline INLINE on the big session model (gated above), then
|
||||||
|
delegates the client deliverable (Markdown + branded HTML + PDF) to the
|
||||||
|
sonnet-pinned `handover-doc-writer` subagent (BDR-066).
|
||||||
|
|
||||||
The agent runs a **ship-and-handover pipeline** with explicit gates:
|
The agent runs a **ship-and-handover pipeline** with explicit gates:
|
||||||
|
|
||||||
|
|||||||
+186
-3
@@ -20,9 +20,192 @@ allowed-tools:
|
|||||||
- AskUserQuestion
|
- AskUserQuestion
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
# /code-clean — cleanup orchestrator (audit inline, execution dispatched)
|
||||||
- $HOME/.claude/agents/code-cleaner.md
|
|
||||||
|
|
||||||
Execute the CODE-CLEANER agent on the following target:
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE any
|
||||||
|
step below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, dispatch nothing.
|
||||||
|
|
||||||
|
## TARGET
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
|
If blank → entire project from repository root.
|
||||||
|
|
||||||
|
The audit (STEPS 1-3) runs inline, on the session model — reading code and
|
||||||
|
judging severity is reflection. Once the user approves a scope (STEP 4),
|
||||||
|
execution is dispatched to the sonnet-pinned `code-cleaner` executor
|
||||||
|
(STEP 5). The iron law is unchanged across both halves: zero behavior
|
||||||
|
change — identical observable output before and after.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 1 — LOAD PROJECT NORMS
|
||||||
|
|
||||||
|
Read the project's coding standards in this priority order:
|
||||||
|
|
||||||
|
1. `CLAUDE.md` at project root (primary authority)
|
||||||
|
2. Language/framework config files present in the repo:
|
||||||
|
- JS/TS: `.eslintrc*`, `.prettierrc*`, `tsconfig.json`
|
||||||
|
- Python: `pyproject.toml`, `setup.cfg`, `.flake8`, `ruff.toml`
|
||||||
|
- PHP: `phpcs.xml`, `.php-cs-fixer.php`
|
||||||
|
- Go: `.golangci.yml`
|
||||||
|
- General: `.editorconfig`
|
||||||
|
3. If neither CLAUDE.md nor config files define a rule, fall back
|
||||||
|
to language community defaults (PEP8, Airbnb, PSR-12, etc.)
|
||||||
|
|
||||||
|
CLAUDE.md rules always win over tool configs when they conflict.
|
||||||
|
|
||||||
|
## STEP 2 — SCAN
|
||||||
|
|
||||||
|
Systematically scan the target for three categories of issues.
|
||||||
|
|
||||||
|
**A. Dead code**
|
||||||
|
- Unused imports and variables
|
||||||
|
- Unused functions/methods (not exported, no callers)
|
||||||
|
- Unreachable code blocks (after return, break, etc.)
|
||||||
|
- Commented-out code blocks (more than 2 consecutive lines)
|
||||||
|
- TODO/FIXME comments older than 90 days (check with `git log`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check age of TODO/FIXME comments
|
||||||
|
git log --all -p --reverse -S "TODO" -- <file> | head -40
|
||||||
|
```
|
||||||
|
|
||||||
|
**B. Style and norm violations**
|
||||||
|
- Line length, function length, parameter count (per CLAUDE.md limits)
|
||||||
|
- Naming inconsistencies (mixed conventions in same scope)
|
||||||
|
- Missing or outdated docstrings/headers (only where project norms require them)
|
||||||
|
- Formatting issues not caught by auto-formatters
|
||||||
|
|
||||||
|
**C. Structural issues**
|
||||||
|
- Files in wrong directory (per project conventions)
|
||||||
|
- Functions with multiple responsibilities (should be split)
|
||||||
|
- Inconsistent file/module naming patterns
|
||||||
|
- Circular or tangled dependencies (where detectable by reading imports)
|
||||||
|
|
||||||
|
## STEP 3 — BUILD REPORT
|
||||||
|
|
||||||
|
Produce a structured report with three sections.
|
||||||
|
Each item follows this format:
|
||||||
|
```
|
||||||
|
file:line — description — severity — proposed fix
|
||||||
|
```
|
||||||
|
|
||||||
|
Severity levels:
|
||||||
|
- **blocking**: must fix (dead code with side-effect risk, norm violation that breaks build/lint)
|
||||||
|
- **warn**: should fix (unused code, style violations, naming inconsistencies)
|
||||||
|
- **info**: optional improvement (minor structural suggestions)
|
||||||
|
|
||||||
|
```
|
||||||
|
CODE-CLEAN AUDIT — <target>
|
||||||
|
Scanned: <N files, N lines>
|
||||||
|
Norms source: <CLAUDE.md / .eslintrc / PEP8 fallback / etc.>
|
||||||
|
|
||||||
|
═══ DEAD CODE ═══
|
||||||
|
1. src/utils.py:42 — unused import `os` — warn — delete import
|
||||||
|
2. src/api/handler.ts:118-134 — commented-out block — warn — delete block
|
||||||
|
3. ...
|
||||||
|
|
||||||
|
═══ STYLE VIOLATIONS ═══
|
||||||
|
1. src/core/parser.py:67 — function `process_data` is 48 lines (max 25) — blocking — split into parse + validate
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
═══ STRUCTURAL ISSUES ═══
|
||||||
|
1. lib/helpers/auth.ts — auth logic in helpers/, should be in lib/auth/ — info — move file
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
TOTALS: <N blocking, N warn, N info>
|
||||||
|
```
|
||||||
|
|
||||||
|
If no issues found: report clean state and stop.
|
||||||
|
|
||||||
|
## STEP 4 — VALIDATION GATE (interactive)
|
||||||
|
|
||||||
|
Present the report from STEP 3. Then ask:
|
||||||
|
|
||||||
|
```
|
||||||
|
AskUserQuestion:
|
||||||
|
Approve which items for execution? (all / <item numbers> / clarify <item>)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `all` → every item in the report is approved for execution.
|
||||||
|
- `<item numbers>` (e.g. `A1,A3,B2`) → only those items are approved; the
|
||||||
|
rest stay untouched.
|
||||||
|
- `clarify <item>` → discuss the item, then re-ask.
|
||||||
|
|
||||||
|
**Exported / public-API symbols**: any dead-code item flagged as exported or
|
||||||
|
part of a public API requires EXPLICIT per-item confirmation before it can
|
||||||
|
be approved — even if it appears unused internally. Ask for it by name; do
|
||||||
|
not fold it into a blanket `all`. This consent lives HERE, at the gate —
|
||||||
|
the dispatched executor never asks, it only executes what this step already
|
||||||
|
cleared.
|
||||||
|
|
||||||
|
**Do NOT proceed to STEP 5 until the user explicitly approves.** If nothing
|
||||||
|
is approved, stop — no dispatch.
|
||||||
|
|
||||||
|
## STEP 5 — PERSIST SCOPE + DISPATCH
|
||||||
|
|
||||||
|
1. **Persist the approved scope.** Write the approved items to
|
||||||
|
`.claude/audits/CODE-CLEAN-SCOPE.md` (run `mkdir -p .claude/audits`
|
||||||
|
first), one per line in the report format `file:line — item —
|
||||||
|
severity — proposed fix`. This is the executor's scope-of-work on
|
||||||
|
disk — named, auditable, the same contract discipline as the dev
|
||||||
|
gates (verifier reads its contract from disk).
|
||||||
|
2. **Dispatch the executor** — sonnet by frontmatter pin, do not override:
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="code-cleaner")
|
||||||
|
prompt: "SCOPE: .claude/audits/CODE-CLEAN-SCOPE.md
|
||||||
|
APPROVED: <the approved item list, incl. any per-item exported-symbol clears>
|
||||||
|
BRANCH: <current branch — verify with git branch --show-current, never switch>
|
||||||
|
Execute PHASE 2 on the approved scope only. Zero behavior change. No commit.
|
||||||
|
Finish with the CODE-CLEAN-EXEC REPORT."
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Parse the `CODE-CLEAN-EXEC REPORT`:
|
||||||
|
- `STATUS : DONE` → STEP 6.
|
||||||
|
- `STATUS : BLOCKED` → surface the blocker to the user, stop.
|
||||||
|
|
||||||
|
## STEP 6 — SUMMARY
|
||||||
|
|
||||||
|
Translate the executor's `CODE-CLEAN-EXEC REPORT` into the user-facing
|
||||||
|
summary:
|
||||||
|
|
||||||
|
```
|
||||||
|
CODE-CLEAN COMPLETE — <target>
|
||||||
|
|
||||||
|
REMOVED:
|
||||||
|
- <N> dead code items (unused imports, functions, commented blocks)
|
||||||
|
|
||||||
|
REFACTORED:
|
||||||
|
- <N> style fixes
|
||||||
|
- <N> structural improvements
|
||||||
|
|
||||||
|
SKIPPED (user decision):
|
||||||
|
- <item> — <reason>
|
||||||
|
|
||||||
|
BUGS FOUND: <N> (logged to .claude/audits/BUGS-FOUND.md)
|
||||||
|
|
||||||
|
TESTS: passing / no test suite / <failures>
|
||||||
|
```
|
||||||
|
|
||||||
|
No commit here — code-clean has never auto-committed. Leave the working
|
||||||
|
tree for the user, or a follow-up `/commit-change`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RULES
|
||||||
|
|
||||||
|
- Zero behavior change. If unsure whether a deletion changes behavior,
|
||||||
|
leave it and flag it — never guess.
|
||||||
|
- No "while we're here" scope creep. Only items approved at STEP 4 reach
|
||||||
|
the executor.
|
||||||
|
- Exported/public API symbols require explicit per-item user consent AT
|
||||||
|
THE GATE (STEP 4) before approval — even if they appear unused. The
|
||||||
|
executor never asks; it only executes what the gate already cleared.
|
||||||
|
- Bugs go to `.claude/audits/BUGS-FOUND.md`, not fixed in this workflow.
|
||||||
|
- If the codebase has no tests and the changes are non-trivial, warn the
|
||||||
|
user about the risk before dispatching.
|
||||||
|
- No plugin check (lightweight skill).
|
||||||
|
- If the audit reveals systemic issues requiring architecture changes,
|
||||||
|
stop and suggest `/ship-feature` for a proper redesign.
|
||||||
|
|||||||
@@ -16,15 +16,102 @@ allowed-tools:
|
|||||||
- AskUserQuestion
|
- AskUserQuestion
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly: `$HOME/.claude/agents/commit-changer.md`.
|
# /commit-change — propose → confirm → apply dispatcher
|
||||||
|
|
||||||
If unreachable, emit `Commit-changer agent missing.` and STOP. Never auto-commit blind — a wrong group is harder to undo than not committing.
|
Grouping and committing both run on the sonnet-pinned `commit-changer`
|
||||||
|
subagent (dispatch makes the pin effective). No inline reflection happens
|
||||||
|
in this dispatcher to protect, so there is no model gate. This dispatcher
|
||||||
|
owns the two approval gates that used to live inside the subagent:
|
||||||
|
commit-plan approval and capitalize approval — the subagent never asks;
|
||||||
|
`MODE: propose` only proposes, `MODE: apply` only executes what this
|
||||||
|
dispatcher confirms. Never auto-commit blind — a wrong group is harder to
|
||||||
|
undo than not committing.
|
||||||
|
|
||||||
Pre-flight checks (the agent should also perform, but flag here):
|
## STEP 0 — Pre-flight (STOP conditions, before any dispatch)
|
||||||
- Detached HEAD or unmerged conflicts → STOP, report state.
|
|
||||||
- Identity unconfigured (`git config user.email` empty) → STOP, ask user.
|
|
||||||
- On a protected base (`main`/`develop`) the agent runs the gitflow
|
|
||||||
aiguillage (Phase 0) and branches to `chore/*` before committing — code
|
|
||||||
never lands directly on a protected branch.
|
|
||||||
|
|
||||||
$ARGUMENTS
|
```bash
|
||||||
|
git rev-parse --abbrev-ref HEAD # "HEAD" = detached
|
||||||
|
git status --porcelain=v1 | grep -c '^UU\|^AA\|^DD' # unmerged conflicts
|
||||||
|
git status --porcelain=v1 | wc -l # nothing pending?
|
||||||
|
git config user.email
|
||||||
|
```
|
||||||
|
|
||||||
|
- Detached HEAD → STOP, report the state, do not dispatch.
|
||||||
|
- Any unmerged conflict entries (`UU`/`AA`/`DD`) → STOP, tell the user to
|
||||||
|
resolve conflicts first, do not dispatch.
|
||||||
|
- Nothing pending (`git status --porcelain` empty) → STOP, tell the user
|
||||||
|
there's nothing to commit.
|
||||||
|
- `git config user.email` empty → STOP, ask the user to configure identity
|
||||||
|
first, do not dispatch.
|
||||||
|
|
||||||
|
On a protected base (`main`/`develop`) the subagent runs the gitflow
|
||||||
|
aiguillage itself inside `MODE: propose` (its Phase 0) and branches to
|
||||||
|
`chore/*` before drafting the plan — code never lands directly on a
|
||||||
|
protected branch.
|
||||||
|
|
||||||
|
## STEP 1 — Propose
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="commit-changer")
|
||||||
|
prompt: "MODE: propose
|
||||||
|
$ARGUMENTS"
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the returned `COMMIT PLAN` + `EDGE CASES` + `CAPITALIZE CANDIDATES`,
|
||||||
|
terminated by `READY TO APPLY — awaiting dispatcher confirmation`.
|
||||||
|
|
||||||
|
The subagent reported `BLOCKED: unresolved merge conflicts...` instead of a
|
||||||
|
plan (a race with STEP 0) → STOP, surface it, do not proceed.
|
||||||
|
|
||||||
|
## STEP 2 — Gate 1: commit-plan approval
|
||||||
|
|
||||||
|
Show the `COMMIT PLAN` and any `EDGE CASES` verbatim, then:
|
||||||
|
|
||||||
|
```
|
||||||
|
AskUserQuestion:
|
||||||
|
Approve the commit plan? (all / <numbers> / edit <n> / skip)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `all` → every step in the plan is approved as-is.
|
||||||
|
- `<numbers>` (e.g. `1,3`) → only those steps are approved; the rest stay
|
||||||
|
uncommitted for a later run.
|
||||||
|
- `edit <n>` → re-dispatch `commit-changer` with `MODE: propose` and the
|
||||||
|
user's correction for step N folded into the prompt, so all grouping /
|
||||||
|
message judgment stays on the sonnet subagent (never redrawn inline on
|
||||||
|
the session model); show the redrawn plan and re-ask.
|
||||||
|
- `skip` → exit cleanly, no commits created, no `MODE: apply` dispatch.
|
||||||
|
Note: if the propose run created a `chore/*` branch (gitflow aiguillage
|
||||||
|
off a protected base), that branch stays checked out with the work
|
||||||
|
uncommitted — mention it so the user isn't surprised by the branch switch.
|
||||||
|
|
||||||
|
## STEP 3 — Gate 2: capitalize approval
|
||||||
|
|
||||||
|
If the STEP 1 output said `CAPITALIZE: nothing to log`, skip this gate —
|
||||||
|
treat the capitalize entries as `none` and go straight to STEP 4.
|
||||||
|
|
||||||
|
Otherwise show the `CAPITALIZE CANDIDATES` block, then:
|
||||||
|
|
||||||
|
```
|
||||||
|
AskUserQuestion:
|
||||||
|
Valider les entrées mémoire ? (all / <IDs> / skip)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `all` → every candidate entry is approved verbatim.
|
||||||
|
- `<IDs>` (e.g. `BDR-041,LRN-019`) → only those entries are approved.
|
||||||
|
- `skip` → no memory write; `MODE: apply` still runs for the code commits.
|
||||||
|
|
||||||
|
## STEP 4 — Apply
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="commit-changer")
|
||||||
|
prompt: "MODE: apply
|
||||||
|
APPROVED PLAN: <the STEP-2-approved steps — numbers, messages, files,
|
||||||
|
exactly as confirmed, including any edits>
|
||||||
|
APPROVED CAPITALIZE ENTRIES: <the STEP-3-approved entries verbatim, or none>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the `COMMIT-EXEC REPORT`:
|
||||||
|
- `STATUS: DONE` → report the `COMMITS` + `MEMORY` hashes to the user.
|
||||||
|
- `STATUS: BLOCKED` → surface the blocker verbatim and stop. Do not retry
|
||||||
|
automatically — a blocked step (e.g. one file needs an interactive
|
||||||
|
`git add -p` split) needs a human decision.
|
||||||
|
|||||||
+9
-5
@@ -15,12 +15,16 @@ allowed-tools:
|
|||||||
- Bash
|
- Bash
|
||||||
- Grep
|
- Grep
|
||||||
- Glob
|
- Glob
|
||||||
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
Dispatch the doc-syncer as a subagent so its `model: sonnet` pin takes
|
||||||
- $HOME/.claude/agents/doc-syncer.md
|
effect (doc-sync = execution, not the session's big model):
|
||||||
|
|
||||||
Execute the DOC SYNCER on this project.
|
Agent(subagent_type="doc-syncer")
|
||||||
|
prompt: "Audit + sync public docs for this project. Context from the user:
|
||||||
|
$ARGUMENTS. Report PATCHED_FILES and a summary — do NOT commit."
|
||||||
|
|
||||||
Context from the user (if any):
|
Then commit the patched docs from THIS loop per `$HOME/.claude/lib/doc-commit.md`
|
||||||
$ARGUMENTS
|
(surgical: only doc-syncer's PATCHED_FILES, never `.claude/`/`CLAUDE.md`,
|
||||||
|
no-op if nothing patched).
|
||||||
|
|||||||
+221
-7
@@ -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,9 +20,223 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
# /feat — small-feature orchestrator (reflection inline, execution dispatched)
|
||||||
- $HOME/.claude/agents/feater.md
|
|
||||||
|
|
||||||
Execute the FEATER agent on the following target:
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE any
|
||||||
|
step below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, dispatch nothing.
|
||||||
|
|
||||||
|
## 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 → route to `/hotfix` (its orchestrator does LOCATE + dispatches the hotfixer executor; never load the bare agent file) |
|
||||||
|
| 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 grouped by logical
|
||||||
|
unit — or run `/commit-change` on the pending work (it dispatches the
|
||||||
|
sonnet commit-changer; never inline-load the bare agent, it is now a
|
||||||
|
propose/apply executor).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /geo — GEO (AI-search) audit + fix dispatcher
|
# /geo — GEO (AI-search) audit + fix dispatcher
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
Dispatches the `geo-analyzer` subagent (audit + fix bundle), then applies
|
Dispatches the `geo-analyzer` subagent (audit + fix bundle), then applies
|
||||||
the bundle from THIS main loop at **L1** — same shape as `/web-validate`
|
the bundle from THIS main loop at **L1** — same shape as `/web-validate`
|
||||||
and `/seo`. The analyzer never edits files: it emits a `## FIX BUNDLE`
|
and `/seo`. The analyzer never edits files: it emits a `## FIX BUNDLE`
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /harden — web hardening audit
|
# /harden — web hardening audit
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
This skill orchestrates a narrow-scope hardening audit: TLS + security
|
This skill orchestrates a narrow-scope hardening audit: TLS + security
|
||||||
headers + redirects + canonical + custom 404 + server configs. It
|
headers + redirects + canonical + custom 404 + server configs. It
|
||||||
reuses the `seo-analyzer` agent with a **strict scope filter** to avoid
|
reuses the `seo-analyzer` agent with a **strict scope filter** to avoid
|
||||||
|
|||||||
+180
-3
@@ -18,9 +18,186 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
# /hotfix — quick-fix orchestrator (reflection inline, execution dispatched)
|
||||||
- $HOME/.claude/agents/hotfixer.md
|
|
||||||
|
|
||||||
Execute the HOTFIXER agent on the following target:
|
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE any
|
||||||
|
step below. Verdict `small` → STOP — print the gate's remedy, end the
|
||||||
|
turn, dispatch nothing.
|
||||||
|
|
||||||
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## STEP 1 — LOCATE (reflection)
|
||||||
|
|
||||||
|
Find the bug. Use the description and any error message to go
|
||||||
|
straight to the source:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status
|
||||||
|
git log --oneline -3
|
||||||
|
```
|
||||||
|
|
||||||
|
- Read the relevant file(s). Confirm the root cause is obvious
|
||||||
|
and superficial (typo, wrong value, missing import, etc.).
|
||||||
|
- If the bug turns out to be deeper than expected (unclear cause,
|
||||||
|
multiple files involved, logic error): STOP and say:
|
||||||
|
"This looks deeper than a hotfix — it needs investigation. Re-run this
|
||||||
|
as `/bugfix` (root-cause investigation, then a scoped fix)."
|
||||||
|
- Settle the proposed fix HERE — the executor cannot ask questions, so the
|
||||||
|
exact edit (what changes, in which file(s)) must be closed before dispatch.
|
||||||
|
|
||||||
|
OPTIONAL — memory check (exempt by default; hotfix = obvious fix, mirror of its capitalize
|
||||||
|
skip). For a RECURRING or urgent bug only, a quick blockers-only glance may save time:
|
||||||
|
|
||||||
|
[ -d .claude/memory ] && grep -nE '^## BLK-' .claude/memory/blockers.md # "déjà vu ?"
|
||||||
|
|
||||||
|
If a prior BLK names this bug, jump to its solution. Not mandatory; no RELATED MEMORY
|
||||||
|
disposition required at hotfix weight.
|
||||||
|
|
||||||
|
## STEP 1.5 — DESIGN GATE
|
||||||
|
|
||||||
|
Follow `$HOME/.claude/lib/design-gate.md`:
|
||||||
|
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, styling, animation).
|
||||||
|
- 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 1.7 — CONTRACT (silent autofill)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/contract-interview.md` at hotfix weight: **zero
|
||||||
|
questions ever** (a hotfix is an obvious fix by definition). Autofill the
|
||||||
|
contract — REQUEST verbatim = the bug description as given; ACCEPTANCE
|
||||||
|
CRITERIA = "symptom gone; build/tests green"; FILE SCOPE = the 1-2 target
|
||||||
|
files from STEP 1. It writes `.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`.
|
||||||
|
This is the reference the executor reads first, and the scope for STEP 4's
|
||||||
|
security gate and the escalation report if a gate fails. No verifier is
|
||||||
|
dispatched at hotfix weight — STEP 4's smoke result already verifies these
|
||||||
|
trivial criteria; the gate hotfix adds is security (STEP 4).
|
||||||
|
|
||||||
|
## STEP 2 — PRE-FLIGHT
|
||||||
|
|
||||||
|
**Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
||||||
|
— your type = `hotfix`. On `main`/`develop` it branches first; on a working
|
||||||
|
branch it's a no-op (commit in place). Never `finish`.
|
||||||
|
|
||||||
|
Snapshot current state so revert is possible:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git diff HEAD --stat # confirm working tree is clean OR carries only the
|
||||||
|
# in-progress hotfix area; if unrelated dirty files are
|
||||||
|
# present, ask user whether to stash them first
|
||||||
|
git rev-parse HEAD # capture the SHA to revert to on failure
|
||||||
|
```
|
||||||
|
|
||||||
|
If the working tree contains unrelated uncommitted changes the user has not
|
||||||
|
mentioned: STOP and ask `"working tree dirty: stash and continue, or abort?"`.
|
||||||
|
|
||||||
|
## STEP 3 — DISPATCH EXECUTOR
|
||||||
|
|
||||||
|
Dispatch the executor — sonnet by frontmatter pin, do not override:
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="hotfixer")
|
||||||
|
prompt: "CONTRACT: <path from STEP 1.7>
|
||||||
|
LOCATED: <file(s) found in STEP 1 + the confirmed root cause>
|
||||||
|
FIX: <the proposed minimal fix, closed in STEP 1>
|
||||||
|
BRANCH: <current branch — verify with git branch --show-current, never switch>
|
||||||
|
Apply the minimal fix. No refactoring, no commit, no branch ops, no
|
||||||
|
security dispatch, no revert. Finish with the HOTFIX-EXEC REPORT."
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the `HOTFIX-EXEC REPORT`:
|
||||||
|
- `STATUS : DONE` → STEP 4 (the SMOKE line in the report decides pass/fail
|
||||||
|
there; DONE here means execution completed, not that it verified clean).
|
||||||
|
- `STATUS : BLOCKED` → if any edits were made, `git restore .` to the
|
||||||
|
pre-flight SHA (STEP 2); surface the blocker to the user; STOP. One
|
||||||
|
attempt only — hotfix never re-dispatches (escalate to `/bugfix` for
|
||||||
|
deeper work).
|
||||||
|
|
||||||
|
## STEP 4 — VERIFY + SECURE + COMMIT (main loop, LRN-083)
|
||||||
|
|
||||||
|
1. Read the SMOKE line from the executor's report. **Failure branch** — if
|
||||||
|
it reports a failing test/build result:
|
||||||
|
- Print the failure output verbatim (under 30 lines).
|
||||||
|
- Run `git restore .` to revert the working-tree edits to the pre-flight
|
||||||
|
SHA (STEP 2). (Files were not yet staged — restore is safe.)
|
||||||
|
- STOP and tell user: `"Hotfix introduced a regression. Reverted.
|
||||||
|
Escalate to /bugfix or /analyze for deeper investigation."`
|
||||||
|
- Do NOT commit a broken fix.
|
||||||
|
2. **Security gate (fresh auditor) — failure REVERTS, never loops.** Dispatch
|
||||||
|
a FRESH security-auditor (`subagent_type: security-auditor`, or load
|
||||||
|
`agents/security-auditor.md`) with `MODE: gate`, `SCOPE:` the working-tree
|
||||||
|
diff vs the pre-flight SHA. Parse its `SECURITY — VERDICT:` line:
|
||||||
|
- `PASS` (or `DEGRADED` with no BLOCK) → proceed to commit.
|
||||||
|
- `BLOCK(n)` → this is hotfix: do NOT loop. Run `git restore .` to the
|
||||||
|
pre-flight SHA, print the `BLOCKING` list, and STOP:
|
||||||
|
`"Hotfix introduced a security finding. Reverted. Escalate to /bugfix
|
||||||
|
for a fix under the full verify+security loop."` The hotfix model is
|
||||||
|
one attempt; any gate failure (smoke OR security) reverts and escalates.
|
||||||
|
- Structural failure (mute / unparsable / no VERDICT line) → treat as a
|
||||||
|
failed gate: retry ONCE fresh; a 2nd structural failure → revert +
|
||||||
|
escalate. A mute auditor is never a PASS.
|
||||||
|
3. Commit using conventional format (only after smoke AND security pass):
|
||||||
|
```
|
||||||
|
fix(<scope>): <what was wrong>
|
||||||
|
```
|
||||||
|
4. Print summary:
|
||||||
|
```
|
||||||
|
HOTFIX APPLIED
|
||||||
|
FILE(S) : <changed files>
|
||||||
|
FIX : <one-line description>
|
||||||
|
VERIFIED: <test name or smoke check that passed>
|
||||||
|
SECURITY: <PASS | DEGRADED (checklist only)>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 hotfix. No FINISH in an inline flow, so
|
||||||
|
it just commits the docs on the current branch (no ordering concern).
|
||||||
|
|
||||||
|
## STEP 6 — CAPITALIZE (memory registries, lightweight)
|
||||||
|
|
||||||
|
Hotfixes are often trivial (typo, config, import) — skip by default. But if the fix revealed something non-obvious:
|
||||||
|
|
||||||
|
- Wrong default that should never have been merged → propose `LRN-XXX` in `.claude/memory/learnings.md`.
|
||||||
|
- Bug that cost real time to locate despite being "superficial" → propose `BLK-XXX` in `.claude/memory/blockers.md` (status: resolved).
|
||||||
|
|
||||||
|
Default behaviour: `CAPITALIZE: hotfix trivial, skip` (no prompt, no output).
|
||||||
|
Ask the user only when there is an actual candidate to propose.
|
||||||
|
|
||||||
|
Always append a 1-line entry to today's heading in `.claude/memory/journal.md` (even trivial hotfix — journal is timeline, not signal).
|
||||||
|
|
||||||
|
**Language rule**: the journal line and any proposed BLK/LRN entries are ALWAYS written in English (see CLAUDE.md "Memory registries" § Language).
|
||||||
|
|
||||||
|
**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. The always-on journal line means a
|
||||||
|
trivial hotfix still produces a `chore(memory): journal — …` commit (Frame 2 / F3).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RULES
|
||||||
|
- Max 2 files changed. If more needed → `/bugfix`.
|
||||||
|
- Reflection (LOCATE, contract, gate decisions) NEVER leaves this main
|
||||||
|
loop; execution NEVER stays in it — the executor is the sonnet-pinned
|
||||||
|
hotfixer subagent (BDR-066).
|
||||||
|
- The executor is dispatched FRESH, once — hotfix never re-dispatches (no
|
||||||
|
decision round-trips; a blocked or failed attempt reverts and escalates
|
||||||
|
to `/bugfix`, it does not retry).
|
||||||
|
- Design gate only if CSS/style signals detected. See STEP 1.5.
|
||||||
|
- **Revert-not-loop preserved**: smoke FAIL or security BLOCK → `git
|
||||||
|
restore .` to the pre-flight SHA + STOP + escalate to `/bugfix`; hotfix
|
||||||
|
never loops. No verifier is dispatched at hotfix weight.
|
||||||
|
- If root cause is unclear → escalate to `/bugfix` (STEP 1).
|
||||||
|
- If fix touches >5 lines of logic → reconsider if this is
|
||||||
|
truly a hotfix.
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|||||||
|
|
||||||
# ORCHESTRATOR: INIT PROJECT
|
# ORCHESTRATOR: INIT PROJECT
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
## REQUEST
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
@@ -169,6 +176,12 @@ Invoke `superpowers:subagent-driven-development` for the per-task implement loop
|
|||||||
`gitflow finish` (STEP 11). When SDD's flow reaches "Use
|
`gitflow finish` (STEP 11). When SDD's flow reaches "Use
|
||||||
finishing-a-development-branch", stop and return.
|
finishing-a-development-branch", stop and return.
|
||||||
|
|
||||||
|
**Model routing (BDR-066):** every subagent dispatched under SDD — per-task
|
||||||
|
implementers AND its reviewers — MUST carry `model: "sonnet"` in the Agent
|
||||||
|
call. The plan is closed; execution and plan-conformity review are sonnet
|
||||||
|
work. Reflection (task decomposition, review verdict arbitration) stays in
|
||||||
|
this loop.
|
||||||
|
|
||||||
## STEP 8b — GRAPHIFY FULL (after implementation)
|
## STEP 8b — GRAPHIFY FULL (after implementation)
|
||||||
If `graphify` CLI is installed AND complexity >= 30%:
|
If `graphify` CLI is installed AND complexity >= 30%:
|
||||||
1. Run full graphify on the implemented project:
|
1. Run full graphify on the implemented project:
|
||||||
|
|||||||
+11
-4
@@ -7,6 +7,13 @@ allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Agent, Skill
|
|||||||
|
|
||||||
# ORCHESTRATOR: ONBOARD
|
# ORCHESTRATOR: ONBOARD
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
## REQUEST
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
@@ -347,7 +354,7 @@ Lire le bloc `audit_stack:` du fichier `~/.claude/lib/project-archetypes/<archet
|
|||||||
| Entry | Action | Livraison |
|
| Entry | Action | Livraison |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `analyze` | Déjà fait en STEP 5 | L3a |
|
| `analyze` | Déjà fait en STEP 5 | L3a |
|
||||||
| `code-clean` | Spawn subagent `code-cleaner` (audit-only) | L3a |
|
| `code-clean` | Spawn subagent `general-purpose` (audit-only, inherits session = big model) | L3a |
|
||||||
| `cso` | Si gstack ON → Skill(cso). Sinon → Agent general-purpose avec checklist OWASP + deps audit | L3a |
|
| `cso` | Si gstack ON → Skill(cso). Sinon → Agent general-purpose avec checklist OWASP + deps audit | L3a |
|
||||||
| `doc` | Spawn subagent `doc-syncer` (auto-mode OFF, report-only) | L3a |
|
| `doc` | Spawn subagent `doc-syncer` (auto-mode OFF, report-only) | L3a |
|
||||||
| `seo` | Subagents seo-analyzer + geo-analyzer en parallèle | L3b |
|
| `seo` | Subagents seo-analyzer + geo-analyzer en parallèle | L3b |
|
||||||
@@ -359,11 +366,11 @@ Lire le bloc `audit_stack:` du fichier `~/.claude/lib/project-archetypes/<archet
|
|||||||
|
|
||||||
Lancer EN PARALLÈLE (un seul message, plusieurs Agent calls) les audits correspondant aux entrées de `audit_stack:` qui sont en L3a (`code-clean`, `cso`, `doc`).
|
Lancer EN PARALLÈLE (un seul message, plusieurs Agent calls) les audits correspondant aux entrées de `audit_stack:` qui sont en L3a (`code-clean`, `cso`, `doc`).
|
||||||
|
|
||||||
#### Dispatch code-cleaner (si `code-clean` dans audit_stack)
|
#### Dispatch code-clean audit (si `code-clean` dans audit_stack)
|
||||||
```
|
```
|
||||||
Agent(
|
Agent(
|
||||||
subagent_type="code-cleaner",
|
subagent_type="general-purpose",
|
||||||
description="Onboard — code-clean audit only",
|
description="Onboard — code-clean audit only (read-only, big session model)",
|
||||||
prompt="""
|
prompt="""
|
||||||
AUDIT-ONLY mode — NO fixes, NO refactoring, NO file modifications.
|
AUDIT-ONLY mode — NO fixes, NO refactoring, NO file modifications.
|
||||||
Target: <PROJECT_ROOT>. ARCHETYPE: <archetype>.
|
Target: <PROJECT_ROOT>. ARCHETYPE: <archetype>.
|
||||||
|
|||||||
@@ -2,11 +2,19 @@
|
|||||||
name: refactor
|
name: refactor
|
||||||
description: 'Improve code quality without changing behavior — strict norm enforcement, targeted scope (file/module). Full-codebase audit+cleanup → /code-clean. Triggers: "refactor", "clean up code", "normaliser".'
|
description: 'Improve code quality without changing behavior — strict norm enforcement, targeted scope (file/module). Full-codebase audit+cleanup → /code-clean. Triggers: "refactor", "clean up code", "normaliser".'
|
||||||
argument-hint: <file, function, or module to refactor>
|
argument-hint: <file, function, or module to refactor>
|
||||||
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
|
allowed-tools: Read, Write, Edit, Grep, Glob, Bash, Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly: `$HOME/.claude/agents/refactorer.md`.
|
Dispatch the refactorer executor — behavior-preserving norm application is
|
||||||
|
closed execution, so it runs pinned on **sonnet** (not the big session
|
||||||
|
model). The scope you name is the only reflection; the agent applies norms.
|
||||||
|
|
||||||
If unreachable, emit `Refactorer agent missing.` and STOP. Never improvise — silent behavior change is unsafe.
|
```
|
||||||
|
Agent(subagent_type="refactorer")
|
||||||
|
prompt: "Refactor to strict project norms, preserving external behavior
|
||||||
|
exactly (zero behavioral regression, existing tests must pass). Target:
|
||||||
|
$ARGUMENTS"
|
||||||
|
```
|
||||||
|
|
||||||
$ARGUMENTS
|
If the refactorer agent is unavailable, emit `Refactorer agent missing.` and
|
||||||
|
STOP — never improvise, silent behavior change is unsafe.
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
---
|
---
|
||||||
name: release-candidate
|
name: release-candidate
|
||||||
description: 'Use when develop is ahead of main and you want to cut a versioned release — finalize version.txt + CHANGELOG, merge develop→main via the gitflow fan-out, tag it, and push. Triggers: "cut a release", "release candidate", "tag a version", "ship develop to main". NOT feature/bugfix integration (that is gitflow finish via /ship-feature) nor a hotfix.'
|
description: 'Use when develop is ahead of main and you want to cut a versioned release — finalize version.txt + CHANGELOG, merge develop→main via the gitflow fan-out, tag it, and push. Triggers: "cut a release", "release candidate", "tag a version", "ship develop to main". NOT feature/bugfix integration (that is gitflow finish via /ship-feature) nor a hotfix.'
|
||||||
|
allowed-tools:
|
||||||
|
- Read
|
||||||
|
- Write
|
||||||
|
- Edit
|
||||||
|
- Bash
|
||||||
|
- Grep
|
||||||
|
- Glob
|
||||||
|
- Agent
|
||||||
|
- AskUserQuestion
|
||||||
---
|
---
|
||||||
|
|
||||||
# /release-candidate — cut a gitflow release (orchestrator)
|
# /release-candidate — cut a gitflow release (orchestrator)
|
||||||
@@ -10,6 +19,14 @@ Turns the accumulated work on `develop` into a tagged release on `main`. THIN OR
|
|||||||
|
|
||||||
**Division of labour (lib = mechanic, skill = judgment):** the tag lives HERE, not in `gitflow.sh`, because it is release-specific (version + message + human decision) while the lib's fan-out is generic. **Consequence (accepted):** a release cut by calling `gitflow finish` directly, bypassing this skill, fans out but is NOT tagged — `/release-candidate` is the canonical release path.
|
**Division of labour (lib = mechanic, skill = judgment):** the tag lives HERE, not in `gitflow.sh`, because it is release-specific (version + message + human decision) while the lib's fan-out is generic. **Consequence (accepted):** a release cut by calling `gitflow finish` directly, bypassing this skill, fans out but is NOT tagged — `/release-candidate` is the canonical release path.
|
||||||
|
|
||||||
|
The two mechanical spans (prep, finish+tag) run on the sonnet-pinned
|
||||||
|
`release-executor` subagent (dispatch makes the pin effective) — no model
|
||||||
|
gate needed here, dispatch does the job. This dispatcher keeps everything
|
||||||
|
the executor must never own: the version-NUMBER decision (judgment — derives
|
||||||
|
from semver change nature), and the two human gates (when to release, and
|
||||||
|
the push). A human gate sits BETWEEN the two spans by construction, so the
|
||||||
|
executor is never dispatched twice in one call.
|
||||||
|
|
||||||
## When to use
|
## When to use
|
||||||
- `develop` is ahead of `main` and you want to publish a version.
|
- `develop` is ahead of `main` and you want to publish a version.
|
||||||
- "cut a release", "release candidate", "tag a version", "ship develop to main".
|
- "cut a release", "release candidate", "tag a version", "ship develop to main".
|
||||||
@@ -21,19 +38,71 @@ Not for: integrating a feature/bugfix → `gitflow finish` (via /ship-feature).
|
|||||||
- The number DERIVES from the change nature (semver), not the reverse: a migration-requiring/breaking change → MAJOR; new features → MINOR; fixes → PATCH. Personal repo ⇒ "breaking" = requires a migration of your own usage. Decide the number BEFORE running.
|
- The number DERIVES from the change nature (semver), not the reverse: a migration-requiring/breaking change → MAJOR; new features → MINOR; fixes → PATCH. Personal repo ⇒ "breaking" = requires a migration of your own usage. Decide the number BEFORE running.
|
||||||
|
|
||||||
## Flow
|
## Flow
|
||||||
**REQUIRED:** `lib/gitflow.sh` (the release mechanic). Clean tree, identity set, `develop` ahead of `main`.
|
**REQUIRED:** `lib/gitflow.sh` (the release mechanic, via the `release-executor` subagent). Clean tree, identity set, `develop` ahead of `main`.
|
||||||
|
|
||||||
1. **Preconditions** — clean tree, git identity, `develop` ahead of `main` (else nothing to release).
|
### STEP 1 — Preconditions
|
||||||
2. `gitflow start release <X.Y.Z>` — forks from develop, lands on `release/<X.Y.Z>`.
|
```bash
|
||||||
3. **Prep** on the release branch:
|
git status --porcelain=v1 | wc -l # 0 required — clean tree
|
||||||
- `version.txt` → `<X.Y.Z>`.
|
git config user.email # must be set
|
||||||
- CHANGELOG: `## [Unreleased]` → `## [<X.Y.Z>] — <date>`, re-open an empty `[Unreleased]`. A MAJOR must spell out its breaking change (`### Changed`/`### Removed`/BREAKING); review the doc-syncer draft for completeness.
|
git rev-list --count main..develop # 0 → nothing to release, STOP
|
||||||
- Any release-candidate fixes; commit the prep on the branch.
|
```
|
||||||
- **Run the test suite** (`lib/tests/*`, gitflow-test) — RC gate; never release red.
|
Any of these fail their check → STOP, tell the user what's blocking, dispatch nothing.
|
||||||
4. **HUMAN GATE — WHEN to release.** STOP. Proceed only on an explicit human go (mirror /ship-feature's finish gate). Never fire on "tests pass".
|
|
||||||
5. `gitflow finish` — lib fans out: merge `release/*`→`main`, merge-back→`develop`, delete the branch.
|
### STEP 2 — Version-number decision (judgment, stays HERE)
|
||||||
6. **Tag** (the piece the lib lacks): `git tag -a v<X.Y.Z> main -m "release <X.Y.Z>"` — annotated, on main's release-merge commit, AFTER finish.
|
Read the `## [Unreleased]` section of `CHANGELOG.md` and the commits on
|
||||||
7. **Push — GATED (ASK).** On explicit go only ([[LRN-069]]): `git push origin main develop && git push origin v<X.Y.Z>`.
|
`develop` since `main`. Apply the Versioning rule above (breaking → MAJOR,
|
||||||
|
features → MINOR, fixes → PATCH) and settle `<X.Y.Z>` before dispatching
|
||||||
|
anything — the executor never derives or second-guesses this number.
|
||||||
|
|
||||||
|
### STEP 3 — Dispatch: prep
|
||||||
|
```
|
||||||
|
Agent(subagent_type="release-executor")
|
||||||
|
prompt: "SPAN: prep <X.Y.Z>
|
||||||
|
<any release-candidate fixes to fold into the prep commit, or 'none'>"
|
||||||
|
```
|
||||||
|
Parse the `RELEASE-EXEC REPORT`:
|
||||||
|
- `STATUS: DONE` → continue to STEP 4, carrying the `TESTS` line forward.
|
||||||
|
- `STATUS: NEED-DECISION` → surface the exact question to the user, STOP
|
||||||
|
(don't guess the CHANGELOG wording on its behalf). Resume note: prep may
|
||||||
|
have already run `gitflow start release` (the release branch exists) — do
|
||||||
|
NOT re-dispatch `SPAN: prep` (it would BLOCK on the existing branch);
|
||||||
|
resolve the CHANGELOG on the current release branch, commit the prep, then
|
||||||
|
resume at STEP 4.
|
||||||
|
- `STATUS: BLOCKED` → surface the blocker verbatim, STOP.
|
||||||
|
|
||||||
|
### STEP 4 — HUMAN GATE: when to release
|
||||||
|
STOP. Show the prep report's `TESTS` result, then:
|
||||||
|
```
|
||||||
|
AskUserQuestion:
|
||||||
|
Release <X.Y.Z> now? (tests: <TESTS line from STEP 3>) — go / hold
|
||||||
|
```
|
||||||
|
Proceed only on an explicit human go. **Never fire on "tests pass"** — a
|
||||||
|
green suite means ready to release, not authorized to. `hold` → stop here;
|
||||||
|
the prepped `release/<X.Y.Z>` branch stays as-is for a later run.
|
||||||
|
|
||||||
|
### STEP 5 — Dispatch: finish + tag
|
||||||
|
```
|
||||||
|
Agent(subagent_type="release-executor")
|
||||||
|
prompt: "SPAN: finish <X.Y.Z>"
|
||||||
|
```
|
||||||
|
Parse the `RELEASE-EXEC REPORT`:
|
||||||
|
- `STATUS: DONE` → continue to STEP 6, carrying the `TAG` value forward.
|
||||||
|
- `STATUS: BLOCKED` → surface the blocker verbatim (e.g. a merge conflict
|
||||||
|
the fan-out hit), STOP — resolving a conflicted fan-out is a human call,
|
||||||
|
not an auto-retry.
|
||||||
|
|
||||||
|
### STEP 6 — Push GATE (ASK)
|
||||||
|
STOP. On explicit go only ([[LRN-069]]) — run the push HERE, in this
|
||||||
|
dispatcher, never delegated to the executor:
|
||||||
|
```
|
||||||
|
AskUserQuestion:
|
||||||
|
Push main, develop, and v<X.Y.Z> to origin? — go / hold
|
||||||
|
```
|
||||||
|
Go →
|
||||||
|
```bash
|
||||||
|
git push origin main develop && git push origin v<X.Y.Z>
|
||||||
|
```
|
||||||
|
`hold` → stop; the release is fanned out and tagged locally, unpushed.
|
||||||
|
|
||||||
## Common mistakes
|
## Common mistakes
|
||||||
- Tagging before `gitflow finish` → tag wouldn't sit on main's merge commit. Tag AFTER, on main.
|
- Tagging before `gitflow finish` → tag wouldn't sit on main's merge commit. Tag AFTER, on main.
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /seo — parallel SEO + GEO dispatcher
|
# /seo — parallel SEO + GEO dispatcher
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
This skill orchestrates TWO specialist agents running in parallel, then
|
This skill orchestrates TWO specialist agents running in parallel, then
|
||||||
merges their output into a single `.claude/audits/SEO.md` report. It is the main
|
merges their output into a single `.claude/audits/SEO.md` report. It is the main
|
||||||
entry point for any SEO/GEO work on a web project.
|
entry point for any SEO/GEO work on a web project.
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|||||||
|
|
||||||
# ORCHESTRATOR: SHIP FEATURE
|
# ORCHESTRATOR: SHIP FEATURE
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
## REQUEST
|
## REQUEST
|
||||||
$ARGUMENTS
|
$ARGUMENTS
|
||||||
|
|
||||||
@@ -147,6 +154,12 @@ Invoke `superpowers:subagent-driven-development` for the per-task implement loop
|
|||||||
`gitflow finish` (STEP 9). When SDD's flow reaches "Use
|
`gitflow finish` (STEP 9). When SDD's flow reaches "Use
|
||||||
finishing-a-development-branch", stop and return.
|
finishing-a-development-branch", stop and return.
|
||||||
|
|
||||||
|
**Model routing (BDR-066):** every subagent dispatched under SDD — per-task
|
||||||
|
implementers AND its reviewers — MUST carry `model: "sonnet"` in the Agent
|
||||||
|
call. The plan is closed; execution and plan-conformity review are sonnet
|
||||||
|
work. Reflection (task decomposition, review verdict arbitration) stays in
|
||||||
|
this loop.
|
||||||
|
|
||||||
## STEP 4b — ERROR RECOVERY (if STEP 4 fails)
|
## STEP 4b — ERROR RECOVERY (if STEP 4 fails)
|
||||||
If a subagent returns a build error, failing test, or type error:
|
If a subagent returns a build error, failing test, or type error:
|
||||||
1. Load `$HOME/.claude/agents/analyzer.md` in DEBUG MODE on the exact error output.
|
1. Load `$HOME/.claude/agents/analyzer.md` in DEBUG MODE on the exact error output.
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
name: status
|
name: status
|
||||||
description: 'Consolidated project snapshot — plugins, token cost, git state, recent commits, GSD v2 milestone progress. Read-only. Run at session start or after a break. Open-work reconciliation (stale TODO vs real git) → /reconcile. Triggers: "status", "sitrep", "where are we", "project state", "after break".'
|
description: 'Consolidated project snapshot — plugins, token cost, git state, recent commits, GSD v2 milestone progress. Read-only. Run at session start or after a break. Open-work reconciliation (stale TODO vs real git) → /reconcile. Triggers: "status", "sitrep", "where are we", "project state", "after break".'
|
||||||
argument-hint: (no arguments needed)
|
argument-hint: (no arguments needed)
|
||||||
allowed-tools: Read, Bash, Glob, Grep
|
allowed-tools: Read, Bash, Glob, Grep, Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Load and follow strictly:
|
Dispatch the status-reporter as a subagent so its `model: haiku` pin takes
|
||||||
- `$HOME/.claude/agents/status-reporter.md`
|
effect (read-only collection = cheapest tier, off the big session model):
|
||||||
|
|
||||||
Produce the full PROJECT STATUS report for the current working directory.
|
Agent(subagent_type="status-reporter")
|
||||||
|
prompt: "Produce the full PROJECT STATUS report for the current working
|
||||||
|
directory. $ARGUMENTS"
|
||||||
|
|
||||||
## Fallback when agent file missing
|
## Fallback when agent file missing
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -23,6 +23,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /tour — grouped multi-axis sweep (clean + security + reconcile + doc)
|
# /tour — grouped multi-axis sweep (clean + security + reconcile + doc)
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
One pipeline per project: **security → clean → re-verify → reconcile →
|
One pipeline per project: **security → clean → re-verify → reconcile →
|
||||||
doc → convergence re-audit**, looping until a full pass applies zero new
|
doc → convergence re-audit**, looping until a full pass applies zero new
|
||||||
fixes. Auto mode by design: fixes are committed on a dedicated
|
fixes. Auto mode by design: fixes are committed on a dedicated
|
||||||
@@ -104,8 +111,9 @@ honestly in the summary. Never loop past 3.
|
|||||||
|
|
||||||
### Phase B — CLEAN
|
### Phase B — CLEAN
|
||||||
|
|
||||||
1. Dispatch a read-only cleanup audit (code-cleaner agent if available,
|
1. Dispatch a read-only cleanup audit (analyzer or general-purpose —
|
||||||
else analyzer/general): dead code, unused imports/exports,
|
inherits the big session model; NOT the sonnet code-cleaner, which is
|
||||||
|
now a fix executor): dead code, unused imports/exports,
|
||||||
commented-out blocks, stale flags, norm violations. Findings as
|
commented-out blocks, stale flags, norm violations. Findings as
|
||||||
`id | file:line | finding | proposed fix`.
|
`id | file:line | finding | proposed fix`.
|
||||||
2. Apply **behavior-preserving** fixes only. A finding that would change
|
2. Apply **behavior-preserving** fixes only. A finding that would change
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ allowed-tools:
|
|||||||
|
|
||||||
# /web-validate — web standards audit (W3C + WCAG)
|
# /web-validate — web standards audit (W3C + WCAG)
|
||||||
|
|
||||||
|
## MODEL GATE (blocking — run before any other step)
|
||||||
|
|
||||||
|
Run `$HOME/.claude/lib/model-gate.md`. Reflection here (planning, audit
|
||||||
|
judgment, loop decisions) requires Fable/Opus. Verdict `small` → STOP: the
|
||||||
|
gate prints the remedy; end the turn — no later step, no dispatch. Nominal
|
||||||
|
(big) path is silent.
|
||||||
|
|
||||||
This skill orchestrates a narrow-scope standards audit :
|
This skill orchestrates a narrow-scope standards audit :
|
||||||
|
|
||||||
- **W3C HTML validity** — validator.nu API (FULL) or `html-validate` /
|
- **W3C HTML validity** — validator.nu API (FULL) or `html-validate` /
|
||||||
@@ -271,10 +278,23 @@ Options :
|
|||||||
D) Abort — keep .claude/audits/VALIDATE.md as audit report
|
D) Abort — keep .claude/audits/VALIDATE.md as audit report
|
||||||
```
|
```
|
||||||
|
|
||||||
4. On `A` : apply each bundle via `Edit` (targeted `old_string` /
|
4. On `A` : dispatch each file-group's applier at L1 (execution = sonnet;
|
||||||
`new_string`). Never use `Write` on shared templates (risk of
|
this loop only orchestrates), serially — one applier at a time, appliers
|
||||||
overwriting /seo or /geo content — meta tags, JSON-LD).
|
share files:
|
||||||
5. On `B` : for each diff, show and ask yes/no/skip.
|
|
||||||
|
```
|
||||||
|
Agent(subagent_type="hotfixer")
|
||||||
|
prompt: "<paste the file-group's bundle items: file, issue, current,
|
||||||
|
expected fix>.
|
||||||
|
Context: web-validate fix bundle, user-approved scope — no
|
||||||
|
confirmation needed. Apply via targeted Edit (old_string/new_string);
|
||||||
|
NEVER Write whole files (shared templates carry /seo and /geo
|
||||||
|
content — meta tags, JSON-LD). Do NOT commit — apply and self-verify
|
||||||
|
only."
|
||||||
|
```
|
||||||
|
|
||||||
|
5. On `B` : for each diff, show and ask yes/no/skip; apply approved diffs
|
||||||
|
as in `A` (hotfixer dispatch).
|
||||||
6. On `C` : filter to Critique + Haute, then behave as `A`.
|
6. On `C` : filter to Critique + Haute, then behave as `A`.
|
||||||
7. On `D` : stop, leave `.claude/audits/VALIDATE.md` untouched.
|
7. On `D` : stop, leave `.claude/audits/VALIDATE.md` untouched.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user