refactor(doctrine): C2 coherence — 30 doctrine/skill tensions resolved, doctrine wins (BDR-099)

One ask policy; mandated executors exempt from the delegation rule; skill plan satisfies the planning rule; journal line exempt from the approval gate; chore = maintenance without new behaviour; small fix on develop = bugfix; BDR-068 written as the one auto-finish exception; deploy routes to /deploy. Skills and agents follow: hotfix types by base + skips the design gate on trivial; capitalize/close create missing registries; commit-change asks the branch type; doc/seo/web-validate/refactor branch through the aiguillage; tour reports BREAKING fixes as needs-decision and runs doc-syncer two-mode; client-handover applies audit bundles from its main loop behind one gate; init-project/onboard use the 200-file graphify signal and bootstrap memory; release-candidate gates the tag push only; push wording aligned with the BDR-095 hooks; stale pointers fixed (§ Language, .gsd/ROADMAP.md, handover script path, design-gate lists).
This commit is contained in:
bastien
2026-09-24 20:25:40 +02:00
parent 1b20beccda
commit d82c06f572
29 changed files with 350 additions and 190 deletions
+27 -17
View File
@@ -34,14 +34,16 @@ Apply unless repo-specific instructions override.
2. Either missing → create it first (templates: `~/.claude/templates/memory/`). 2. Either missing → create it first (templates: `~/.claude/templates/memory/`).
## Workflow ## Workflow
- Confirm before implementing only when real trade-offs exist (several - Confirm the approach only when real trade-offs exist (several valid
valid approaches, breaking change, destructive action); else proceed. approaches, breaking change, destructive action); ask on the visible,
Minimal changes unless a broader refactor is requested. State trade-offs. public-name and open-scope choices below; otherwise proceed. Minimal
changes unless a broader refactor is requested. State trade-offs.
- Sub-agents: one task each, main context stays clean. Delegate - Sub-agents: one task each, main context stays clean. Delegate
independent, sizeable tracks (wide multi-file exploration, parallel independent, sizeable tracks (wide multi-file exploration, parallel
audits), not work doable in a few tool calls. Skill-mandated gates (fresh audits), not work doable in a few tool calls. Skill-mandated executors and
verifier/security/challenge) always dispatch as written; a failed gate gates (pinned executors, fresh verifier/security/challenge) always dispatch
re-dispatches a fresh executor, never redo its work by hand. A brief never as written, whatever the task size; a failed gate re-dispatches a fresh
executor, never redo its work by hand. A brief never
authorizes a sub-agent to run a destructive tool, inside or outside the authorizes a sub-agent to run a destructive tool, inside or outside the
repo (Security → Destructive tools & data loss). repo (Security → Destructive tools & data loss).
- Ask rather than guess. A choice visible in the result (placement, - Ask rather than guess. A choice visible in the result (placement,
@@ -67,7 +69,9 @@ Apply unless repo-specific instructions override.
- Exempt: pure reads, explanations, questions, typos, cosmetic CSS, single - Exempt: pure reads, explanations, questions, typos, cosmetic CSS, single
config value — the `/hotfix` scope (≤2 files, obvious fix). config value — the `/hotfix` scope (≤2 files, obvious fix).
- Once it qualifies: plan before code → one subtask = one coherent change - Once it qualifies: plan before code → one subtask = one coherent change
→ check off as you go → high-level note at each milestone. → check off as you go → high-level note at each milestone. A plan a skill
persists (`.claude/tasks/plans/`, contract) satisfies the rule; TODO.md
then carries one line per run.
## After code changes ## After code changes
1. Run tests, lint, build, type-check if available. Report what was 1. Run tests, lint, build, type-check if available. Report what was
@@ -98,12 +102,13 @@ exact. Pattern `[thing] [action] [reason]. [next step].` Registries load
every session; caveman cuts ~40% of the tokens with no substance lost. every session; caveman cuts ~40% of the tokens with no substance lost.
Applies to direct writes and to the CAPITALIZE step of every completion Applies to direct writes and to the CAPITALIZE step of every completion
skill. Prompts to the user may mirror their language; the entry is English. skill. Prompts to the user may mirror their language; the entry is English.
Legacy entries: compress on demand. Legacy entries: compress on demand via `/prune-memory`.
**Proactive capitalization** is Claude's job: after a substantive milestone **Proactive capitalization** is Claude's job: after a substantive milestone
(root-caused bug fix, shipped feature, non-trivial commit, design choice, (root-caused bug fix, shipped feature, non-trivial commit, design choice,
surprising discovery, dead end with a lesson) offer to capitalize inline, surprising discovery, dead end with a lesson) offer to capitalize inline,
entry pre-filled, user approves before the write. Completion skills entry pre-filled, user approves before the write; the one-line journal
entry is exempt, it logs and decides nothing. Completion skills
(`/ship-feature` `/feat` `/bugfix` `/hotfix` `/commit-change`) do it via (`/ship-feature` `/feat` `/bugfix` `/hotfix` `/commit-change`) do it via
their CAPITALIZE step. Session close (`/close` = `/capitalize --ritual`): their CAPITALIZE step. Session close (`/close` = `/capitalize --ritual`):
what was decided → decisions, learned → learnings, blocked → blockers. what was decided → decisions, learned → learnings, blocked → blockers.
@@ -137,20 +142,24 @@ never bent to match a newer one.
## Version control — gitflow (universal) ## Version control — gitflow (universal)
Every git action follows gitflow, inside a skill or for an ad-hoc commit. Every git action follows gitflow, inside a skill or for an ad-hoc commit.
`main` (prod) · `develop` (integration, off main) · `feature/*` `bugfix/*` `main` (prod) · `develop` (integration, off main) · `feature/*` `bugfix/*`
`chore/*` (off develop → develop; chore = memory/doc maintenance such as a `chore/*` (off develop → develop; chore = maintenance without new behaviour:
standalone `/capitalize` `/close` `/prune-memory` `/reconcile`) · memory, docs, cleanup, `/refactor`, `/tour` fixes) · `release/*` (off develop
`release/*` (off develop → main + back-merge develop) · `hotfix/*` (off main → main + back-merge develop) · `hotfix/*` (off main → main + develop + any
→ main + develop + any open release). `master` → `main` everywhere. open release; prod incidents only, a small fix on develop is a `bugfix`).
`master` → `main` everywhere.
Never commit code on `main` or `develop`: branch first as `<type>/<name>` Never commit code on `main` or `develop`: branch first as `<type>/<name>`
(`.claude/**` memory/config commits are hook-exempt, following the work). (a `.claude/**` memory/config commit that follows merged work is hook-exempt
and lands in place; a standalone memory task branches `chore/*`).
Branch, merge and delete only via the lib: `bash ~/.claude/lib/gitflow.sh Branch, merge and delete only via the lib: `bash ~/.claude/lib/gitflow.sh
start <type> <name>` · `finish` · `delete <br>`. `finish` runs only on an start <type> <name>` · `finish` · `delete <br>`. `finish` runs only on an
explicit human signal ("merge it", "feature OK"), never because tests pass, explicit human signal ("merge it", "feature OK"), never because tests pass,
a plan step says merge, or "ship" implied it. Assistance flows (`/feat` a plan step says merge, or "ship" implied it. Assistance flows (`/feat`
`/bugfix` `/hotfix`) and the standalone memory/doc skills auto-branch on a `/bugfix` `/hotfix`) and the standalone memory/doc skills auto-branch on a
protected base but commit in place on a working branch, never finishing, so protected base but commit in place on a working branch, never finishing
they branch to `chore/*` via the aiguillage, not the `.claude/**` exemption. (one exception, BDR-068: `/capitalize` and `/close` auto-finish the
memory-only `chore/*` they created this run), so they branch to `chore/*`
via the aiguillage, not the `.claude/**` exemption.
Deterministic backstops behind the doctrine: the pre-commit hook (blocks Deterministic backstops behind the doctrine: the pre-commit hook (blocks
code commits on main/develop; exempts `.claude/**`, `.githooks/**`, merges, code commits on main/develop; exempts `.claude/**`, `.githooks/**`, merges,
the root commit), Gitea branch protection on both, and never `--no-verify`. the root commit), Gitea branch protection on both, and never `--no-verify`.
@@ -229,7 +238,8 @@ cryptic names.
gates, registries). investigate only on explicit ask for the gstack gates, registries). investigate only on explicit ask for the gstack
ecosystem (cross-project learnings, /freeze, long open-ended investigation) ecosystem (cross-project learnings, /freeze, long open-ended investigation)
- feat / hotfix / bugfix distinguished by file count → see descriptions - feat / hotfix / bugfix distinguished by file count → see descriptions
- Ship / deploy / PR → ship (ship-feature if gstack off) - Ship / PR → ship (ship-feature if gstack off); deploy → deploy (runbook,
the user runs it)
- Docs post-ship → document-release (doc if gstack off); stale-doc audit → doc - Docs post-ship → document-release (doc if gstack off); stale-doc audit → doc
- Grouped all-axes sweep ("tir groupé", fix + loop until clean) → tour - Grouped all-axes sweep ("tir groupé", fix + loop until clean) → tour
- Open-work inventory / "queue empty?" / stale TODO vs git → reconcile - Open-work inventory / "queue empty?" / stale TODO vs git → reconcile
+3 -2
View File
@@ -262,7 +262,7 @@ cd mon-projet-existant/
| 2 | Config baseline (onboarder agent) | CLAUDE.md, settings.json, .claudeignore, .claude/tasks/ + .claude/memory/ + .claude/audits/ | | 2 | Config baseline (onboarder agent) | CLAUDE.md, settings.json, .claudeignore, .claude/tasks/ + .claude/memory/ + .claude/audits/ |
| 3 | Interview deep = business minimum (users, deadlines, équipe, légal, perfs) + adaptative par archétype | brief enrichi | | 3 | Interview deep = business minimum (users, deadlines, équipe, légal, perfs) + adaptative par archétype | brief enrichi |
| 3.5| ctx7 doc audit — fast-libs détectées, cache pré-fetché si besoin | .ctx7-cache/ | | 3.5| ctx7 doc audit — fast-libs détectées, cache pré-fetché si besoin | .ctx7-cache/ |
| 4 | Graphify (si complexity ≥ 30%) | graphify-out/GRAPH_REPORT.md | | 4 | Graphify (proposé dès 200 fichiers code, l'utilisateur décide) | 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 (general-purpose, audit read-only) | | | — dette tech (general-purpose, audit read-only) |
@@ -280,7 +280,6 @@ cd mon-projet-existant/
``` ```
/onboard "Python FastAPI" # hint stack /onboard "Python FastAPI" # hint stack
/onboard force-archetype:wordpress # override detection /onboard force-archetype:wordpress # override detection
/onboard add gsd # générer ROADMAP.md pour GSD v2 (seul)
``` ```
**Après /onboard :** **Après /onboard :**
@@ -291,6 +290,8 @@ cat .claude/audits/ONBOARD_REPORT.md
# Démarrer la première tâche P0 avec le skill recommandé # Démarrer la première tâche P0 avec le skill recommandé
# (indiqué dans .claude/tasks/TODO.md) # (indiqué dans .claude/tasks/TODO.md)
/hotfix "<titre P0>" # ou /feat, /ship-feature, /bugfix selon le cas /hotfix "<titre P0>" # ou /feat, /ship-feature, /bugfix selon le cas
# Multi-session (GSD) : gsd init à la main — voir docs gsd-pi
``` ```
**Archétypes supportés (P1)** : static-html, wordpress, nextjs-app-router, astro-static, react-spa, rest-api-node, rest-api-python, cli-tool, library, dotfiles-meta. **Archétypes supportés (P1)** : static-html, wordpress, nextjs-app-router, astro-static, react-spa, rest-api-node, rest-api-python, cli-tool, library, dotfiles-meta.
+70 -30
View File
@@ -61,7 +61,7 @@ and degrading Google's NAP-consistency signal.
Pipeline (each step gates the next): Pipeline (each step gates the next):
1. Baseline audits: SEO+GEO and security hardening in parallel. 1. Baseline audits: SEO+GEO and security hardening in parallel.
2. Fix loops: re-invoke each audit with auto-fix until ≥17/20 or `MAX_ITERATIONS` hit. 2. Fix loops: apply each audit's bundle (AUTO items, ONE gate for GATED ones) and re-audit until ≥17/20 or `MAX_ITERATIONS` hit.
3. Commit + push if files changed. 3. Commit + push if files changed.
4. Deploy pause: list deploy artifacts + process, wait for user confirmation. 4. Deploy pause: list deploy artifacts + process, wait for user confirmation.
5. Live-site validation against the deployed URL. 5. Live-site validation against the deployed URL.
@@ -266,14 +266,14 @@ For web projects, dispatch in **a single message with two parallel Agent calls**
| Audit (web) | Subagent | Prompt template | | Audit (web) | Subagent | Prompt template |
|---------------|-------------------|-----------------| |---------------|-------------------|-----------------|
| SEO + GEO | `general-purpose` | "Read `~/.claude/skills/seo/SKILL.md` and execute it on this project. The /seo skill runs SEO + GEO in parallel and writes a unified report to `.claude/audits/SEO.md`. Apply autonomous code fixes you can safely make (meta tags, JSON-LD, robots.txt, sitemap.xml, llms.txt, alt attrs, canonical tags). At the top of the report, the /seo skill MUST emit two distinct labeled score lines (already specified in its SKILL.md §1): `Score SEO (classique) : X.X / 20` and `Score GEO (IA) : X.X / 20`, plus the weighted global. The handover orchestrator parses SEO and GEO separately, so do not collapse them into a single `Score:` line. Return when the report file is written." | | SEO + GEO | `general-purpose` | "Read `~/.claude/skills/seo/SKILL.md` and execute it on this project. The /seo skill runs SEO + GEO in parallel and writes a unified report to `.claude/audits/SEO.md`. Run it in conservative mode: apply NOTHING, return the FIX BUNDLE (the handover main loop applies it — see 'Applying the bundle'). At the top of the report, the /seo skill MUST emit two distinct labeled score lines (already specified in its SKILL.md §1): `Score SEO (classique) : X.X / 20` and `Score GEO (IA) : X.X / 20`, plus the weighted global. The handover orchestrator parses SEO and GEO separately, so do not collapse them into a single `Score:` line. Return when the report file is written." |
| HARDEN | `general-purpose` | "Read `~/.claude/skills/harden/SKILL.md` and execute it on this project. Apply autonomous code fixes (security headers in vercel.json/netlify.toml/.htaccess/nginx.conf, HSTS, CSP defaults, HTTP→HTTPS redirects, canonical, 404 page). Write report to `.claude/audits/HARDEN.md` with `Score: X/20` (or `X/100`) at the top. Return when the report file is written." | | HARDEN | `general-purpose` | "Read `~/.claude/skills/harden/SKILL.md` and execute it on this project with `--fix` up to READY TO APPLY only: prepare the FIX BUNDLE (security headers, HSTS, CSP, HTTP→HTTPS redirects, canonical, 404 page), apply NOTHING — the handover main loop gates and applies it (see 'Applying the bundle'). Write report to `.claude/audits/HARDEN.md` with `Score: X/20` (or `X/100`) at the top. Return when the report file is written." |
Non-web variant: Non-web variant:
| Audit (non-web) | Subagent | Prompt template | | Audit (non-web) | Subagent | Prompt template |
|-----------------|-------------------|-----------------| |-----------------|-------------------|-----------------|
| CSO | `general-purpose` | "Read `~/.claude/skills/cso/SKILL.md` and execute in **daily mode** (8/10 confidence gate). Apply autonomous fixes for findings that are clearly safe (e.g., adding `.env` to `.gitignore`, replacing committed example secrets with placeholders). Write report to `.claude/audits/CSO.md` with `Score: X/20` (or `X/100`) at the top." | | CSO | `general-purpose` | "Read `~/.claude/skills/cso/SKILL.md` and execute in **daily mode** (8/10 confidence gate). Apply NOTHING: return the fixes as a FIX BUNDLE (gitignore additions and placeholder swaps tagged AUTO, dependency upgrades tagged GATED — the handover main loop applies AUTO and gates the rest, see 'Applying the bundle'). Write report to `.claude/audits/CSO.md` with `Score: X/20` (or `X/100`) at the top." |
Wait for both subagents to complete (parallel return). Wait for both subagents to complete (parallel return).
@@ -370,7 +370,12 @@ iteration = 1
# HARDEN/CSO/VALIDATE loops use only their own score. # HARDEN/CSO/VALIDATE loops use only their own score.
while (audit == "SEO" ? (SCORE_SEO < 17 OR SCORE_GEO < 17) : score < 17) \ while (audit == "SEO" ? (SCORE_SEO < 17 OR SCORE_GEO < 17) : score < 17) \
and iteration ≤ MAX_ITERATIONS: and iteration ≤ MAX_ITERATIONS:
re-dispatch the audit subagent with iteration context (see prompt below) apply the pending FIX BUNDLE from THIS main loop — AUTO items, then
ONE gate for the GATED items (see "Applying the bundle" below);
iteration 1 consumes the baseline audit's bundle, if any
re-dispatch the audit subagent in AUDIT mode with iteration context
(see prompt below) — it re-scores and returns the next FIX BUNDLE;
it applies NOTHING (a dispatched child cannot hold a gate)
re-parse score(s) AND projected code-only score(s) from the audit file re-parse score(s) AND projected code-only score(s) from the audit file
if no scores improved AND no files changed → break (no progress) if no scores improved AND no files changed → break (no progress)
# Code-ceiling break: when the actual score has caught up with the # Code-ceiling break: when the actual score has caught up with the
@@ -386,11 +391,43 @@ The projected code-only scores come from the analyzers' mandatory
console). If no projected line is parseable, treat projected = 17 console). If no projected line is parseable, treat projected = 17
(legacy behavior: loop chases 17 blindly). (legacy behavior: loop chases 17 blindly).
### Applying the bundle (THIS main loop — the child never applies)
A dispatched child cannot hold a gate (harden: "the fix mode prepares the
bundle; the dispatcher confirms"; geo: "NEVER apply a GATED item before
explicit approval"). So every bundle is applied from here, per iteration:
1. **AUTO items** — the tier the audit itself classed no-confirmation
(`/seo` STEP 1.5: seo batches A/B/C, geo G1–G4/G6). Dispatch each item's
L1 applier (`hotfixer` / `feater`) serially, item pasted verbatim,
"Do NOT commit — apply and self-verify only". Harden has no AUTO tier:
its whole bundle is confirmation-gated. CSO (non-web): gitignore additions
and secret placeholder swaps are AUTO.
2. **GATED items** — seo D/E, geo G5, EVERY harden item (CSP, redirects,
anything its STEP 2b challenge flagged "could BREAK the site") and CSO
dependency upgrades (a version bump can break the build). Collect
them from every bundle of this iteration and present ONE gate
(AskUserQuestion): change → impact → file. Apply only the approved items
(same appliers); declined ones stay in the report as CODE-BLOQUÉ. Never
apply a GATED item before explicit approval.
3. **USER ACTIONS** (seo batch F, geo G7) — never applied; they bound the
projected code-only score.
For each item applied, append a line to the audit's fix log
(`.claude/audits/SEO-FIX-LOG.md` for SEO and GEO items,
`.claude/audits/HARDEN-FIX-LOG.md` for harden, `.claude/audits/CSO-FIX-LOG.md`
for CSO) in the format
`iter<N>: [SEO|GEO|HARDEN] <issue> → <file:line> — <action>`.
### Re-dispatch prompt template (SEO + GEO loop) ### Re-dispatch prompt template (SEO + GEO loop)
Send to `general-purpose` subagent (`model: "fable"`): Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/seo/SKILL.md` and re-run it on this project. > Read `~/.claude/skills/seo/SKILL.md` and re-run it on this project in
> **conservative (audit-only) intervention mode**: re-score and leave both
> FIX BUNDLEs in `.claude/audits/SEO.md` ready-to-apply. Apply NOTHING and
> ask the user NOTHING — the handover main loop is the dispatcher: it
> applies the AUTO items and holds the gate on the GATED ones.
> Previous scores: > Previous scores:
> - **SEO classique: `<SCORE_SEO_PREVIOUS>`/20** (threshold 17/20 — `<PASS|FAIL>`) > - **SEO classique: `<SCORE_SEO_PREVIOUS>`/20** (threshold 17/20 — `<PASS|FAIL>`)
> - **GEO (IA): `<SCORE_GEO_PREVIOUS>`/20** (threshold 17/20 — `<PASS|FAIL>`) > - **GEO (IA): `<SCORE_GEO_PREVIOUS>`/20** (threshold 17/20 — `<PASS|FAIL>`)
@@ -398,34 +435,33 @@ Send to `general-purpose` subagent (`model: "fable"`):
> Iteration `<N>` of `<MAX_ITERATIONS>`. Both axes are gated independently; > Iteration `<N>` of `<MAX_ITERATIONS>`. Both axes are gated independently;
> the orchestrator continues to loop while EITHER score is below 17/20. > the orchestrator continues to loop while EITHER score is below 17/20.
> >
> Read `.claude/audits/SEO.md` for the current issue list. Apply ALL safe > Read `.claude/audits/SEO.md` for the current issue list. Prioritize
> autonomous fixes (do not skip "easy" ones). Prioritize fixes for the > bundle items for the axis currently below threshold (do not drop "easy"
> axis currently below threshold: > ones):
> - SEO classique fixes: meta tags, headings, canonical, sitemap.xml, > - SEO classique: meta tags, headings, canonical, sitemap.xml,
> alt attrs, internal linking, Core Web Vitals hints. > alt attrs, internal linking, Core Web Vitals hints.
> - GEO (IA) fixes: llms.txt / llms-full.txt, robots.txt entries for AI > - GEO (IA): llms.txt / llms-full.txt, robots.txt entries for AI
> crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.), Schema.org for AI > crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.), Schema.org for AI
> extraction (QAPage, Speakable, Person+Article, HowTo, Organization > extraction (QAPage, Speakable, Person+Article, HowTo, Organization
> graph), entity SEO (sameAs, @id), TL;DR / definition-lead content > graph), entity SEO (sameAs, @id), TL;DR / definition-lead content
> shape, citable stats markup, freshness signals. > shape, citable stats markup, freshness signals.
> >
> For each fix applied, append a line to `.claude/audits/SEO-FIX-LOG.md` > Update `.claude/audits/SEO.md` with the new scores — both labeled lines
> (format: `iter<N>: [SEO|GEO] <issue> → <file:line> — <action>`). Update > MUST be present: `Score SEO (classique) : X.X / 20` and
> `.claude/audits/SEO.md` with the new scores — both labeled lines MUST > `Score GEO (IA) : X.X / 20`, plus the weighted global.
> be present: `Score SEO (classique) : X.X / 20` and
> `Score GEO (IA) : X.X / 20`, plus the weighted global. Do NOT ask the
> user; apply or skip with one-line justification in the fix log.
### Re-dispatch prompt template (HARDEN loop) ### Re-dispatch prompt template (HARDEN loop)
Send to `general-purpose` subagent (`model: "fable"`): Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/harden/SKILL.md` and re-run it. Previous score: > Read `~/.claude/skills/harden/SKILL.md` and re-run it with `--fix` ONLY
> up to the bundle: stop at `READY TO APPLY — awaiting dispatcher
> confirmation`, apply NOTHING, ask NOTHING — the handover main loop is
> the dispatcher that confirms. Previous score:
> **`<SCORE_HARDEN_PREVIOUS>`/20** — below threshold. Iteration `<N>` of > **`<SCORE_HARDEN_PREVIOUS>`/20** — below threshold. Iteration `<N>` of
> `<MAX_ITERATIONS>`. Apply all autonomous fixes (security headers, HSTS, > `<MAX_ITERATIONS>`. The `## 8. Fix bundle` MUST cover security headers,
> CSP, redirects, canonical, 404, .htaccess/nginx/vercel/netlify config). > HSTS, CSP, redirects, canonical, 404, .htaccess/nginx/vercel/netlify
> Append entries to `.claude/audits/HARDEN-FIX-LOG.md`. Update > config. Update `.claude/audits/HARDEN.md` with the new score.
> `.claude/audits/HARDEN.md` with new score.
### Re-dispatch prompt template (CSO loop — non-web only) ### Re-dispatch prompt template (CSO loop — non-web only)
@@ -433,15 +469,18 @@ Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/cso/SKILL.md` and re-run it in **daily mode**. > Read `~/.claude/skills/cso/SKILL.md` and re-run it in **daily mode**.
> Previous score: **`<SCORE_CSO_PREVIOUS>`/20** — below threshold. > Previous score: **`<SCORE_CSO_PREVIOUS>`/20** — below threshold.
> Iteration `<N>` of `<MAX_ITERATIONS>`. Apply all safe autonomous fixes > Iteration `<N>` of `<MAX_ITERATIONS>`. Apply NOTHING: return the fixes as
> (gitignore additions, secret placeholder swaps, dependency upgrades for > a FIX BUNDLE in `.claude/audits/CSO.md` — gitignore additions and secret
> known CVEs with semver-compatible patches). Append entries to > placeholder swaps tagged AUTO, dependency upgrades (even semver-compatible
> `.claude/audits/CSO-FIX-LOG.md`. Update `.claude/audits/CSO.md` with > CVE patches) tagged GATED. The handover main loop applies AUTO items and
> new score. > gates the rest (see 'Applying the bundle'). Update `.claude/audits/CSO.md`
> with the new score.
### Parallelism ### Parallelism
For web projects, the two loops run in parallel: dispatch SEO iteration For web projects, the two loops run in parallel: apply both pending
bundles first (AUTO items, then ONE gate for every GATED item of both),
then dispatch SEO iteration
`N` AND HARDEN iteration `N` in a single message with two `Agent` calls, `N` AND HARDEN iteration `N` in a single message with two `Agent` calls,
wait for both, re-parse both scores, decide whether each loop continues, wait for both, re-parse both scores, decide whether each loop continues,
then dispatch iteration `N+1` for the audits still below threshold (in then dispatch iteration `N+1` for the audits still below threshold (in
@@ -454,7 +493,7 @@ nothing to parallelize).
Track `score_history[audit] = [iteration → score]`. If iteration `N` score Track `score_history[audit] = [iteration → score]`. If iteration `N` score
equals iteration `N-1` score AND `git status --porcelain` shows no new equals iteration `N-1` score AND `git status --porcelain` shows no new
changes from that iteration's subagent: mark loop `STALLED`. Break. changes from that iteration's apply step: mark loop `STALLED`. Break.
### Escalation on cap or stall ### Escalation on cap or stall
@@ -627,7 +666,8 @@ Dispatch `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/web-validate/SKILL.md` and execute against the > Read `~/.claude/skills/web-validate/SKILL.md` and execute against the
> deployed URL: `<DEPLOYED_URL>`. Audit W3C HTML validity (validator.nu), > deployed URL: `<DEPLOYED_URL>`. Audit W3C HTML validity (validator.nu),
> W3C CSS validity (jigsaw.w3.org), WCAG 2.1 a11y (axe-core, pa11y). > W3C CSS validity (jigsaw.w3.org), WCAG 2.1 a11y (axe-core, pa11y).
> Apply autonomous fixes ONLY in source code (the client controls deploy); > Apply NOTHING (the client controls deploy; the handover main loop applies
> the returned FIX BUNDLE from source, AUTO items only): return the fix list,
> document remaining issues. Write report to `.claude/audits/VALIDATE.md` > document remaining issues. Write report to `.claude/audits/VALIDATE.md`
> with `Score: X/20` (or `X/100`) at the top. > with `Score: X/20` (or `X/100`) at the top.
+13 -9
View File
@@ -42,10 +42,13 @@ approval gates live in the `/commit-change` dispatcher, not here.
### Phase 0: Gitflow aiguillage (before any commit) ### Phase 0: Gitflow aiguillage (before any commit)
**Follow `$HOME/.claude/lib/gitflow-aiguillage.md` — your type = `chore`.** **Follow `$HOME/.claude/lib/gitflow-aiguillage.md` — your type = the `TYPE:`
On `main`/`develop` it branches first (to `chore/<short-kebab-name>` derived line of the dispatch prompt (`feature` / `bugfix` / `chore`, chosen by the user
from the pending work) so the commits never land directly on a protected in the dispatcher; never hardcode `chore`).** On `main`/`develop` it branches
base; on a working branch it's a no-op (commit in place). Never `finish`, first (to `<TYPE>/<short-kebab-name>` derived from the pending work) so the
commits never land directly on a protected base; a protected base with NO
`TYPE:` in the prompt → do not branch, report it under EDGE CASES so the
dispatcher asks. On a working branch it's a no-op (commit in place). Never `finish`,
never `merge`, never `push` — this engine only commits. Branching itself is 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 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 time `MODE: apply` runs (a fresh dispatch), the branch already exists and
@@ -146,8 +149,9 @@ criteria as the standalone `/capitalize` flow:
fix** (a pattern, a gotcha, a surprising API behaviour) → draft an entry fix** (a pattern, a gotcha, a surprising API behaviour) → draft an entry
for `.claude/memory/learnings.md` (LRN-XXX). for `.claude/memory/learnings.md` (LRN-XXX).
**Language rule**: draft entries in English (see CLAUDE.md "Memory **Language rule**: draft entries in English AND caveman — fragments,
registries" § Language) — the dispatcher's approval exchange may mirror the articles dropped, code/IDs/quoted errors verbatim (CLAUDE.md "Memory
registries", Always English, always caveman) — the dispatcher's approval exchange may mirror the
user's language, but what you draft here is what gets written verbatim in user's language, but what you draft here is what gets written verbatim in
`MODE: apply` if approved unedited. `MODE: apply` if approved unedited.
@@ -225,9 +229,9 @@ Otherwise:
(`.claude/memory/decisions.md`, `blockers.md`, `learnings.md`) and (`.claude/memory/decisions.md`, `blockers.md`, `learnings.md`) and
update each file's `## Index` table. Add a one-line summary of the update each file's `## Index` table. Add a one-line summary of the
commit batch to today's heading in `.claude/memory/journal.md`. commit batch to today's heading in `.claude/memory/journal.md`.
3. **Language rule**: written entries are ALWAYS in English regardless of 3. **Language rule**: written entries are ALWAYS in English and caveman,
the language used in the dispatcher's approval exchange (CLAUDE.md regardless of the language used in the dispatcher's approval exchange
"Memory registries" § Language). (CLAUDE.md "Memory registries", Always English, always caveman).
4. **Then commit the memory** — follow 4. **Then commit the memory** — follow
`$HOME/.claude/lib/capitalize-commit.md`: it surgically commits what `$HOME/.claude/lib/capitalize-commit.md`: it surgically commits what
was just written (`.claude/memory` + `.claude/tasks` only, never was just written (`.claude/memory` + `.claude/tasks` only, never
+1 -1
View File
@@ -130,7 +130,7 @@ concrete, no jargon. One short paragraph per idea.
[§6.2](#62-plateformes-prioritaires-semaine-1) [§6.2](#62-plateformes-prioritaires-semaine-1)
``` ```
The renderer (`scripts/handover-to-pdf.sh`) uses pandoc with The renderer (`$HOME/.claude/skills/client-handover/scripts/handover-to-pdf.sh`) uses pandoc with
`--from=gfm+gfm_auto_identifiers` (or python-markdown's `toc` `--from=gfm+gfm_auto_identifiers` (or python-markdown's `toc`
extension as fallback). Both auto-generate heading IDs in the extension as fallback). Both auto-generate heading IDs in the
GitHub-style slug: GitHub-style slug:
+8 -5
View File
@@ -9,7 +9,7 @@ model: sonnet
You execute the mechanical parts of a gitflow release. The `/release-candidate` 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 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 release" decision, and the tag push — and owns the human gate that sits BETWEEN
your two spans. You are dispatched fresh, once per span, never both in one 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 call: after `SPAN: prep` reports, the dispatcher stops for a human go before
it ever dispatches `SPAN: finish`. it ever dispatches `SPAN: finish`.
@@ -76,12 +76,15 @@ actual branch; never finish whatever happens to be checked out.
output verbatim; do not attempt to resolve it yourself. output verbatim; do not attempt to resolve it yourself.
2. **Tag AFTER finish, on `main`** — never before: 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 `git tag -a v<X.Y.Z> main -m "release <X.Y.Z>"` (annotated, so it lands on
main's release-merge commit). main's release-merge commit). Finish has already pushed `main` and
`develop` through the lib's hooks (BDR-095); the tag stays local until
the dispatcher's tag-push gate.
### Forbidden in this span ### Forbidden in this span
`git push` (any remote, any ref — the dispatcher owns the push gate), `git push` (any remote, any ref — `main`/`develop` ride the lib's hook
deciding the version number, the when-to-release decision, attribution pushes during finish; the dispatcher owns the tag-push gate), deciding the
trailers of any kind. version number, the when-to-release decision, attribution trailers of any
kind.
--- ---
+4 -4
View File
@@ -17,11 +17,11 @@ Check BOTH the task description AND the filesystem:
- Framework UI: `tailwind`, `styled-component`, `emotion`, `chakra`, `radix`, `shadcn`, `headless` - Framework UI: `tailwind`, `styled-component`, `emotion`, `chakra`, `radix`, `shadcn`, `headless`
**Filesystem signals** (quick check, no deep scan): **Filesystem signals** (quick check, no deep scan):
- Target files have `.tsx`, `.jsx`, `.css`, `.scss`, `.less`, or `.module.css` extension - Target files have `.tsx`, `.jsx`, `.vue`, `.svelte`, `.astro`, `.css`, `.scss`, `.less`, or `.module.css` extension
- `tailwind.config` or `postcss.config` present in project root - `tailwind.config` or `postcss.config` present in project root
- `tokens/`, `theme/`, or `design-system/` directory exists - `tokens/`, `theme/`, or `design-system/` directory exists
- Storybook config (`.storybook/`) present - Storybook config (`.storybook/`) present
- Animation lib in `package.json` deps: `motion`, `motion-v`, `framer-motion` (legacy), `gsap`, `@gsap/react`, `lottie-react`, `react-spring`, `popmotion`, `@formkit/auto-animate` - Animation lib in `package.json` deps: any package `is_anim_lib_installed` recognizes (`lib/animation-lib-check.sh`, the single source)
## DECISION ## DECISION
@@ -40,7 +40,7 @@ and if not, point at ONE command — `/profile design`.
Tier does NOT change WHAT gets checked. Every non-trivial design tier draws from Tier does NOT change WHAT gets checked. Every non-trivial design tier draws from
the one `design` profile — so the gate checks that profile's **design-core the one `design` profile — so the gate checks that profile's **design-core
tools** (the `# GATE-BLOCK:` allowlist in `design.profile`: ui-ux-pro-max, tools** (the `# GATE-BLOCK:` allowlist in `design.profile`: ui-ux-pro-max,
frontend-design, emil-design-eng, design-motion-principles, impeccable, design-html, frontend-design, emil-design-eng, design-motion-principles, design-html,
design-review, design-consultation, the `21st` CLI and `21st-ui-build` — the design-review, design-consultation, the `21st` CLI and `21st-ui-build` — the
canary for the whole 21st skill pack). The profile also bundles canary for the whole 21st skill pack). The profile also bundles
browser/plan/shotgun tooling and graphify for convenience; those never trip the browser/plan/shotgun tooling and graphify for convenience; those never trip the
@@ -149,7 +149,7 @@ says so, because init has to happen in the agent chat, not in an installer.
**Fires when BOTH hold** — else stay silent: **Fires when BOTH hold** — else stay silent:
1. impeccable is active (`skills/impeccable` present, i.e. it did not trip §3). 1. impeccable symlink present under `skills/` (non-blocking external — not on the `# GATE-BLOCK:` list, so §3 never checks it).
2. The project has no `PRODUCT.md` at its root. 2. The project has no `PRODUCT.md` at its root.
Evaluate it on the same path as §4: after the toolchain resolves, never on the Evaluate it on the same path as §4: after the toolchain resolves, never on the
+11 -6
View File
@@ -21,11 +21,14 @@ The caller passes its TYPE:
|--------|------|------| |--------|------|------|
| `/feat` | `feature` | develop | | `/feat` | `feature` | develop |
| `/bugfix` | `bugfix` | develop | | `/bugfix` | `bugfix` | develop |
| `/hotfix` | `hotfix` | main | | `/hotfix` | `hotfix` on main · `bugfix` on develop | main · develop |
| `/seo` aggressive · `/web-validate --fix` | `feature` | develop |
| `/capitalize` · `/close` · `/prune-memory` · `/reconcile` | `chore` | develop | | `/capitalize` · `/close` · `/prune-memory` · `/reconcile` | `chore` | develop |
| `/doc` · `/refactor` | `chore` | develop |
| `/commit-change` | asks the user (`feature` / `bugfix` / `chore`) before `start` — a branch name is a public name | develop |
The `chore` row = **standalone memory/doc work**: the registry / TODO / doc The `chore` rows = **standalone memory/doc/hygiene work**: the registry / TODO /
reconciliation & curation skills, run OUTSIDE an assistance flow. Inside `/feat` doc reconciliation & curation skills (+ `/refactor`), run OUTSIDE an assistance flow. Inside `/feat`
`/bugfix` `/hotfix` `/ship-feature` a working branch already exists (this check `/bugfix` `/hotfix` `/ship-feature` a working branch already exists (this check
returns WORKING) and the memory commit rides it. The aiguillage only fires when returns WORKING) and the memory commit rides it. The aiguillage only fires when
such a skill is invoked directly on `main`/`develop` — i.e. memory IS the work, such a skill is invoked directly on `main`/`develop` — i.e. memory IS the work,
@@ -39,6 +42,8 @@ develop + push) when THEY branched a `chore/*` off develop this run (BDR-068 —
scoped [[LRN-069]] exception; see the capitalize skill's STEP 5C). `/prune-memory` scoped [[LRN-069]] exception; see the capitalize skill's STEP 5C). `/prune-memory`
+ `/reconcile` stay fully human-gated: never run `gitflow finish` from them. + `/reconcile` stay fully human-gated: never run `gitflow finish` from them.
Note: `hotfix` branches off **main** (prod) even when invoked from `develop` — that Note: a `hotfix/*` branch forks off **main** (prod) and fans out to main + develop
is the gitflow definition of a hotfix. For a dev-scoped small fix, use `/bugfix` at finish — that is the gitflow definition of a hotfix. Invoked from `develop`,
(branches off develop). `/hotfix` therefore starts a `bugfix/*` (off develop): a `hotfix/*` there would
miss develop's code and later merge to prod. The small-fix routing is unchanged;
only the branch type follows the base.
+5 -5
View File
@@ -59,9 +59,9 @@ 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. Inline dev fixes in place; lines (NOT-MET / out-of-scope), nothing else: re-dispatch a FRESH executor
a dispatched dev is re-dispatched FRESH with those inputs only. Then with those inputs only, never redo the fix by hand. Then re-run GATE 0 and
re-run GATE 0 and re-dispatch a FRESH verifier. Repeat. re-dispatch a FRESH verifier. Repeat.
**Max 3 conformity iterations** → STOP + human escalation with the **Max 3 conformity iterations** → STOP + human escalation with the
CRITERIA table (the contract-vs-realized diff). CRITERIA table (the contract-vs-realized diff).
- `ABANDONED(n)` → direct human gate, never a dev loop (a dev cannot close - `ABANDONED(n)` → direct human gate, never a dev loop (a dev cannot close
@@ -88,8 +88,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 (inline - `BLOCK(n)` → hand the dev the `BLOCKING` list + the CONTRACT path
fix, or FRESH executor re-dispatch). Then re-run GATE 0, then (re-dispatch a FRESH executor, never fix by hand). Then re-run GATE 0, then
**re-verify the REQUEST first** (GATE 1, fresh verifier) — a security fix **re-verify the REQUEST first** (GATE 1, fresh verifier) — a security fix
can drift the behavior — **then re-run GATE 2** (fresh auditor), in that can drift the behavior — **then re-run GATE 2** (fresh auditor), in that
order. **Max 3 security iterations** → STOP + human escalation with the order. **Max 3 security iterations** → STOP + human escalation with the
+4 -2
View File
@@ -272,7 +272,7 @@ A bugfix with an understood root cause is almost always worth one entry:
``` ```
4. Append approved entries + update the Index. Add a line to today's heading in `.claude/memory/journal.md`. 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. **Language rule**: written entries are ALWAYS English AND caveman — fragments, articles dropped, code/IDs/quoted errors verbatim — per CLAUDE.md "Memory registries" (Always English, always caveman). 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`. If the bug was trivial and the root cause not transferable → skip with `CAPITALIZE: trivial, skip`.
@@ -287,7 +287,9 @@ hash, and no-ops if nothing was written.
- No fix without understanding the root cause first (STEP 2/3). - No fix without understanding the root cause first (STEP 2/3).
- Reflection (GATHER, INVESTIGATE, DIAGNOSIS, contract, loop decisions) NEVER - Reflection (GATHER, INVESTIGATE, DIAGNOSIS, contract, loop decisions) NEVER
leaves this main loop; execution NEVER stays in it — the executor is the leaves this main loop; execution NEVER stays in it — the executor is the
sonnet-pinned bugfixer subagent (BDR-066). sonnet-pinned bugfixer subagent (BDR-066). A skill-mandated executor is exempt from the doctrine's "don't delegate
few-tool-call work" rule (CLAUDE.md "Workflow" names that exception:
skill-mandated dispatches run as written).
- The executor is re-dispatched FRESH on every round-trip (NEED-DECISION, - The executor is re-dispatched FRESH on every round-trip (NEED-DECISION,
ECARTS, BLOCK) — feedback travels as contract path + named ECARTS, BLOCK) — feedback travels as contract path + named
gaps/decisions, never as transcript. gaps/decisions, never as transcript.
+20 -14
View File
@@ -9,7 +9,7 @@ description: |
Triggers: "capitalize", "before clear/compact", "flush memory", "don't Triggers: "capitalize", "before clear/compact", "flush memory", "don't
lose this", "avant de clear/compact", "capitalise ce qui manque", lose this", "avant de clear/compact", "capitalise ce qui manque",
"close", "fin de journée", "checkpoint memory". "close", "fin de journée", "checkpoint memory".
argument-hint: "[--ritual] [--no-push] (scans conversation + git + TODO against .claude/memory/; --ritual adds the 3-question reflection; --no-push holds memory on the chore branch instead of the default auto-merge+push)" argument-hint: "[--ritual] [--no-push] (scans conversation + git + TODO against .claude/memory/; --ritual adds the 3-question reflection; --no-push holds memory on chore/<name>: pushed to origin by the hooks, NOT merged (finish skipped), merge when ready; default = auto-finish into develop)"
allowed-tools: allowed-tools:
- Read - Read
- Edit - Edit
@@ -65,17 +65,22 @@ ls .claude/memory/decisions.md .claude/memory/learnings.md \
ls .claude/tasks/TODO.md 2>/dev/null ls .claude/tasks/TODO.md 2>/dev/null
``` ```
- `.claude/memory/` missing entirely → print and STOP (do NOT create here — - `.claude/memory/` missing entirely → create it first (CLAUDE.md "Session
that is `/onboard` / `/init-project` responsibility): start": either missing → create from the templates), then proceed:
``` ```bash
⚠️ .claude/memory/ absent. Lance `/onboard` (ou `/init-project`) pour créer mkdir -p .claude/memory
les registres avant de capitaliser. cp -n ~/.claude/templates/memory/{decisions,learnings,blockers,evals,journal}.md .claude/memory/
``` ```
`/onboard` stays the fuller setup (CLAUDE.md, settings, audits) — this
bootstraps only the five registries capitalize writes to.
- Some registry files missing → name them, create each from - Some registry files missing → name them, create each from
`~/.claude/templates/memory/<name>.md`, continue. `~/.claude/templates/memory/<name>.md`, continue.
- `.claude/tasks/TODO.md` missing → the TODO reconcile volet (STEP 2B) is - `.claude/tasks/TODO.md` missing → create a minimal one, then run the TODO
**skipped**. Do NOT create it (same posture as the registries). Registries reconcile volet (STEP 2B) on it:
still run. ```bash
mkdir -p .claude/tasks
printf '# TODO\n\n## %s\n' "$(date +%Y-%m-%d)" > .claude/tasks/TODO.md
```
## STEP 1 — SCAN THE CONVERSATION ## STEP 1 — SCAN THE CONVERSATION
@@ -164,7 +169,7 @@ concatenated class names" entry.)
## STEP 2B — TODO RECONCILE (both modes) ## STEP 2B — TODO RECONCILE (both modes)
Runs only if `.claude/tasks/TODO.md` exists (STEP 0). Two passes. Runs on `.claude/tasks/TODO.md` (created minimal at STEP 0 when absent). Two passes.
**PASS A — done-detection (TODO → reality).** Detection is free — a capable **PASS A — done-detection (TODO → reality).** Detection is free — a capable
agent already spots the finished tasks from the STEP 1 git scan. The only rule agent already spots the finished tasks from the STEP 1 git scan. The only rule
@@ -358,7 +363,7 @@ Then the closing line — pick by the STEP 5C persist result (`<mode>` = `Contex
flushed` for pre-wipe, `Session closed` for ritual): flushed` for pre-wipe, `Session closed` for ritual):
- **auto-persisted (default — branched off develop, pushed)** → `✅ <mode> + persisted to origin/develop (<short>). Next session: read .claude/memory/ at startup.` - **auto-persisted (default — branched off develop, pushed)** → `✅ <mode> + persisted to origin/develop (<short>). Next session: read .claude/memory/ at startup.`
- **--no-push (held on branch)** → `✅ <mode> + committed on chore/<name>, NOT pushed (--no-push). Merge + push when ready.` - **--no-push (held on branch)** → `✅ <mode> + committed on chore/<name> — pushed to origin by the hooks, NOT merged (--no-push: finish skipped). Merge when ready.`
- **push failed after merge** → `✅ <mode> + merged to develop — ⚠️ push FAILED (<reason>); merged locally, push manually.` - **push failed after merge** → `✅ <mode> + merged to develop — ⚠️ push FAILED (<reason>); merged locally, push manually.`
- **WORKING branch (rode a feature branch)** → `✅ <mode> + committed <mem_hash> on <branch>. Integrates when the branch merges.` - **WORKING branch (rode a feature branch)** → `✅ <mode> + committed <mem_hash> on <branch>. Integrates when the branch merges.`
- **commit skipped (rc 3)** → keep the ✅ on the WRITE but make the gap loud, never - **commit skipped (rc 3)** → keep the ✅ on the WRITE but make the gap loud, never
@@ -380,7 +385,7 @@ manual commit (rc 3).
- **Append-only.** Never overwrite or renumber existing registry entries. - **Append-only.** Never overwrite or renumber existing registry entries.
- **Caveman English** registry bodies, always English. **The TODO is plain - **Caveman English** registry bodies, always English. **The TODO is plain
prose, never caveman** — caveman is registries-only. prose, never caveman** — caveman is registries-only.
- **TODO reconcile runs only if TODO.md exists.** Never create it (STEP 0). - **TODO reconcile always runs** — a missing TODO.md is created minimal at STEP 0.
- **PASS A checks only on an unambiguous task↔code/commit map.** Partial / - **PASS A checks only on an unambiguous task↔code/commit map.** Partial /
umbrella / vague → leave unchecked. Never on assumption. umbrella / vague → leave unchecked. Never on assumption.
- **PASS B captures only explicit to-dos**, deduped — never invented or - **PASS B captures only explicit to-dos**, deduped — never invented or
@@ -398,7 +403,8 @@ manual commit (rc 3).
WORKING branch (memory rides feature/bugfix) or rc 3 skips it. NEVER auto-finish WORKING branch (memory rides feature/bugfix) or rc 3 skips it. NEVER auto-finish
a branch the run did not create. a branch the run did not create.
- **Skip trivial** for the 4 ID registries; journal excepted. - **Skip trivial** for the 4 ID registries; journal excepted.
- `.claude/memory/` missing → STOP at STEP 0, do not create the structure here. - `.claude/memory/` missing → STEP 0 creates the five registries from the
templates (doctrine: either missing → create first), then proceeds.
## Common mistakes ## Common mistakes
@@ -417,7 +423,7 @@ manual commit (rc 3).
| Dumping an architecture directive as a TODO task | Route orientation/policy directives to decisions.md (BDR), not the TODO. | | Dumping an architecture directive as a TODO task | Route orientation/policy directives to decisions.md (BDR), not the TODO. |
| Writing a ritual answer fresh without dedup | Ritual answers go through STEP 2 like any candidate; a dup shows its existing ID. | | Writing a ritual answer fresh without dedup | Ritual answers go through STEP 2 like any candidate; a dup shows its existing ID. |
| French/English entry text | Prompt may be French; written registry entry is always English. | | French/English entry text | Prompt may be French; written registry entry is always English. |
| Creating `.claude/memory/` or `.claude/tasks/TODO.md` when absent | Not this skill's job — registries STOP and point to `/onboard`; TODO volet is skipped. | | Stopping on a missing `.claude/memory/` or `.claude/tasks/TODO.md` | Doctrine says create first — STEP 0 bootstraps the five registries + a minimal TODO from the templates, then proceeds; `/onboard` is the fuller setup. |
## Red flags — STOP ## Red flags — STOP
+3 -3
View File
@@ -40,8 +40,8 @@ The agent runs a **ship-and-handover pipeline** with explicit gates:
1. **PRE-FLIGHT** — Detect git repo, project root, language, project type, web sub-type, NAP signals, stack. 1. **PRE-FLIGHT** — Detect git repo, project root, language, project type, web sub-type, NAP signals, stack.
2. **BASELINE AUDITS** — Run /seo (SEO+GEO) and /harden in parallel. Capture initial scores (`SCORE_SEO_BEFORE`, `SCORE_GEO_BEFORE`, `SCORE_HARDEN_BEFORE`). 2. **BASELINE AUDITS** — Run /seo (SEO+GEO) and /harden in parallel. Capture initial scores (`SCORE_SEO_BEFORE`, `SCORE_GEO_BEFORE`, `SCORE_HARDEN_BEFORE`).
3. **FIX LOOPS (parallel, bounded)** — For each audit < 17/20: 3. **FIX LOOPS (parallel, bounded)** — For each audit < 17/20:
- Re-invoke the audit subagent with explicit instruction to apply auto-fixes. - Apply the pending FIX BUNDLE from the MAIN loop: items the audit classed AUTO directly, then every GATED item (CSP, redirects, anything harden marks "could BREAK the site") presented to the user at ONE gate before applying.
- Re-score. - Re-invoke the audit subagent in audit mode: it re-scores and returns the next FIX BUNDLE; it applies nothing (a dispatched child cannot hold a gate).
- Repeat up to `MAX_ITERATIONS` (default 5). - Repeat up to `MAX_ITERATIONS` (default 5).
- If still < 17/20 after cap → escalate to user with concrete remaining issues; user decides continue / stop / manual intervention. - If still < 17/20 after cap → escalate to user with concrete remaining issues; user decides continue / stop / manual intervention.
4. **COMMIT + PUSH** — If files changed during fix loops, run /commit-change (atomic logical commits) then `git push`. 4. **COMMIT + PUSH** — If files changed during fix loops, run /commit-change (atomic logical commits) then `git push`.
@@ -57,7 +57,7 @@ The agent runs a **ship-and-handover pipeline** with explicit gates:
- **§6 Détails techniques (pour les curieux)** — vulgarized BDR decisions, phases with technical detail, optional glossary (score table NOT here — promoted to §2). - **§6 Détails techniques (pour les curieux)** — vulgarized BDR decisions, phases with technical detail, optional glossary (score table NOT here — promoted to §2).
- **§7 Annexe — plateformes externes** (web/local-business only). - **§7 Annexe — plateformes externes** (web/local-business only).
- **§8 Annexe — build & déploiement** (only if requested). - **§8 Annexe — build & déploiement** (only if requested).
9. **RENDER** — Write `LIVRAISON.md` (fr) or `HANDOVER.md` (en) at project root, then run `scripts/handover-to-pdf.sh` to produce the matching branded `.html` (always) and `.pdf` (when a PDF engine is on the host: weasyprint > wkhtmltopdf > chromium). HTML/PDF use the ZenQuality cover page, green palette, Inter + Playfair Display typography, running header/footer with project name + page numbers. 9. **RENDER** — Write `LIVRAISON.md` (fr) or `HANDOVER.md` (en) at project root, then run `$HOME/.claude/skills/client-handover/scripts/handover-to-pdf.sh` to produce the matching branded `.html` (always) and `.pdf` (when a PDF engine is on the host: weasyprint > wkhtmltopdf > chromium). HTML/PDF use the ZenQuality cover page, green palette, Inter + Playfair Display typography, running header/footer with project name + page numbers.
Flags: Flags:
- `--skip-fix-loop` — run baseline audits once, skip auto-fix iterations. - `--skip-fix-loop` — run baseline audits once, skip auto-fix iterations.
+1 -1
View File
@@ -8,7 +8,7 @@ description: |
(that is /prune-memory). (that is /prune-memory).
Triggers: "close", "end session", "ferme la session", "session close", Triggers: "close", "end session", "ferme la session", "session close",
"checkpoint memory", "what did we learn", "retro rapide", "fin de journée". "checkpoint memory", "what did we learn", "retro rapide", "fin de journée".
argument-hint: "[--no-push] (runs capitalize in ritual mode; --no-push holds memory on the chore branch instead of the default auto-merge+push)" argument-hint: "[--no-push] (runs capitalize in ritual mode; --no-push holds memory on chore/<name>: pushed to origin by the hooks, NOT merged (finish skipped), merge when ready; default = auto-finish into develop)"
allowed-tools: allowed-tools:
- Read - Read
- Edit - Edit
+17 -5
View File
@@ -45,16 +45,28 @@ git config user.email
- `git config user.email` empty → STOP, ask the user to configure identity - `git config user.email` empty → STOP, ask the user to configure identity
first, do not dispatch. first, do not dispatch.
On a protected base (`main`/`develop`) the subagent runs the gitflow On a protected base (`main`/`develop` — `bash "$HOME/.claude/lib/gitflow.sh"
aiguillage itself inside `MODE: propose` (its Phase 0) and branches to protected-base`) ask the user the branch TYPE before any dispatch — a branch
`chore/*` before drafting the plan — code never lands directly on a name is a public name:
protected branch.
```
AskUserQuestion:
Protected base — branch type for these commits? (feature / bugfix / chore)
```
Suggest `chore` only when every pending path is under `.claude/**` or docs;
pending code never lands on a `chore/*` branch. Pass the answer as
`TYPE: <type>` in the STEP 1 prompt — the subagent runs the aiguillage with it
inside `MODE: propose` (its Phase 0) and branches to `<type>/*` before drafting
the plan. Code never lands directly on a protected branch. On a working
branch, omit `TYPE:` (the aiguillage is a no-op there).
## STEP 1 — Propose ## STEP 1 — Propose
``` ```
Agent(subagent_type="commit-changer", model="opus") Agent(subagent_type="commit-changer", model="opus")
prompt: "MODE: propose prompt: "MODE: propose
TYPE: <the STEP 0 answer — feature / bugfix / chore; omit on a working branch>
$ARGUMENTS" $ARGUMENTS"
``` ```
@@ -86,7 +98,7 @@ AskUserQuestion:
BDR-077 — never redrawn inline on the session model); show the redrawn BDR-077 — never redrawn inline on the session model); show the redrawn
plan and re-ask. plan and re-ask.
- `skip` → exit cleanly, no commits created, no `MODE: apply` dispatch. - `skip` → exit cleanly, no commits created, no `MODE: apply` dispatch.
Note: if the propose run created a `chore/*` branch (gitflow aiguillage Note: if the propose run created a `<type>/*` branch (gitflow aiguillage
off a protected base), that branch stays checked out with the work 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. uncommitted — mention it so the user isn't surprised by the branch switch.
+5 -9
View File
@@ -182,7 +182,6 @@ Author a runbook, seed the incident ledger, commit both, then proceed to STEP 1.
#!/usr/bin/env bash #!/usr/bin/env bash
# === deploy runbook (reference) — NOT run directly. Instantiated into the deploy checklist per delta. === # === deploy runbook (reference) — NOT run directly. Instantiated into the deploy checklist per delta. ===
# Fixed steps run every deploy; annotated steps (@delta lines) re-instantiate from the delta. # Fixed steps run every deploy; annotated steps (@delta lines) re-instantiate from the delta.
# @config push_deploy_tags=false
``` ```
3. Scan for migration, rebuild, and dependency steps; propose `@delta:` annotations inline: 3. Scan for migration, rebuild, and dependency steps; propose `@delta:` annotations inline:
- Migration steps (`psql -f`, `migrate up`, `supabase migration`) → - Migration steps (`psql -f`, `migrate up`, `supabase migration`) →
@@ -219,12 +218,10 @@ Author a runbook, seed the incident ledger, commit both, then proceed to STEP 1.
| Backup command | "Backup command before migrations?" | `pg_dump "$DB" > ~/backups/pre-deploy-$(date +%F-%H%M).sql` | | Backup command | "Backup command before migrations?" | `pg_dump "$DB" > ~/backups/pre-deploy-$(date +%F-%H%M).sql` |
| Health-check URL | "Health-check URL (expects HTTP 200)?" | `https://$DEPLOY_HOST/health` | | Health-check URL | "Health-check URL (expects HTTP 200)?" | `https://$DEPLOY_HOST/health` |
| Rollback note | "One-line rollback note (optional)?" | omit if blank | | Rollback note | "One-line rollback note (optional)?" | omit if blank |
| Push deploy tags | "`push_deploy_tags`? (true / false)" | `false` |
**Using** `~/.claude/templates/deploy/PROCEDURE.md` **as base, populate** fields from interview answers + detected artifacts: **Using** `~/.claude/templates/deploy/PROCEDURE.md` **as base, populate** fields from interview answers + detected artifacts:
- Substitute `$DEPLOY_HOST` with the supplied host (keep literal `$DEPLOY_HOST` if none given). - Substitute `$DEPLOY_HOST` with the supplied host (keep literal `$DEPLOY_HOST` if none given).
- Include only the annotated steps whose artifact was detected; keep all fixed steps. - Include only the annotated steps whose artifact was detected; keep all fixed steps.
- Set `# @config push_deploy_tags=<answer>` in the header.
- Append the rollback note as `# ROLLBACK: <note>` at the end if provided. - Append the rollback note as `# ROLLBACK: <note>` at the end if provided.
→ **[GATE]** below. → **[GATE]** below.
@@ -427,9 +424,7 @@ Then:
The deploy succeeded. Lay the oracle and close out. The deploy succeeded. Lay the oracle and close out.
1. Read `# @config push_deploy_tags=` from the `PROCEDURE.md` header (default 1. Pick `date = today` (`YYYY-MM-DD`); if `deploy/<date>` exists, suffix `-N`.
`false`). Pick `date = today` (`YYYY-MM-DD`); if `deploy/<date>` exists, suffix
`-N`.
2. Write `.claude/deploy/STATE.json` (overwrite): 2. Write `.claude/deploy/STATE.json` (overwrite):
```jsonc ```jsonc
{ "deployed_sha": "<PENDING.target_sha>", "deployed_at": "<now ISO-8601>", { "deployed_sha": "<PENDING.target_sha>", "deployed_at": "<now ISO-8601>",
@@ -438,9 +433,10 @@ The deploy succeeded. Lay the oracle and close out.
**`deployed_sha` = `PENDING.target_sha`, NOT current HEAD** — HEAD may have **`deployed_sha` = `PENDING.target_sha`, NOT current HEAD** — HEAD may have
moved during the gap; the bridge's target is the deployed truth. moved during the gap; the bridge's target is the deployed truth.
3. `git tag -a deploy/<date> <PENDING.target_sha> -m "<summary>"`. 3. `git tag -a deploy/<date> <PENDING.target_sha> -m "<summary>"`.
4. If `push_deploy_tags=true` → `git push origin deploy/<date>` — **best-effort, 4. No separate tag push: the oracle commit (step 5) fires the gitflow
non-fatal**: a push failure logs a warning, never blocks the mark (the tag is a post-commit hook, which pushes with `--follow-tags`, so `deploy/<date>`
bookmark; `STATE.json` is the oracle). rides along (BDR-095). A hook `push FAILED` warning never blocks the mark
(the tag is a bookmark; `STATE.json` is the oracle).
5. Commit the oracle: 5. Commit the oracle:
```bash ```bash
bash ~/.claude/lib/deploy-commit.sh commit "chore(deploy): mark <date> @ <short>" \ bash ~/.claude/lib/deploy-commit.sh commit "chore(deploy): mark <date> @ <short>" \
+7
View File
@@ -22,6 +22,13 @@ Run the two-mode doc pipeline (BDR-077 — audit judgment on opus, patch on
the sonnet pin, the validation gate in THIS loop; a dispatched agent cannot the sonnet pin, the validation gate in THIS loop; a dispatched agent cannot
hold a gate): hold a gate):
0. AIGUILLAGE — before any write, follow `$HOME/.claude/lib/gitflow-aiguillage.md`
— this skill's TYPE = `chore`. On `main`/`develop` it branches to
`chore/<name>` off develop so the doc patch lands on a branch; on a working
branch it proceeds in place. Never `gitflow finish`. `lib/doc-commit.md`'s
rc 5 (commit rejected by the hook on a protected base) stays as the
backstop, not the plan.
1. AUDIT — dispatch: 1. AUDIT — dispatch:
`Agent(subagent_type="doc-syncer", model="opus")` `Agent(subagent_type="doc-syncer", model="opus")`
prompt: "MODE: audit. Audit public docs for this project. Context from prompt: "MODE: audit. Audit public docs for this project. Context from
+4 -2
View File
@@ -244,7 +244,7 @@ Valider ? (all / <IDs> / edit / skip)
Always append a 1-line entry to today's heading in `.claude/memory/journal.md`. 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. **Language rule**: written entries are ALWAYS English AND caveman — fragments, articles dropped, code/IDs/quoted errors verbatim — per CLAUDE.md "Memory registries" (Always English, always caveman). 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`. If no substantive capture candidate → skip with `CAPITALIZE: nothing to log`.
@@ -259,7 +259,9 @@ hash, and no-ops if nothing was written.
- Max 5 files. If more needed → `/ship-feature`. - Max 5 files. If more needed → `/ship-feature`.
- Reflection (scope, plan, contract, loop decisions) NEVER leaves this main - Reflection (scope, plan, contract, loop decisions) NEVER leaves this main
loop; execution NEVER stays in it — the executor is the sonnet-pinned loop; execution NEVER stays in it — the executor is the sonnet-pinned
feater subagent (BDR-066). feater subagent (BDR-066). A skill-mandated executor is exempt from the doctrine's "don't delegate
few-tool-call work" rule (CLAUDE.md "Workflow" names that exception:
skill-mandated dispatches run as written).
- The executor is dispatched FRESH on every round-trip — feedback travels - The executor is dispatched FRESH on every round-trip — feedback travels
as contract path + named gaps/decisions, never as transcript. as contract path + named gaps/decisions, never as transcript.
- Design gate only (not full plugin check). See STEP 0.5. - Design gate only (not full plugin check). See STEP 0.5.
+4 -1
View File
@@ -85,7 +85,10 @@ On a protected base, assistance skills (`feat`/`bugfix`/`hotfix`) AND the standa
memory/doc skills (`capitalize`/`close`/`prune-memory`/`reconcile`, TYPE `chore`) memory/doc skills (`capitalize`/`close`/`prune-memory`/`reconcile`, TYPE `chore`)
call `start <type>` to branch first; on a working branch they commit in place. Same call `start <type>` to branch first; on a working branch they commit in place. Same
`protected-base` predicate the out-of-skill hook uses. Caller→type map + rationale: `protected-base` predicate the out-of-skill hook uses. Caller→type map + rationale:
`lib/gitflow-aiguillage.md`. `lib/gitflow-aiguillage.md`. `/capitalize` and `/close` auto-finish their memory-only
`chore/*` branch into develop when THEY created it this run (BDR-068; `--no-push`
opts out) — the only finish that fires without a live human signal; everything else
stays human-gated.
## Failure modes (mechanical — lib return codes are the contract) ## Failure modes (mechanical — lib return codes are the contract)
+15 -6
View File
@@ -64,8 +64,11 @@ disposition required at hotfix weight.
Follow `$HOME/.claude/lib/design-gate.md`: Follow `$HOME/.claude/lib/design-gate.md`:
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, styling, animation). - 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, - Signals found → a hotfix is the trivial tier by definition (≤2 files, one
tell the user to run `/profile design` before proceeding. cosmetic value — `design-gate.md` §1): skip the gate, no toolchain. If the
signals reveal real UI work (new component, layout, motion), this is not a
hotfix → route to `/feat` or `/bugfix` instead of running
`design-tool-gate.sh`.
- If no signals → skip (zero overhead). - If no signals → skip (zero overhead).
## STEP 1.7 — CONTRACT (silent autofill) ## STEP 1.7 — CONTRACT (silent autofill)
@@ -104,8 +107,12 @@ verify+secure loop).
## STEP 2 — PRE-FLIGHT ## STEP 2 — PRE-FLIGHT
**Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md` **Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
— your type = `hotfix`. On `main`/`develop` it branches first; on a working — your type follows the base: on `main` → `hotfix` (prod incident; finish fans
branch it's a no-op (commit in place). Never `finish`. out to main + develop); on `develop` → `bugfix` (the fix forks from develop — a
`hotfix/*` off main would miss develop's code and later merge to prod). Either
protected base branches first; on a working branch it's a no-op (commit in
place). The /hotfix size rules and the hotfixer executor are unchanged either
way. Never `finish`.
Snapshot current state so revert is possible: Snapshot current state so revert is possible:
@@ -223,7 +230,7 @@ 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). 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). **Language rule**: the journal line and any proposed BLK/LRN entries are ALWAYS written English AND caveman — fragments, articles dropped, code/IDs/quoted errors verbatim — per CLAUDE.md "Memory registries" (Always English, always caveman).
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it **Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks` surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks`
@@ -237,7 +244,9 @@ trivial hotfix still produces a `chore(memory): journal — …` commit (Frame 2
- Max 2 files changed. If more needed → `/bugfix`. - Max 2 files changed. If more needed → `/bugfix`.
- Reflection (LOCATE, contract, gate decisions) NEVER leaves this main - Reflection (LOCATE, contract, gate decisions) NEVER leaves this main
loop; execution NEVER stays in it — the executor is the sonnet-pinned loop; execution NEVER stays in it — the executor is the sonnet-pinned
hotfixer subagent (BDR-066). hotfixer subagent (BDR-066). A skill-mandated executor is exempt from the doctrine's "don't delegate
few-tool-call work" rule (CLAUDE.md "Workflow" names that exception:
skill-mandated dispatches run as written).
- The executor is dispatched FRESH, once — hotfix never re-dispatches after - The executor is dispatched FRESH, once — hotfix never re-dispatches after
a failed or blocked attempt (it reverts and escalates to `/bugfix`, it a failed or blocked attempt (it reverts and escalates to `/bugfix`, it
does not retry). Sole exception: a class-tagged BLOCKED answered by the does not retry). Sole exception: a class-tagged BLOCKED answered by the
+27 -14
View File
@@ -103,7 +103,14 @@ every field the scaffolder consumes crosses the dispatch): BRIEF (verbatim)
`~/.claude/CLAUDE.md`. A STOP (missing input) comes back as its report — `~/.claude/CLAUDE.md`. A STOP (missing input) comes back as its report —
resolve here, re-dispatch. The ~30s liveness pings are THIS loop's job resolve here, re-dispatch. The ~30s liveness pings are THIS loop's job
while waiting. while waiting.
Creates: CLAUDE.md, `.claude/settings.json`, `.claudeignore`, `.gitignore`, `.env.example`, empty entry points. NO README, NO features, NO `.claude/tasks/` or `.claude/memory/` (not bootstrapped by this flow — copy from `~/.claude/templates/memory/` manually if wanted before STEP 10b's memory commit). Creates: CLAUDE.md, `.claude/settings.json`, `.claudeignore`, `.gitignore`, `.env.example`, empty entry points. NO README, NO features.
Then bootstrap the memory in THIS loop, before STEP 5f so the root commit embeds
it (doctrine: registries + TODO exist from day one; STEP 10b appends to them):
```bash
mkdir -p .claude/memory .claude/tasks
cp -n ~/.claude/templates/memory/{decisions,learnings,blockers,evals,journal}.md .claude/memory/
[ -f .claude/tasks/TODO.md ] || printf '# TODO\n\n## %s\n' "$(date +%Y-%m-%d)" > .claude/tasks/TODO.md
```
Verify: `git init` + build passes. Verify: `git init` + build passes.
## STEP 5b — CREATE README ## STEP 5b — CREATE README
@@ -166,7 +173,7 @@ layout and the deterministic root commit:
bash "$HOME/.claude/lib/gitflow.sh" init "chore: scaffold <project-name>" bash "$HOME/.claude/lib/gitflow.sh" init "chore: scaffold <project-name>"
``` ```
Creates `main`+`develop`, root-commits the FULL scaffold (CLAUDE.md, README, Creates `main`+`develop`, root-commits the FULL scaffold (CLAUDE.md, README,
config, `.gitignore`, deps), reconciles the `.gitignore` socle, and installs the config, `.gitignore`, `.claude/memory/` + `.claude/tasks/TODO.md`, deps), reconciles the `.gitignore` socle, and installs the
versioned pre-commit hook — all embedded in the root commit, working tree clean. versioned pre-commit hook — all embedded in the root commit, working tree clean.
This is the deterministic scaffold commit owner (closes BLK-010). The MVP is This is the deterministic scaffold commit owner (closes BLK-010). The MVP is
implemented on a `feature/*` branch off `develop` (STEP 8). implemented on a `feature/*` branch off `develop` (STEP 8).
@@ -217,14 +224,15 @@ call. The plan is closed; execution and plan-conformity review are sonnet
work. Reflection (task decomposition, review verdict arbitration) stays in work. Reflection (task decomposition, review verdict arbitration) stays in
this loop. this loop.
## STEP 8b — GRAPHIFY FULL (after implementation) ## STEP 8b — GRAPHIFY SIGNAL (after implementation — BDR-097)
If `graphify` CLI is installed AND complexity >= 30%: graphify is proposed only from 200 tracked code files, and the USER decides —
1. Run full graphify on the implemented project: never build, install or update a graph here:
```bash ```bash
graphify . --out graphify-out 2>/dev/null || true bash ~/.claude/lib/graphify-gate.sh .
``` ```
2. Print: `🔗 Full project graph updated at graphify-out/` - Prints a line → carry it into the FINAL OUTPUT status table as
If `graphify` not installed or complexity < 30% → skip silently. `GRAPHIFY: <line> — /graphify on your go`.
- Silent → `GRAPHIFY: below 200 code files, not proposed`.
## STEP 9 — VERIFY + SECURE (fresh gates, bounded loops) ## STEP 9 — VERIFY + SECURE (fresh gates, bounded loops)
Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with Run the two fresh gates per `$HOME/.claude/lib/verify-secure-loop.md` with
@@ -284,7 +292,9 @@ capitalizes NOTHING. Do NOT fabricate a BDR to fill the step. Print
[ decisions.md ] BDR-XXX — <decision> — <1-line why> [ decisions.md ] BDR-XXX — <decision> — <1-line why>
Valider lesquels ? (all / <IDs> / edit / skip) Valider lesquels ? (all / <IDs> / edit / skip)
``` ```
3. Append approved entries + update the Index. Append a journal line under today. 3. Append approved entries to the existing registries (bootstrapped at STEP 5,
in the root commit) + update the Index. Append a journal line under today's
heading in `.claude/memory/journal.md`.
**Hash rule — founding decisions carry NO commit hash; use path + date only.** **Hash rule — founding decisions carry NO commit hash; use path + date only.**
This is by nature, not an omission: a founding decision is made at DESIGN This is by nature, not an omission: a founding decision is made at DESIGN
@@ -295,8 +305,10 @@ that IMPLEMENTS the decision, e.g. BDR-033 → 11792cc). This is the SECOND case
where hash-anchoring does not apply — the first being a squash-merged PR, whose where hash-anchoring does not apply — the first being a squash-merged PR, whose
anchored commit ceases to exist. anchored commit ceases to exist.
**Language rule**: written entries are ALWAYS in English (CLAUDE.md "Memory **Language rule**: written entries are ALWAYS English AND caveman — fragments,
registries"). The gate may mirror the user's language; entries must not. articles dropped, code/IDs/quoted errors verbatim — per CLAUDE.md "Memory
registries" (Always English, always caveman). The gate may mirror the user's
language; entries must not.
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it **Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
surgically commits the approved founding decisions (`.claude/memory` + surgically commits the approved founding decisions (`.claude/memory` +
@@ -369,5 +381,6 @@ LOCATION: <path> | STACK: <stack> | BUILD: ✅/❌ | TESTS: ✅<N>/❌
V1 FEATURES: ✅<f> / ⚠️<f> partial: <reason> V1 FEATURES: ✅<f> / ⚠️<f> partial: <reason>
REMAINING ISSUES: <list or none> REMAINING ISSUES: <list or none>
QUICK START: <exact cmds> QUICK START: <exact cmds>
CLAUDE.md ✅ | README ✅ | SETTINGS ✅ CLAUDE.md ✅ | README ✅ | SETTINGS ✅ | MEMORY ✅
GRAPHIFY: <STEP 8b line>
``` ```
+30 -19
View File
@@ -1,7 +1,7 @@
--- ---
name: onboard name: onboard
description: 'Use when bringing an existing repo into the claude-config framework — needs archetype detection, config install, full multi-axis audit (debt/SEO/GEO/UI-UX/perf/security/a11y/docs), and prioritized backlog. Multi-agent orchestrator. Do NOT use for repos created via /init-project. Triggers: "onboard", "onboard project", "audit existing repo", "setup existing project".' description: 'Use when bringing an existing repo into the claude-config framework — needs archetype detection, config install, full multi-axis audit (debt/SEO/GEO/UI-UX/perf/security/a11y/docs), and prioritized backlog. Multi-agent orchestrator. Do NOT use for repos created via /init-project. Triggers: "onboard", "onboard project", "audit existing repo", "setup existing project".'
argument-hint: '[optional hints: "Python FastAPI" | "add gsd" | "Next.js monorepo" | "force-archetype:wordpress"]' argument-hint: '[optional hints: "Python FastAPI" | "Next.js monorepo" | "force-archetype:wordpress"]'
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Agent, Skill allowed-tools: Read, Write, Edit, Bash, Glob, Grep, Agent, Skill
--- ---
@@ -27,7 +27,8 @@ Run `$HOME/.claude/lib/plugin-gate.md` with hint "onboarding existing project +
- PROPOSED CHANGES exist → show list, ask "Apply? (yes / no / customize)". Apply on confirm. - PROPOSED CHANGES exist → show list, ask "Apply? (yes / no / customize)". Apply on confirm.
- OK → `✅ Plugin check passed — [active plugins] — complexity: <score>%`, continue. - OK → `✅ Plugin check passed — [active plugins] — complexity: <score>%`, continue.
Complexity score is carried forward for STEP 4 graphify decision. Complexity score is informative here; STEP 4 graphify is gated by
`graphify-gate.sh` (200 tracked code files, BDR-097), not by this score.
--- ---
@@ -107,7 +108,7 @@ L'agent génère :
- `.claudeignore` - `.claudeignore`
- `.gitignore` (safety check) - `.gitignore` (safety check)
- `.claude/tasks/TODO.md`, `.claude/memory/{decisions,learnings,blockers,journal,evals}.md` - `.claude/tasks/TODO.md`, `.claude/memory/{decisions,learnings,blockers,journal,evals}.md`
- **Pas encore** `ROADMAP.md` (généré uniquement via `/onboard add gsd` — voir Next steps) - **Pas encore** `ROADMAP.md` (GSD multi-session : `gsd init` à la main, voir docs gsd-pi — cf. Next steps)
Si `CLAUDE.md` existe déjà : lire son contenu, ne PAS écraser — fusionner après STEP 3. Si `CLAUDE.md` existe déjà : lire son contenu, ne PAS écraser — fusionner après STEP 3.
@@ -151,11 +152,13 @@ Adopter le modèle gitflow sur ce repo existant :
```bash ```bash
bash "$HOME/.claude/lib/gitflow.sh" init bash "$HOME/.claude/lib/gitflow.sh" init
``` ```
Sur un repo existant, cela : renomme `master`→`main` si besoin (LOCAL), crée Sur un repo existant, cela : renomme `master`→`main` si besoin (LOCAL), pose le
`develop` depuis main, réconcilie le socle `.gitignore` (additif — n'écrase socle (`.gitignore` réconcilié — additif, n'écrase jamais les règles du projet —
jamais les règles du projet), installe le hook pre-commit versionné, et fait UN + `.githooks/` versionnés) sur une branche `chore/gitflow-adopt` créée depuis
commit `chore: adopt gitflow socle + pre-commit hook` sur main (pendant que le hook est main, la merge `--no-ff` dans main (le hook pre-commit est global sur la machine
inactif → jamais auto-bloqué). Idempotent — un re-run est un no-op. et bloque tout commit de code sur main, mais exempte les merges — BDR-095),
supprime la branche, puis crée `develop` depuis main. Idempotent — un re-run est
un no-op.
**Annoncer le renommage master→main** s'il a lieu. Le renommage est LOCAL ; **Annoncer le renommage master→main** s'il a lieu. Le renommage est LOCAL ;
repointer la branche par défaut du remote vers `main` + la protection de branche repointer la branche par défaut du remote vers `main` + la protection de branche
@@ -247,21 +250,29 @@ Pour chaque fast-lib détectée :
--- ---
## STEP 4 — GRAPHIFY (si complexity ≥ 30% et pas déjà présent) ## STEP 4 — GRAPHIFY (proposé dès 200 fichiers code — l'utilisateur décide)
```bash ```bash
command -v graphify &>/dev/null && echo "available" || echo "not-installed" command -v graphify &>/dev/null && echo "available" || echo "not-installed"
test -f graphify-out/GRAPH_REPORT.md && echo "graph-exists" test -f graphify-out/graph.json && echo "graph-exists"
bash ~/.claude/lib/graphify-gate.sh .
``` ```
- **Pas installé** → skip avec message : `graphify non installé — skip audit architectural. Install : (voir graphify/SKILL.md)` - **Pas installé** → skip avec message : `graphify non installé — skip audit architectural. Install : (voir graphify/SKILL.md)`
- **Complexity < 30%** → skip silencieusement, projet trop petit pour justifier. - **`graph-exists`** → skip, réutiliser l'existant.
- **Graphe déjà présent + récent** (fichier < 7j) → skip, réutiliser l'existant. - **La gate n'imprime rien** → moins de 200 fichiers code trackés (BDR-097 :
- **Sinon** → run : grep + lecture suffisent). Pas de proposition ; ligne FINAL OUTPUT
`below 200 code files, not proposed`.
- **La gate imprime une ligne** (`graphify? N code files ≥ 200, no graph`) →
l'afficher et DEMANDER à l'utilisateur. Jamais de build sans oui explicite.
Sur oui :
```bash ```bash
graphify . --out graphify-out 2>&1 | tail -20 printf '.claude/\ndocs/superpowers/\n' >> .graphifyignore
grep -qxF 'graphify-out/' .gitignore || echo 'graphify-out/' >> .gitignore
graphify update .
``` ```
Puis `test -f graphify-out/GRAPH_REPORT.md` pour valider. Puis `test -f graphify-out/GRAPH_REPORT.md` pour valider. Sur non → skip,
ligne FINAL OUTPUT `proposed, declined`.
Print : `🔗 Knowledge graph : graphify-out/GRAPH_REPORT.md (N nodes, M edges)`. Print : `🔗 Knowledge graph : graphify-out/GRAPH_REPORT.md (N nodes, M edges)`.
@@ -937,7 +948,7 @@ Choix ? (A / B / C / D / E)
**STOP.** Attendre la réponse. **STOP.** Attendre la réponse.
- **A** → stop ici, l'utilisateur relira et reviendra avec `/onboard continue`. - **A** → stop ici, l'utilisateur relit les 4 fichiers ; le backlog (STEP 9) se génère ensuite à la demande depuis `.claude/audits/AUDIT_PROPOSALS.md`.
- **B** → continuer STEP 9 avec toutes les recommandations. - **B** → continuer STEP 9 avec toutes les recommandations.
- **C** → demander les changements spécifiques, les appliquer dans .claude/audits/AUDIT_PROPOSALS.md, puis re-présenter la gate. - **C** → demander les changements spécifiques, les appliquer dans .claude/audits/AUDIT_PROPOSALS.md, puis re-présenter la gate.
- **D** → continuer STEP 9 avec seulement les P0. - **D** → continuer STEP 9 avec seulement les P0.
@@ -1020,7 +1031,7 @@ Pour démarrer : lire .claude/tasks/TODO.md, choisir une tâche P0, lancer le /s
- Si `CLAUDE.md` existe : le lire, ne pas l'écraser sans fusion après STEP 3. - Si `CLAUDE.md` existe : le lire, ne pas l'écraser sans fusion après STEP 3.
- STEP 3 : ne redemande jamais ce qui est déjà dans README ou manifests. - STEP 3 : ne redemande jamais ce qui est déjà dans README ou manifests.
- STEP 3.5 : si ctx7 absent + fast-libs, WARN mais ne bloque pas. - STEP 3.5 : si ctx7 absent + fast-libs, WARN mais ne bloque pas.
- STEP 4 : skip si complexity < 30% ou graph récent déjà présent. - STEP 4 : graphify proposé seulement si `graphify-gate.sh` imprime une ligne (≥ 200 fichiers code, pas de graphe — BDR-097) ; l'utilisateur décide, jamais de build sans oui explicite.
- STEP 5-6 : subagents isolés (Agent tool avec subagent_type spécifique) — pas de contexte partagé entre les audits. Chaque subagent écrit son rapport dans `.onboard-audit/<name>.md`. - STEP 5-6 : subagents isolés (Agent tool avec subagent_type spécifique) — pas de contexte partagé entre les audits. Chaque subagent écrit son rapport dans `.onboard-audit/<name>.md`.
- STEP 6 dispatches parallélisables : regrouper dans un seul message Agent multi-calls. - STEP 6 dispatches parallélisables : regrouper dans un seul message Agent multi-calls.
- `.onboard-audit/` gitignoré automatiquement — ne jamais commiter. - `.onboard-audit/` gitignoré automatiquement — ne jamais commiter.
@@ -1035,7 +1046,7 @@ ARCHETYPE : <name> (confiance: <niveau>)
STACK : <stack> STACK : <stack>
CONFIG : ✅ CLAUDE.md, settings.json, .claudeignore, .claude/{tasks,memory,audits}/ CONFIG : ✅ CLAUDE.md, settings.json, .claudeignore, .claude/{tasks,memory,audits}/
CTX7 CACHE : ✅ [libs] | ⚠️ not installed | — N/A CTX7 CACHE : ✅ [libs] | ⚠️ not installed | — N/A
GRAPHIFY : ✅ graphify-out/ | ⚠️ not installed | — skipped (simple) GRAPHIFY : ✅ graphify-out/ | ⚠️ not installed | — below 200 code files, not proposed | — proposed, declined
AUDITS : AUDITS :
✅ dette technique (.onboard-audit/analyze.md + code-clean.md) ✅ dette technique (.onboard-audit/analyze.md + code-clean.md)
✅ sécurité (.onboard-audit/cso.md) ✅ sécurité (.onboard-audit/cso.md)
@@ -1055,6 +1066,6 @@ SYNTHÈSE :
NEXT STEPS : NEXT STEPS :
1. Ouvrir .claude/audits/ONBOARD_REPORT.md — overview complète 1. Ouvrir .claude/audits/ONBOARD_REPORT.md — overview complète
2. Démarrer par la première tâche P0 de .claude/tasks/TODO.md avec le skill indiqué 2. Démarrer par la première tâche P0 de .claude/tasks/TODO.md avec le skill indiqué
3. /onboard add gsd — générer ROADMAP.md pour multi-session si besoin 3. GSD (multi-session) : `gsd init` à la main, voir docs gsd-pi
4. .onboard-audit/ peut être supprimé (raw data consommée en synthèse) 4. .onboard-audit/ peut être supprimé (raw data consommée en synthèse)
``` ```
+7 -4
View File
@@ -28,14 +28,17 @@ digraph pipeline {
## STEP 0: Dependencies ## STEP 0: Dependencies
Check before starting. Install what's missing. Check before starting. If something is missing, print the install
command(s) and STOP until the user has run them — `sudo` / `apt` is the
user's to run, never Claude's. The one exception: `pip install pymupdf`
inside the project's own venv may be run by Claude.
```bash ```bash
# Option A: poppler (lighter) # Option A: poppler (lighter) — USER runs the install
command -v pdftoppm && echo "OK" || echo "INSTALL: sudo apt install poppler-utils" command -v pdftoppm && echo "OK" || echo "USER RUNS: sudo apt install poppler-utils"
# Option B: PyMuPDF (more powerful — extracts embedded images with coordinates) # Option B: PyMuPDF (more powerful — extracts embedded images with coordinates)
python3 -c "import fitz; print('OK')" 2>/dev/null || echo "INSTALL: pip install pymupdf" python3 -c "import fitz; print('OK')" 2>/dev/null || echo "INSTALL: pip install pymupdf (project venv only — otherwise USER RUNS)"
``` ```
Prefer PyMuPDF if both available — it extracts embedded images + gives page dimensions. Prefer PyMuPDF if both available — it extracts embedded images + gives page dimensions.
+6
View File
@@ -9,6 +9,12 @@ Dispatch the refactorer executor — behavior-preserving norm application is
closed execution, so it runs pinned on **sonnet** (not the big session 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. model). The scope you name is the only reflection; the agent applies norms.
**Gitflow aiguillage first** (the refactorer edits code): follow
`$HOME/.claude/lib/gitflow-aiguillage.md`, this skill's TYPE = `chore`. On
`main`/`develop` run `bash ~/.claude/lib/gitflow.sh start chore refactor-<slug>`
and dispatch on the new branch; on a working branch dispatch in place. Never
`gitflow finish` — integration is human-gated.
``` ```
Agent(subagent_type="refactorer") Agent(subagent_type="refactorer")
prompt: "Refactor to strict project norms, preserving external behavior prompt: "Refactor to strict project norms, preserving external behavior
+10 -8
View File
@@ -24,7 +24,7 @@ The two mechanical spans (prep, finish+tag) run on the sonnet-pinned
gate needed here, dispatch does the job. This dispatcher keeps everything gate needed here, dispatch does the job. This dispatcher keeps everything
the executor must never own: the version-NUMBER decision (judgment — derives the executor must never own: the version-NUMBER decision (judgment — derives
from semver change nature), and the two human gates (when to release, and 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 the tag push). A human gate sits BETWEEN the two spans by construction, so the
executor is never dispatched twice in one call. executor is never dispatched twice in one call.
## When to use ## When to use
@@ -91,24 +91,26 @@ Parse the `RELEASE-EXEC REPORT`:
the fan-out hit), STOP — resolving a conflicted fan-out is a human call, the fan-out hit), STOP — resolving a conflicted fan-out is a human call,
not an auto-retry. not an auto-retry.
### STEP 6 — Push GATE (ASK) ### STEP 6 — Tag push GATE (ASK)
STOP. On explicit go only ([[LRN-069]]) — run the push HERE, in this `main` and `develop` are already on origin: the lib pushes every merge as
dispatcher, never delegated to the executor: it lands (`_gitflow_merge_into` + the post-merge hook, BDR-095). Only the
tag is left. STOP. On explicit go only ([[LRN-069]]) — run the tag push
HERE, in this dispatcher, never delegated to the executor:
``` ```
AskUserQuestion: AskUserQuestion:
Push main, develop, and v<X.Y.Z> to origin? — go / hold Push tag v<X.Y.Z> to origin? — go / hold
``` ```
Go → Go →
```bash ```bash
git push origin main develop && git push origin v<X.Y.Z> git push origin v<X.Y.Z>
``` ```
`hold` → stop; the release is fanned out and tagged locally, unpushed. `hold` → stop; the release is on origin (main + develop), the tag stays local.
## 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.
- Auto-firing finish because tests pass → finish is a HUMAN gate. - Auto-firing finish because tests pass → finish is a HUMAN gate.
- Restarting the tag at v1.0.0 → desyncs from the CHANGELOG lineage. Continue it. - Restarting the tag at v1.0.0 → desyncs from the CHANGELOG lineage. Continue it.
- Pushing without the ASK gate → [[LRN-069]]. - Pushing the tag without the ASK gate → [[LRN-069]].
## Validation ## Validation
`RC_WORK=$(mktemp -d) RC_TAG=1 bash lib/tests/run-release-candidate.sh` → 5/5 (fan-out + tag on main). `RC_TAG=0` reds the tag assertion — proves the lib alone never tags (the gap this skill fills). `RC_WORK=$(mktemp -d) RC_TAG=1 bash lib/tests/run-release-candidate.sh` → 5/5 (fan-out + tag on main). `RC_TAG=0` reds the tag assertion — proves the lib alone never tags (the gap this skill fills).
+7
View File
@@ -535,6 +535,13 @@ intent, not header wording: **AUTO** = no-confirmation items (seo batches
A/B/C · geo G1–G4/G6); **GATED** = items marked NEEDS CONFIRMATION / visible A/B/C · geo G1–G4/G6); **GATED** = items marked NEEDS CONFIRMATION / visible
/ structural (seo D/E · geo G5); **USER ACTIONS** = batch F / G7. / structural (seo D/E · geo G5); **USER ACTIONS** = batch F / G7.
### Gitflow aiguillage (before the first edit)
Follow `$HOME/.claude/lib/gitflow-aiguillage.md` — this skill's TYPE =
`feature` (aggressive mode edits code). On `main`/`develop` branch first:
`bash ~/.claude/lib/gitflow.sh start feature seo-<slug>`; on a working
branch apply in place. Never `gitflow finish` — integration is human-gated.
### Serial by ownership (no parallel race) ### Serial by ownership (no parallel race)
The two bundles may touch the same shared template (meta vs JSON-LD). Apply The two bundles may touch the same shared template (meta vs JSON-LD). Apply
+4 -3
View File
@@ -32,7 +32,8 @@ Verify the project has a `CLAUDE.md` and print a brief orientation summary:
ls CLAUDE.md .claude/CLAUDE.md 2>/dev/null | head -1 ls CLAUDE.md .claude/CLAUDE.md 2>/dev/null | head -1
git branch --show-current 2>/dev/null || echo "not a git repo" git branch --show-current 2>/dev/null || echo "not a git repo"
git log --oneline -3 --format="%h %<(50,trunc)%s" 2>/dev/null || true git log --oneline -3 --format="%h %<(50,trunc)%s" 2>/dev/null || true
ls .gsd/ROADMAP.md 2>/dev/null | head -1 # gsd-pi ≥ 3: state in .gsd/STATE.md + gsd.db + milestones/<ID>/<ID>-ROADMAP.md (no .gsd/ROADMAP.md)
ls .gsd/ 2>/dev/null >/dev/null && head -20 .gsd/STATE.md 2>/dev/null
``` ```
- **CLAUDE.md found** → read it silently, then print orientation header (informational, not a gate): - **CLAUDE.md found** → read it silently, then print orientation header (informational, not a gate):
``` ```
@@ -41,7 +42,7 @@ ls .gsd/ROADMAP.md 2>/dev/null | head -1
Stack : <stack from CLAUDE.md> Stack : <stack from CLAUDE.md>
Branch : <current git branch> Branch : <current git branch>
Recent : <last 3 commit messages> Recent : <last 3 commit messages>
GSD : <current milestone if .gsd/ROADMAP.md exists, else "not initialized"> GSD : <current milestone read from .gsd/STATE.md if .gsd/ exists, else "not initialized">
``` ```
Continue to STEP 1. Continue to STEP 1.
- **Not found** → - **Not found** →
@@ -262,7 +263,7 @@ Feature shipped implies at least one design decision worth capturing. Run this B
4. Append approved entries to the registries. Update the Index table at the top of each file. 4. Append approved entries to the registries. Update the Index table at the top of each file.
5. Append a one-line entry to `.claude/memory/journal.md` under today's date heading (`## YYYY-MM-DD`). 5. Append a one-line entry to `.claude/memory/journal.md` under today's date heading (`## YYYY-MM-DD`).
**Language rule**: written entries are ALWAYS in English (see CLAUDE.md "Memory registries" § Language). The interactive gate above may mirror the user's language; the appended entries must not. **Language rule**: written entries are ALWAYS English AND caveman — fragments, articles dropped, code/IDs/quoted errors verbatim — per CLAUDE.md "Memory registries" (Always English, always caveman). The interactive gate above may mirror the user's language; the appended entries must not.
If nothing substantive to log → print `CAPITALIZE: nothing substantive to log` and skip. If nothing substantive to log → print `CAPITALIZE: nothing substantive to log` and skip.
+31 -18
View File
@@ -39,7 +39,7 @@ plus its report IS the approval gate, reviewed by the human afterwards.
Core principle: **autonomy on the working branch, never on shared Core principle: **autonomy on the working branch, never on shared
state.** The skill may edit code freely on its own branch; it may NOT state.** The skill may edit code freely on its own branch; it may NOT
silently rewrite declared state (target TODO, memory registries) or silently rewrite declared state (target TODO, memory registries) or
integrate anything (merge/finish/push). integrate anything (merge/finish/push to `main`/`develop`).
## When NOT to use ## When NOT to use
@@ -79,8 +79,8 @@ Model discipline (the user-fixed invariant behind this mode):
must never be pinned down to an executor tier. must never be pinned down to an executor tier.
- Inside a runner, every dispatched agent keeps the tier this skill - Inside a runner, every dispatched agent keeps the tier this skill
already defines: security-auditor (sonnet frontmatter), the Phase B already defines: security-auditor (sonnet frontmatter), the Phase B
audit (analyzer opus pin or `model="opus"`), doc-syncer (sonnet audit (analyzer opus pin or `model="opus"`), doc-syncer (audit on
frontmatter, its two-mode contract untouched). `model="opus"`, patch on its sonnet frontmatter — BDR-077).
Runner dispatch, one per project: Runner dispatch, one per project:
@@ -91,7 +91,7 @@ Agent(subagent_type="general-purpose",
for EXACTLY ONE project: <absolute path>. Flags: <--report-only|none>. for EXACTLY ONE project: <absolute path>. Flags: <--report-only|none>.
Skip STEP 0/0b (routing) and the global summary — the dispatcher owns Skip STEP 0/0b (routing) and the global summary — the dispatcher owns
them. Every rule of the skill applies unchanged: max 3 iterations, them. Every rule of the skill applies unchanged: max 3 iterations,
never merge/finish/push, scoped commits, report appended to that never merge/finish/push main|develop, scoped commits, report appended to that
project's own .claude/audits/TOUR.md. Return EXACTLY: the project's project's own .claude/audits/TOUR.md. Return EXACTLY: the project's
one-line global-summary row (STEP 3 format), then BRANCH: <name|no one-line global-summary row (STEP 3 format), then BRANCH: <name|no
branch>, then REPORT: <path>.") branch>, then REPORT: <path>.")
@@ -156,9 +156,12 @@ honestly in the summary. Never loop past 3.
MEDIUM/LOW → fix only if local and behavior-preserving, else leave MEDIUM/LOW → fix only if local and behavior-preserving, else leave
`open`. Every fix minimal, CLAUDE.md security defaults apply. `open`. Every fix minimal, CLAUDE.md security defaults apply.
A CRITICAL/HIGH fix that changes the API contract (new required A CRITICAL/HIGH fix that changes the API contract (new required
header/param, changed status codes, moved paths) is still applied — header/param, changed status codes, moved paths) is NOT applied — a
but its report row and the global summary line carry a **BREAKING** breaking change is the human's call (CLAUDE.md: confirm before a
tag, so the human review cannot miss it. breaking change). Its report row becomes
`open — needs decision (BREAKING)` with the proposed patch attached,
and the global summary line carries the **BREAKING** count.
Behaviour-preserving CRITICAL/HIGH fixes stay auto-applied.
4. Commit scoped: `git add <files touched>` (never `-A`), 4. Commit scoped: `git add <files touched>` (never `-A`),
`fix(security): …`. `fix(security): …`.
@@ -196,11 +199,18 @@ honestly in the summary. Never loop past 3.
`.claude/memory/`** — an inferred checkbox is exactly the lie `.claude/memory/`** — an inferred checkbox is exactly the lie
/reconcile exists to catch. The human applies suggestions via /reconcile exists to catch. The human applies suggestions via
`/reconcile` later. `/reconcile` later.
2. **Doc sync** — dispatch doc-syncer in AUTOMATIC (silent) mode: 2. **Doc sync** — two-mode doc-syncer, mirrors /ship-feature STEP 8
public docs only (README, INSTALL, USAGE, CHANGELOG…), never (BDR-077: audit judgment on opus, patch on the sonnet pin):
`.claude/**`, never CLAUDE.md. Commit its `PATCHED_FILES:` via `Agent(subagent_type="doc-syncer", model="opus")` with `MODE: audit`
`bash ~/.claude/lib/doc-commit.sh` when available, else a scoped + `auto-mode scope: <files this tour touched>`; public docs only
`docs: …` commit of exactly those paths. (README, INSTALL, USAGE, CHANGELOG…), never `.claude/**`, never
CLAUDE.md. NONE → done. `[MINOR]` PATCH PLAN → re-dispatch
`Agent(subagent_type="doc-syncer")` (sonnet frontmatter) with
`MODE: patch` + the plan verbatim, then commit its `PATCHED_FILES:`
via `bash ~/.claude/lib/doc-commit.sh` when available, else a scoped
`docs: …` commit of exactly those paths. SIGNIFICANT → not applied:
report row `suggested` with the plan item (the tour has no human
gate mid-run).
### End of iteration ### End of iteration
@@ -231,15 +241,15 @@ order:
| ID | Axis | File | Sev | Finding | Status | | ID | Axis | File | Sev | Finding | Status |
|----|------|------|-----|---------|--------| |----|------|------|-----|---------|--------|
| SEC-1 | security | app.py:17 | high | shell=True + concat | fixed | | SEC-1 | security | app.py:17 | high | shell=True + concat | fixed |
| SEC-2 | security | app.py:14 | high | no authz on POST /backup | fixed — **BREAKING**: new required X-Backup-Token header | | SEC-2 | security | app.py:14 | high | no authz on POST /backup | open — needs decision (BREAKING): new required X-Backup-Token header, patch attached |
| CLN-1 | clean | utils.py:9 | - | dead legacy_md5 | fixed | | CLN-1 | clean | utils.py:9 | - | dead legacy_md5 | fixed |
| REC-1 | reconcile | TODO.md | - | "/health" unchecked, shipped 2d92696 | suggested | | REC-1 | reconcile | TODO.md | - | "/health" unchecked, shipped 2d92696 | suggested |
| DOC-1 | doc | README.md | - | phantom /status endpoint | fixed | | DOC-1 | doc | README.md | - | phantom /status endpoint | fixed |
Checks: pytest PASS, ruff PASS. Residuals: none. Commits: 5. BREAKING: 1 (SEC-2). Checks: pytest PASS, ruff PASS. Residuals: SEC-2 (needs decision). Commits: 4. BREAKING: 1 (SEC-2).
``` ```
Global summary inline, one line per project (append `BREAKING: n` to Global summary inline, one line per project (append `BREAKING: n` to
any project line whose fixes changed an API contract): any project line with contract-changing fixes left open for decision):
``` ```
TOUR COMPLETE — 2026-07-04 TOUR COMPLETE — 2026-07-04
@@ -257,7 +267,10 @@ without that approval — neither this repo's nor any target project's.
## Rules ## Rules
- Branch via the gitflow lib; **never `gitflow finish`, never merge, - Branch via the gitflow lib; **never `gitflow finish`, never merge,
never push** — no exceptions, "the tour is green" is not a signal. never push `main`/`develop`** — "the tour is green" is not a signal.
The chore branch's own commits are pushed by the gitflow hooks
(BDR-095); a `push FAILED` hook warning is a report residual, fixed
with a plain `git push -u origin chore/tour-<date>`.
- Scoped pathspecs only; `git add -A` is forbidden. - Scoped pathspecs only; `git add -A` is forbidden.
- Target TODO.md and target `.claude/memory/` are READ-ONLY. Reconcile - Target TODO.md and target `.claude/memory/` are READ-ONLY. Reconcile
produces suggestions, not edits. produces suggestions, not edits.
@@ -286,12 +299,12 @@ without that approval — neither this repo's nor any target project's.
| One TOUR.md for all projects in the config repo | Each project gets its own `.claude/audits/TOUR.md`. | | One TOUR.md for all projects in the config repo | Each project gets its own `.claude/audits/TOUR.md`. |
| Fixing a behavior-changing "cleanup" finding | That is a bug → BUGS-FOUND.md, untouched code. | | Fixing a behavior-changing "cleanup" finding | That is a bug → BUGS-FOUND.md, untouched code. |
| Scratch audit files left untracked at the end | Delete them in STEP 3.2 — a dirty tree self-blocks the next tour. | | Scratch audit files left untracked at the end | Delete them in STEP 3.2 — a dirty tree self-blocks the next tour. |
| Contract-changing security fix reported as plain "fixed" | Tag **BREAKING** in the row AND the summary line. | | Contract-changing security fix auto-applied | Not applied: row `open — needs decision (BREAKING)` + proposed patch; **BREAKING** count in the summary line. |
## Red flags — STOP ## Red flags — STOP
- About to `Edit` a target project's TODO.md or `.claude/memory/*`. - About to `Edit` a target project's TODO.md or `.claude/memory/*`.
- About to run `gitflow finish`, `git merge`, or `git push`. - About to run `gitflow finish`, `git merge`, or push `main`/`develop`.
- About to `git add -A` or commit on `main`/`develop`. - About to `git add -A` or commit on `main`/`develop`.
- Starting iteration 4, or "just one more loop, it's almost clean". - Starting iteration 4, or "just one more loop, it's almost clean".
- Security phase done without the security-auditor agent and without a - Security phase done without the security-auditor agent and without a
+6 -1
View File
@@ -299,7 +299,12 @@ Options :
D) Abort — keep .claude/audits/VALIDATE.md as audit report D) Abort — keep .claude/audits/VALIDATE.md as audit report
``` ```
4. On `A` : dispatch each file-group's applier at L1 (execution = sonnet; 4. On `A` : gitflow aiguillage FIRST — follow
`$HOME/.claude/lib/gitflow-aiguillage.md`, this skill's TYPE = `feature`
(`--fix` edits code). On `main`/`develop` branch before any edit:
`bash ~/.claude/lib/gitflow.sh start feature web-validate-<slug>`; on a
working branch apply in place. Never `gitflow finish` (human-gated).
Then dispatch each file-group's applier at L1 (execution = sonnet;
this loop only orchestrates), serially — one applier at a time, appliers this loop only orchestrates), serially — one applier at a time, appliers
share files: share files:
-1
View File
@@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# === deploy runbook (reference) — NOT run directly. Instantiated into the deploy checklist per delta. === # === deploy runbook (reference) — NOT run directly. Instantiated into the deploy checklist per delta. ===
# Fixed steps run every deploy; # @delta: steps re-instantiate from the delta. # Fixed steps run every deploy; # @delta: steps re-instantiate from the delta.
# @config push_deploy_tags=false
# NOTE grammar: glob=<pat>:each repeats the command per matching file (e.g. psql -f <each>); # NOTE grammar: glob=<pat>:each repeats the command per matching file (e.g. psql -f <each>);
# glob=<pat>:list runs once + lists matching files as VERIFY items; when=<pat,...> is conditional. # glob=<pat>:list runs once + lists matching files as VERIFY items; when=<pat,...> is conditional.
# Style: one command per line, as typed in an interactive session — step 1 opens # Style: one command per line, as typed in an interactive session — step 1 opens