From d82c06f57257e42015e6e9eef2f547fc27f18f42 Mon Sep 17 00:00:00 2001 From: bastien Date: Thu, 24 Sep 2026 20:25:40 +0200 Subject: [PATCH] =?UTF-8?q?refactor(doctrine):=20C2=20coherence=20?= =?UTF-8?q?=E2=80=94=2030=20doctrine/skill=20tensions=20resolved,=20doctri?= =?UTF-8?q?ne=20wins=20(BDR-099)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- CLAUDE.global.md | 44 ++++++++----- USAGE.md | 5 +- agents/client-handover-writer.md | 100 +++++++++++++++++++++--------- agents/commit-changer.md | 22 ++++--- agents/handover-doc-writer.md | 2 +- agents/release-executor.md | 13 ++-- lib/design-gate.md | 8 +-- lib/gitflow-aiguillage.md | 17 +++-- lib/verify-secure-loop.md | 10 +-- skills/bugfix/SKILL.md | 6 +- skills/capitalize/SKILL.md | 34 +++++----- skills/client-handover/SKILL.md | 6 +- skills/close/SKILL.md | 2 +- skills/commit-change/SKILL.md | 22 +++++-- skills/deploy/SKILL.md | 14 ++--- skills/doc/SKILL.md | 7 +++ skills/feat/SKILL.md | 6 +- skills/gitflow/SKILL.md | 5 +- skills/hotfix/SKILL.md | 21 +++++-- skills/init-project/SKILL.md | 41 +++++++----- skills/onboard/SKILL.md | 49 +++++++++------ skills/pdf-translate/SKILL.md | 11 ++-- skills/refactor/SKILL.md | 6 ++ skills/release-candidate/SKILL.md | 18 +++--- skills/seo/SKILL.md | 7 +++ skills/ship-feature/SKILL.md | 7 ++- skills/tour/SKILL.md | 49 +++++++++------ skills/web-validate/SKILL.md | 7 ++- templates/deploy/PROCEDURE.md | 1 - 29 files changed, 350 insertions(+), 190 deletions(-) diff --git a/CLAUDE.global.md b/CLAUDE.global.md index 724d651..0a1cff9 100644 --- a/CLAUDE.global.md +++ b/CLAUDE.global.md @@ -34,14 +34,16 @@ Apply unless repo-specific instructions override. 2. Either missing → create it first (templates: `~/.claude/templates/memory/`). ## Workflow -- Confirm before implementing only when real trade-offs exist (several - valid approaches, breaking change, destructive action); else proceed. - Minimal changes unless a broader refactor is requested. State trade-offs. +- Confirm the approach only when real trade-offs exist (several valid + approaches, breaking change, destructive action); ask on the visible, + 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 independent, sizeable tracks (wide multi-file exploration, parallel - audits), not work doable in a few tool calls. Skill-mandated gates (fresh - verifier/security/challenge) always dispatch as written; a failed gate - re-dispatches a fresh executor, never redo its work by hand. A brief never + audits), not work doable in a few tool calls. Skill-mandated executors and + gates (pinned executors, fresh verifier/security/challenge) always dispatch + 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 repo (Security → Destructive tools & data loss). - 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 config value — the `/hotfix` scope (≤2 files, obvious fix). - 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 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. 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. -Legacy entries: compress on demand. +Legacy entries: compress on demand via `/prune-memory`. **Proactive capitalization** is Claude's job: after a substantive milestone (root-caused bug fix, shipped feature, non-trivial commit, design choice, 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 their CAPITALIZE step. Session close (`/close` = `/capitalize --ritual`): what was decided → decisions, learned → learnings, blocked → blockers. @@ -137,20 +142,24 @@ never bent to match a newer one. ## Version control — gitflow (universal) Every git action follows gitflow, inside a skill or for an ad-hoc commit. `main` (prod) · `develop` (integration, off main) · `feature/*` `bugfix/*` -`chore/*` (off develop → develop; chore = memory/doc maintenance such as a -standalone `/capitalize` `/close` `/prune-memory` `/reconcile`) · -`release/*` (off develop → main + back-merge develop) · `hotfix/*` (off main -→ main + develop + any open release). `master` → `main` everywhere. +`chore/*` (off develop → develop; chore = maintenance without new behaviour: +memory, docs, cleanup, `/refactor`, `/tour` fixes) · `release/*` (off develop +→ main + back-merge develop) · `hotfix/*` (off main → main + develop + any +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 `/` -(`.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 start ` · `finish` · `delete
`. `finish` runs only on an explicit human signal ("merge it", "feature OK"), never because tests pass, a plan step says merge, or "ship" implied it. Assistance flows (`/feat` `/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 -they branch to `chore/*` via the aiguillage, not the `.claude/**` exemption. +protected base but commit in place on a working branch, never finishing +(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 code commits on main/develop; exempts `.claude/**`, `.githooks/**`, merges, 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 ecosystem (cross-project learnings, /freeze, long open-ended investigation) - 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 - Grouped all-axes sweep ("tir groupé", fix + loop until clean) → tour - Open-work inventory / "queue empty?" / stale TODO vs git → reconcile diff --git a/USAGE.md b/USAGE.md index c20feec..0393523 100644 --- a/USAGE.md +++ b/USAGE.md @@ -262,7 +262,7 @@ cd mon-projet-existant/ | 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.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 | | 6 | Audits parallèles selon archétype : | .onboard-audit/*.md (9 fichiers max) | | | — dette tech (general-purpose, audit read-only) | @@ -280,7 +280,6 @@ cd mon-projet-existant/ ``` /onboard "Python FastAPI" # hint stack /onboard force-archetype:wordpress # override detection -/onboard add gsd # générer ROADMAP.md pour GSD v2 (seul) ``` **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é # (indiqué dans .claude/tasks/TODO.md) /hotfix "" # 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. diff --git a/agents/client-handover-writer.md b/agents/client-handover-writer.md index c8883d1..6b0af6b 100644 --- a/agents/client-handover-writer.md +++ b/agents/client-handover-writer.md @@ -61,7 +61,7 @@ and degrading Google's NAP-consistency signal. Pipeline (each step gates the next): 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. 4. Deploy pause: list deploy artifacts + process, wait for user confirmation. 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 | |---------------|-------------------|-----------------| -| 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." | -| 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." | +| 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 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: | 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). @@ -370,7 +370,12 @@ iteration = 1 # HARDEN/CSO/VALIDATE loops use only their own score. while (audit == "SEO" ? (SCORE_SEO < 17 OR SCORE_GEO < 17) : score < 17) \ 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 if no scores improved AND no files changed → break (no progress) # 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 (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: [SEO|GEO|HARDEN] → — `. + ### Re-dispatch prompt template (SEO + GEO loop) 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: > - **SEO classique: ``/20** (threshold 17/20 — ``) > - **GEO (IA): ``/20** (threshold 17/20 — ``) @@ -398,34 +435,33 @@ Send to `general-purpose` subagent (`model: "fable"`): > Iteration `` of ``. Both axes are gated independently; > 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 -> autonomous fixes (do not skip "easy" ones). Prioritize fixes for the -> axis currently below threshold: -> - SEO classique fixes: meta tags, headings, canonical, sitemap.xml, +> Read `.claude/audits/SEO.md` for the current issue list. Prioritize +> bundle items for the axis currently below threshold (do not drop "easy" +> ones): +> - SEO classique: meta tags, headings, canonical, sitemap.xml, > 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 > extraction (QAPage, Speakable, Person+Article, HowTo, Organization > graph), entity SEO (sameAs, @id), TL;DR / definition-lead content > shape, citable stats markup, freshness signals. > -> For each fix applied, append a line to `.claude/audits/SEO-FIX-LOG.md` -> (format: `iter: [SEO|GEO] → — `). Update -> `.claude/audits/SEO.md` with the new scores — both labeled lines MUST -> 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. +> Update `.claude/audits/SEO.md` with the new scores — both labeled lines +> MUST be present: `Score SEO (classique) : X.X / 20` and +> `Score GEO (IA) : X.X / 20`, plus the weighted global. ### Re-dispatch prompt template (HARDEN loop) 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: > **``/20** — below threshold. Iteration `` of -> ``. Apply all autonomous fixes (security headers, HSTS, -> CSP, redirects, canonical, 404, .htaccess/nginx/vercel/netlify config). -> Append entries to `.claude/audits/HARDEN-FIX-LOG.md`. Update -> `.claude/audits/HARDEN.md` with new score. +> ``. The `## 8. Fix bundle` MUST cover security headers, +> HSTS, CSP, redirects, canonical, 404, .htaccess/nginx/vercel/netlify +> config. Update `.claude/audits/HARDEN.md` with the new score. ### 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**. > Previous score: **``/20** — below threshold. -> Iteration `` of ``. Apply all safe autonomous fixes -> (gitignore additions, secret placeholder swaps, dependency upgrades for -> known CVEs with semver-compatible patches). Append entries to -> `.claude/audits/CSO-FIX-LOG.md`. Update `.claude/audits/CSO.md` with -> new score. +> Iteration `` of ``. Apply NOTHING: return the fixes as +> a FIX BUNDLE in `.claude/audits/CSO.md` — gitignore additions and secret +> placeholder swaps tagged AUTO, dependency upgrades (even semver-compatible +> CVE patches) tagged GATED. The handover main loop applies AUTO items and +> gates the rest (see 'Applying the bundle'). Update `.claude/audits/CSO.md` +> with the new score. ### 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, wait for both, re-parse both scores, decide whether each loop continues, 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 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 @@ -627,7 +666,8 @@ Dispatch `general-purpose` subagent (`model: "fable"`): > Read `~/.claude/skills/web-validate/SKILL.md` and execute against the > deployed URL: ``. Audit W3C HTML validity (validator.nu), > 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` > with `Score: X/20` (or `X/100`) at the top. diff --git a/agents/commit-changer.md b/agents/commit-changer.md index 211a66a..0acf231 100644 --- a/agents/commit-changer.md +++ b/agents/commit-changer.md @@ -42,10 +42,13 @@ approval gates live in the `/commit-change` dispatcher, not here. ### Phase 0: Gitflow aiguillage (before any commit) -**Follow `$HOME/.claude/lib/gitflow-aiguillage.md` — your type = `chore`.** -On `main`/`develop` it branches first (to `chore/` derived -from the pending work) so the commits never land directly on a protected -base; on a working branch it's a no-op (commit in place). Never `finish`, +**Follow `$HOME/.claude/lib/gitflow-aiguillage.md` — your type = the `TYPE:` +line of the dispatch prompt (`feature` / `bugfix` / `chore`, chosen by the user +in the dispatcher; never hardcode `chore`).** On `main`/`develop` it branches +first (to `/` 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 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 @@ -146,8 +149,9 @@ criteria as the standalone `/capitalize` flow: fix** (a pattern, a gotcha, a surprising API behaviour) → draft an entry for `.claude/memory/learnings.md` (LRN-XXX). -**Language rule**: draft entries in English (see CLAUDE.md "Memory -registries" § Language) — the dispatcher's approval exchange may mirror the +**Language rule**: draft entries in English AND caveman — fragments, +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 `MODE: apply` if approved unedited. @@ -225,9 +229,9 @@ Otherwise: (`.claude/memory/decisions.md`, `blockers.md`, `learnings.md`) and update each file's `## Index` table. Add a one-line summary of the commit batch to today's heading in `.claude/memory/journal.md`. -3. **Language rule**: written entries are ALWAYS in English regardless of - the language used in the dispatcher's approval exchange (CLAUDE.md - "Memory registries" § Language). +3. **Language rule**: written entries are ALWAYS in English and caveman, + regardless of the language used in the dispatcher's approval exchange + (CLAUDE.md "Memory registries", Always English, always caveman). 4. **Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it surgically commits what was just written (`.claude/memory` + `.claude/tasks` only, never diff --git a/agents/handover-doc-writer.md b/agents/handover-doc-writer.md index 0575dd2..85d7e36 100644 --- a/agents/handover-doc-writer.md +++ b/agents/handover-doc-writer.md @@ -130,7 +130,7 @@ concrete, no jargon. One short paragraph per idea. [§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` extension as fallback). Both auto-generate heading IDs in the GitHub-style slug: diff --git a/agents/release-executor.md b/agents/release-executor.md index fe68feb..101c2f9 100644 --- a/agents/release-executor.md +++ b/agents/release-executor.md @@ -9,7 +9,7 @@ model: sonnet You execute the mechanical parts of a gitflow release. The `/release-candidate` dispatcher owns every judgment call — the version number, the "is it time to -release" decision, and both pushes — and owns the human gate that sits BETWEEN +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 call: after `SPAN: prep` reports, the dispatcher stops for a human go before 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. 2. **Tag AFTER finish, on `main`** — never before: `git tag -a v main -m "release "` (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 -`git push` (any remote, any ref — the dispatcher owns the push gate), -deciding the version number, the when-to-release decision, attribution -trailers of any kind. +`git push` (any remote, any ref — `main`/`develop` ride the lib's hook +pushes during finish; the dispatcher owns the tag-push gate), deciding the +version number, the when-to-release decision, attribution trailers of any +kind. --- diff --git a/lib/design-gate.md b/lib/design-gate.md index 01b1ff6..ed385af 100644 --- a/lib/design-gate.md +++ b/lib/design-gate.md @@ -17,11 +17,11 @@ Check BOTH the task description AND the filesystem: - Framework UI: `tailwind`, `styled-component`, `emotion`, `chakra`, `radix`, `shadcn`, `headless` **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 - `tokens/`, `theme/`, or `design-system/` directory exists - 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 @@ -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 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, -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 canary for the whole 21st skill pack). The profile also bundles 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: -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. Evaluate it on the same path as §4: after the toolchain resolves, never on the diff --git a/lib/gitflow-aiguillage.md b/lib/gitflow-aiguillage.md index a51f0d8..196f4b9 100644 --- a/lib/gitflow-aiguillage.md +++ b/lib/gitflow-aiguillage.md @@ -21,11 +21,14 @@ The caller passes its TYPE: |--------|------|------| | `/feat` | `feature` | 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 | +| `/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 -reconciliation & curation skills, run OUTSIDE an assistance flow. Inside `/feat` +The `chore` rows = **standalone memory/doc/hygiene work**: the registry / TODO / +doc reconciliation & curation skills (+ `/refactor`), run OUTSIDE an assistance flow. Inside `/feat` `/bugfix` `/hotfix` `/ship-feature` a working branch already exists (this check 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, @@ -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` + `/reconcile` stay fully human-gated: never run `gitflow finish` from them. -Note: `hotfix` branches off **main** (prod) even when invoked from `develop` — that -is the gitflow definition of a hotfix. For a dev-scoped small fix, use `/bugfix` -(branches off develop). +Note: a `hotfix/*` branch forks off **main** (prod) and fans out to main + develop +at finish — that is the gitflow definition of a hotfix. Invoked from `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. diff --git a/lib/verify-secure-loop.md b/lib/verify-secure-loop.md index 12a37ca..cd37cbe 100644 --- a/lib/verify-secure-loop.md +++ b/lib/verify-secure-loop.md @@ -59,9 +59,9 @@ Parse its single `VERIFY — VERDICT:` line: - `CONFORME` → go to GATE 2. (First-pass conforme = no loop.) - `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; - a dispatched dev is re-dispatched FRESH with those inputs only. Then - re-run GATE 0 and re-dispatch a FRESH verifier. Repeat. + lines (NOT-MET / out-of-scope), nothing else: re-dispatch a FRESH executor + with those inputs only, never redo the fix by hand. Then re-run GATE 0 and + re-dispatch a FRESH verifier. Repeat. **Max 3 conformity iterations** → STOP + human escalation with the CRITERIA table (the contract-vs-realized diff). - `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: - `PASS` → done, proceed to commit. -- `BLOCK(n)` → hand the dev the `BLOCKING` list + the CONTRACT path (inline - fix, or FRESH executor re-dispatch). Then re-run GATE 0, then +- `BLOCK(n)` → hand the dev the `BLOCKING` list + the CONTRACT path + (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 can drift the behavior — **then re-run GATE 2** (fresh auditor), in that order. **Max 3 security iterations** → STOP + human escalation with the diff --git a/skills/bugfix/SKILL.md b/skills/bugfix/SKILL.md index bbd730b..f74941f 100644 --- a/skills/bugfix/SKILL.md +++ b/skills/bugfix/SKILL.md @@ -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`. -**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`. @@ -287,7 +287,9 @@ hash, and no-ops if nothing was written. - No fix without understanding the root cause first (STEP 2/3). - Reflection (GATHER, INVESTIGATE, DIAGNOSIS, contract, loop decisions) NEVER leaves this main loop; execution NEVER stays in it — the executor is the - sonnet-pinned bugfixer subagent (BDR-066). + 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, ECARTS, BLOCK) — feedback travels as contract path + named gaps/decisions, never as transcript. diff --git a/skills/capitalize/SKILL.md b/skills/capitalize/SKILL.md index 547e91b..c637b7c 100644 --- a/skills/capitalize/SKILL.md +++ b/skills/capitalize/SKILL.md @@ -9,7 +9,7 @@ description: | Triggers: "capitalize", "before clear/compact", "flush memory", "don't lose this", "avant de clear/compact", "capitalise ce qui manque", "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/: pushed to origin by the hooks, NOT merged (finish skipped), merge when ready; default = auto-finish into develop)" allowed-tools: - Read - Edit @@ -65,17 +65,22 @@ ls .claude/memory/decisions.md .claude/memory/learnings.md \ ls .claude/tasks/TODO.md 2>/dev/null ``` -- `.claude/memory/` missing entirely → print and STOP (do NOT create here — - that is `/onboard` / `/init-project` responsibility): - ``` - ⚠️ .claude/memory/ absent. Lance `/onboard` (ou `/init-project`) pour créer - les registres avant de capitaliser. +- `.claude/memory/` missing entirely → create it first (CLAUDE.md "Session + start": either missing → create from the templates), then proceed: + ```bash + mkdir -p .claude/memory + 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 `~/.claude/templates/memory/.md`, continue. -- `.claude/tasks/TODO.md` missing → the TODO reconcile volet (STEP 2B) is - **skipped**. Do NOT create it (same posture as the registries). Registries - still run. +- `.claude/tasks/TODO.md` missing → create a minimal one, then run the TODO + reconcile volet (STEP 2B) on it: + ```bash + mkdir -p .claude/tasks + printf '# TODO\n\n## %s\n' "$(date +%Y-%m-%d)" > .claude/tasks/TODO.md + ``` ## STEP 1 — SCAN THE CONVERSATION @@ -164,7 +169,7 @@ concatenated class names" entry.) ## 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 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 (`` = `Contex flushed` for pre-wipe, `Session closed` for ritual): - **auto-persisted (default — branched off develop, pushed)** → `✅ + persisted to origin/develop (). Next session: read .claude/memory/ at startup.` -- **--no-push (held on branch)** → `✅ + committed on chore/, NOT pushed (--no-push). Merge + push when ready.` +- **--no-push (held on branch)** → `✅ + committed on chore/ — pushed to origin by the hooks, NOT merged (--no-push: finish skipped). Merge when ready.` - **push failed after merge** → `✅ + merged to develop — ⚠️ push FAILED (); merged locally, push manually.` - **WORKING branch (rode a feature branch)** → `✅ + committed on . Integrates when the branch merges.` - **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. - **Caveman English** registry bodies, always English. **The TODO is plain 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 / umbrella / vague → leave unchecked. Never on assumption. - **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 a branch the run did not create. - **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 @@ -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. | | 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. | -| 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 diff --git a/skills/client-handover/SKILL.md b/skills/client-handover/SKILL.md index dad6e8b..8d07813 100644 --- a/skills/client-handover/SKILL.md +++ b/skills/client-handover/SKILL.md @@ -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. 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: - - Re-invoke the audit subagent with explicit instruction to apply auto-fixes. - - Re-score. + - 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-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). - 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`. @@ -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). - **§7 Annexe — plateformes externes** (web/local-business only). - **§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: - `--skip-fix-loop` — run baseline audits once, skip auto-fix iterations. diff --git a/skills/close/SKILL.md b/skills/close/SKILL.md index 05497a9..014faef 100644 --- a/skills/close/SKILL.md +++ b/skills/close/SKILL.md @@ -8,7 +8,7 @@ description: | (that is /prune-memory). Triggers: "close", "end session", "ferme la session", "session close", "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/: pushed to origin by the hooks, NOT merged (finish skipped), merge when ready; default = auto-finish into develop)" allowed-tools: - Read - Edit diff --git a/skills/commit-change/SKILL.md b/skills/commit-change/SKILL.md index 6d8d8e2..f2b2579 100644 --- a/skills/commit-change/SKILL.md +++ b/skills/commit-change/SKILL.md @@ -45,16 +45,28 @@ git config user.email - `git config user.email` empty → STOP, ask the user to configure identity first, do not dispatch. -On a protected base (`main`/`develop`) the subagent runs the gitflow -aiguillage itself inside `MODE: propose` (its Phase 0) and branches to -`chore/*` before drafting the plan — code never lands directly on a -protected branch. +On a protected base (`main`/`develop` — `bash "$HOME/.claude/lib/gitflow.sh" +protected-base`) ask the user the branch TYPE before any dispatch — a branch +name is a public name: + +``` +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: ` in the STEP 1 prompt — the subagent runs the aiguillage with it +inside `MODE: propose` (its Phase 0) and branches to `/*` 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 ``` Agent(subagent_type="commit-changer", model="opus") prompt: "MODE: propose +TYPE: $ARGUMENTS" ``` @@ -86,7 +98,7 @@ AskUserQuestion: BDR-077 — never redrawn inline on the session model); show the redrawn plan and re-ask. - `skip` → exit cleanly, no commits created, no `MODE: apply` dispatch. - Note: if the propose run created a `chore/*` branch (gitflow aiguillage + Note: if the propose run created a `/*` branch (gitflow aiguillage off a protected base), that branch stays checked out with the work uncommitted — mention it so the user isn't surprised by the branch switch. diff --git a/skills/deploy/SKILL.md b/skills/deploy/SKILL.md index d8762d0..084be65 100644 --- a/skills/deploy/SKILL.md +++ b/skills/deploy/SKILL.md @@ -182,7 +182,6 @@ Author a runbook, seed the incident ledger, commit both, then proceed to STEP 1. #!/usr/bin/env bash # === 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. - # @config push_deploy_tags=false ``` 3. Scan for migration, rebuild, and dependency steps; propose `@delta:` annotations inline: - 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` | | Health-check URL | "Health-check URL (expects HTTP 200)?" | `https://$DEPLOY_HOST/health` | | 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: - 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. -- Set `# @config push_deploy_tags=` in the header. - Append the rollback note as `# ROLLBACK: ` at the end if provided. → **[GATE]** below. @@ -427,9 +424,7 @@ Then: The deploy succeeded. Lay the oracle and close out. -1. Read `# @config push_deploy_tags=` from the `PROCEDURE.md` header (default - `false`). Pick `date = today` (`YYYY-MM-DD`); if `deploy/` exists, suffix - `-N`. +1. Pick `date = today` (`YYYY-MM-DD`); if `deploy/` exists, suffix `-N`. 2. Write `.claude/deploy/STATE.json` (overwrite): ```jsonc { "deployed_sha": "", "deployed_at": "", @@ -438,9 +433,10 @@ The deploy succeeded. Lay the oracle and close out. **`deployed_sha` = `PENDING.target_sha`, NOT current HEAD** — HEAD may have moved during the gap; the bridge's target is the deployed truth. 3. `git tag -a deploy/ -m ""`. -4. If `push_deploy_tags=true` → `git push origin deploy/` — **best-effort, - non-fatal**: a push failure logs a warning, never blocks the mark (the tag is a - bookmark; `STATE.json` is the oracle). +4. No separate tag push: the oracle commit (step 5) fires the gitflow + post-commit hook, which pushes with `--follow-tags`, so `deploy/` + 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: ```bash bash ~/.claude/lib/deploy-commit.sh commit "chore(deploy): mark @ " \ diff --git a/skills/doc/SKILL.md b/skills/doc/SKILL.md index 11a89b1..db4d8e1 100644 --- a/skills/doc/SKILL.md +++ b/skills/doc/SKILL.md @@ -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 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/` 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: `Agent(subagent_type="doc-syncer", model="opus")` prompt: "MODE: audit. Audit public docs for this project. Context from diff --git a/skills/feat/SKILL.md b/skills/feat/SKILL.md index 65393be..16dce74 100644 --- a/skills/feat/SKILL.md +++ b/skills/feat/SKILL.md @@ -244,7 +244,7 @@ Valider ? (all / / edit / skip) Always append a 1-line entry to today's heading in `.claude/memory/journal.md`. -**Language rule**: written entries are ALWAYS in English (see CLAUDE.md "Memory registries" § Language). The interactive gate may mirror the user's language; the appended entries must not. +**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`. @@ -259,7 +259,9 @@ hash, and no-ops if nothing was written. - Max 5 files. If more needed → `/ship-feature`. - Reflection (scope, plan, contract, loop decisions) NEVER leaves this main loop; execution NEVER stays in it — the executor is the sonnet-pinned - feater subagent (BDR-066). + 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 as contract path + named gaps/decisions, never as transcript. - Design gate only (not full plugin check). See STEP 0.5. diff --git a/skills/gitflow/SKILL.md b/skills/gitflow/SKILL.md index 42a1c39..efc9109 100644 --- a/skills/gitflow/SKILL.md +++ b/skills/gitflow/SKILL.md @@ -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`) call `start ` 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: -`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) diff --git a/skills/hotfix/SKILL.md b/skills/hotfix/SKILL.md index d08682c..2e55596 100644 --- a/skills/hotfix/SKILL.md +++ b/skills/hotfix/SKILL.md @@ -64,8 +64,11 @@ disposition required at hotfix weight. Follow `$HOME/.claude/lib/design-gate.md`: - Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, styling, animation). -- If signals found → run `design-tool-gate.sh`; if it reports INCOMPLETE, - tell the user to run `/profile design` before proceeding. +- Signals found → a hotfix is the trivial tier by definition (≤2 files, one + 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). ## STEP 1.7 — CONTRACT (silent autofill) @@ -104,8 +107,12 @@ verify+secure loop). ## STEP 2 — PRE-FLIGHT **Gitflow aiguillage (before dispatch):** follow `$HOME/.claude/lib/gitflow-aiguillage.md` -— your type = `hotfix`. On `main`/`develop` it branches first; on a working -branch it's a no-op (commit in place). Never `finish`. +— your type follows the base: on `main` → `hotfix` (prod incident; finish fans +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: @@ -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). -**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 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`. - Reflection (LOCATE, contract, gate decisions) NEVER leaves this main loop; execution NEVER stays in it — the executor is the sonnet-pinned - hotfixer subagent (BDR-066). + 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 a failed or blocked attempt (it reverts and escalates to `/bugfix`, it does not retry). Sole exception: a class-tagged BLOCKED answered by the diff --git a/skills/init-project/SKILL.md b/skills/init-project/SKILL.md index 3e603b2..239f702 100644 --- a/skills/init-project/SKILL.md +++ b/skills/init-project/SKILL.md @@ -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 — resolve here, re-dispatch. The ~30s liveness pings are THIS loop's job 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. ## STEP 5b — CREATE README @@ -166,7 +173,7 @@ layout and the deterministic root commit: bash "$HOME/.claude/lib/gitflow.sh" init "chore: scaffold " ``` 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. This is the deterministic scaffold commit owner (closes BLK-010). The MVP is 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 this loop. -## STEP 8b — GRAPHIFY FULL (after implementation) -If `graphify` CLI is installed AND complexity >= 30%: -1. Run full graphify on the implemented project: - ```bash - graphify . --out graphify-out 2>/dev/null || true - ``` -2. Print: `🔗 Full project graph updated at graphify-out/` -If `graphify` not installed or complexity < 30% → skip silently. +## STEP 8b — GRAPHIFY SIGNAL (after implementation — BDR-097) +graphify is proposed only from 200 tracked code files, and the USER decides — +never build, install or update a graph here: +```bash +bash ~/.claude/lib/graphify-gate.sh . +``` +- Prints a line → carry it into the FINAL OUTPUT status table as + `GRAPHIFY: — /graphify on your go`. +- Silent → `GRAPHIFY: below 200 code files, not proposed`. ## STEP 9 — VERIFY + SECURE (fresh gates, bounded loops) 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 — — <1-line why> Valider lesquels ? (all / / 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.** 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 anchored commit ceases to exist. -**Language rule**: written entries are ALWAYS in English (CLAUDE.md "Memory -registries"). The gate may mirror the user's language; 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 gate may mirror the user's +language; entries must not. **Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it surgically commits the approved founding decisions (`.claude/memory` + @@ -369,5 +381,6 @@ LOCATION: | STACK: | BUILD: ✅/❌ | TESTS: ✅/❌ V1 FEATURES: ✅ / ⚠️ partial: REMAINING ISSUES: QUICK START: -CLAUDE.md ✅ | README ✅ | SETTINGS ✅ +CLAUDE.md ✅ | README ✅ | SETTINGS ✅ | MEMORY ✅ +GRAPHIFY: ``` diff --git a/skills/onboard/SKILL.md b/skills/onboard/SKILL.md index 96f2c69..b3ae11c 100644 --- a/skills/onboard/SKILL.md +++ b/skills/onboard/SKILL.md @@ -1,7 +1,7 @@ --- 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".' -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 --- @@ -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. - OK → `✅ Plugin check passed — [active plugins] — complexity: %`, 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` - `.gitignore` (safety check) - `.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. @@ -151,11 +152,13 @@ Adopter le modèle gitflow sur ce repo existant : ```bash bash "$HOME/.claude/lib/gitflow.sh" init ``` -Sur un repo existant, cela : renomme `master`→`main` si besoin (LOCAL), crée -`develop` depuis main, réconcilie le socle `.gitignore` (additif — n'écrase -jamais les règles du projet), installe le hook pre-commit versionné, et fait UN -commit `chore: adopt gitflow socle + pre-commit hook` sur main (pendant que le hook est -inactif → jamais auto-bloqué). Idempotent — un re-run est un no-op. +Sur un repo existant, cela : renomme `master`→`main` si besoin (LOCAL), pose le +socle (`.gitignore` réconcilié — additif, n'écrase jamais les règles du projet — ++ `.githooks/` versionnés) sur une branche `chore/gitflow-adopt` créée depuis +main, la merge `--no-ff` dans main (le hook pre-commit est global sur la machine +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 ; 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 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)` -- **Complexity < 30%** → skip silencieusement, projet trop petit pour justifier. -- **Graphe déjà présent + récent** (fichier < 7j) → skip, réutiliser l'existant. -- **Sinon** → run : +- **`graph-exists`** → skip, réutiliser l'existant. +- **La gate n'imprime rien** → moins de 200 fichiers code trackés (BDR-097 : + 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 - 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)`. @@ -937,7 +948,7 @@ Choix ? (A / B / C / D / E) **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. - **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. @@ -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. - 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 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/.md`. - STEP 6 dispatches parallélisables : regrouper dans un seul message Agent multi-calls. - `.onboard-audit/` gitignoré automatiquement — ne jamais commiter. @@ -1035,7 +1046,7 @@ ARCHETYPE : (confiance: ) STACK : CONFIG : ✅ CLAUDE.md, settings.json, .claudeignore, .claude/{tasks,memory,audits}/ 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 : ✅ dette technique (.onboard-audit/analyze.md + code-clean.md) ✅ sécurité (.onboard-audit/cso.md) @@ -1055,6 +1066,6 @@ SYNTHÈSE : NEXT STEPS : 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é - 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) ``` diff --git a/skills/pdf-translate/SKILL.md b/skills/pdf-translate/SKILL.md index 8f26582..44b5d7c 100644 --- a/skills/pdf-translate/SKILL.md +++ b/skills/pdf-translate/SKILL.md @@ -28,14 +28,17 @@ digraph pipeline { ## 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 -# Option A: poppler (lighter) -command -v pdftoppm && echo "OK" || echo "INSTALL: sudo apt install poppler-utils" +# Option A: poppler (lighter) — USER runs the install +command -v pdftoppm && echo "OK" || echo "USER RUNS: sudo apt install poppler-utils" # 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. diff --git a/skills/refactor/SKILL.md b/skills/refactor/SKILL.md index e0ae675..67e5abd 100644 --- a/skills/refactor/SKILL.md +++ b/skills/refactor/SKILL.md @@ -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 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-` +and dispatch on the new branch; on a working branch dispatch in place. Never +`gitflow finish` — integration is human-gated. + ``` Agent(subagent_type="refactorer") prompt: "Refactor to strict project norms, preserving external behavior diff --git a/skills/release-candidate/SKILL.md b/skills/release-candidate/SKILL.md index 95d1220..bafc6fc 100644 --- a/skills/release-candidate/SKILL.md +++ b/skills/release-candidate/SKILL.md @@ -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 the executor must never own: the version-NUMBER decision (judgment — derives from semver change nature), and the two human gates (when to release, and -the push). A human gate sits BETWEEN the two spans by construction, so the +the tag push). A human gate sits BETWEEN the two spans by construction, so the executor is never dispatched twice in one call. ## 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, not an auto-retry. -### STEP 6 — Push GATE (ASK) -STOP. On explicit go only ([[LRN-069]]) — run the push HERE, in this -dispatcher, never delegated to the executor: +### STEP 6 — Tag push GATE (ASK) +`main` and `develop` are already on origin: the lib pushes every merge as +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: - Push main, develop, and v to origin? — go / hold + Push tag v to origin? — go / hold ``` Go → ```bash -git push origin main develop && git push origin v +git push origin v ``` -`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 - 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. - 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 `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). diff --git a/skills/seo/SKILL.md b/skills/seo/SKILL.md index 843bf6b..c7206f5 100644 --- a/skills/seo/SKILL.md +++ b/skills/seo/SKILL.md @@ -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 / 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-`; on a working +branch apply in place. Never `gitflow finish` — integration is human-gated. + ### Serial by ownership (no parallel race) The two bundles may touch the same shared template (meta vs JSON-LD). Apply diff --git a/skills/ship-feature/SKILL.md b/skills/ship-feature/SKILL.md index 2803514..bc01d3e 100644 --- a/skills/ship-feature/SKILL.md +++ b/skills/ship-feature/SKILL.md @@ -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 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 -ls .gsd/ROADMAP.md 2>/dev/null | head -1 +# gsd-pi ≥ 3: state in .gsd/STATE.md + gsd.db + milestones//-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): ``` @@ -41,7 +42,7 @@ ls .gsd/ROADMAP.md 2>/dev/null | head -1 Stack : Branch : Recent : - GSD : + GSD : ``` Continue to STEP 1. - **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. 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. diff --git a/skills/tour/SKILL.md b/skills/tour/SKILL.md index 5239235..b334aac 100644 --- a/skills/tour/SKILL.md +++ b/skills/tour/SKILL.md @@ -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 state.** The skill may edit code freely on its own branch; it may NOT 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 @@ -79,8 +79,8 @@ Model discipline (the user-fixed invariant behind this mode): must never be pinned down to an executor tier. - Inside a runner, every dispatched agent keeps the tier this skill already defines: security-auditor (sonnet frontmatter), the Phase B - audit (analyzer opus pin or `model="opus"`), doc-syncer (sonnet - frontmatter, its two-mode contract untouched). + audit (analyzer opus pin or `model="opus"`), doc-syncer (audit on + `model="opus"`, patch on its sonnet frontmatter — BDR-077). Runner dispatch, one per project: @@ -91,7 +91,7 @@ Agent(subagent_type="general-purpose", for EXACTLY ONE project: . Flags: <--report-only|none>. Skip STEP 0/0b (routing) and the global summary — the dispatcher owns 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 one-line global-summary row (STEP 3 format), then BRANCH: , then REPORT: .") @@ -156,9 +156,12 @@ honestly in the summary. Never loop past 3. MEDIUM/LOW → fix only if local and behavior-preserving, else leave `open`. Every fix minimal, CLAUDE.md security defaults apply. A CRITICAL/HIGH fix that changes the API contract (new required - header/param, changed status codes, moved paths) is still applied — - but its report row and the global summary line carry a **BREAKING** - tag, so the human review cannot miss it. + header/param, changed status codes, moved paths) is NOT applied — a + breaking change is the human's call (CLAUDE.md: confirm before a + 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 ` (never `-A`), `fix(security): …`. @@ -196,11 +199,18 @@ honestly in the summary. Never loop past 3. `.claude/memory/`** — an inferred checkbox is exactly the lie /reconcile exists to catch. The human applies suggestions via `/reconcile` later. -2. **Doc sync** — dispatch doc-syncer in AUTOMATIC (silent) mode: - public docs only (README, INSTALL, USAGE, CHANGELOG…), never - `.claude/**`, never CLAUDE.md. Commit its `PATCHED_FILES:` via - `bash ~/.claude/lib/doc-commit.sh` when available, else a scoped - `docs: …` commit of exactly those paths. +2. **Doc sync** — two-mode doc-syncer, mirrors /ship-feature STEP 8 + (BDR-077: audit judgment on opus, patch on the sonnet pin): + `Agent(subagent_type="doc-syncer", model="opus")` with `MODE: audit` + + `auto-mode scope: `; public docs only + (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 @@ -231,15 +241,15 @@ order: | ID | Axis | File | Sev | Finding | Status | |----|------|------|-----|---------|--------| | 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 | | REC-1 | reconcile | TODO.md | - | "/health" unchecked, shipped 2d92696 | suggested | | 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 -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 @@ -257,7 +267,10 @@ without that approval — neither this repo's nor any target project's. ## Rules - 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-`. - Scoped pathspecs only; `git add -A` is forbidden. - Target TODO.md and target `.claude/memory/` are READ-ONLY. Reconcile 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`. | | 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. | -| 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 - 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`. - Starting iteration 4, or "just one more loop, it's almost clean". - Security phase done without the security-auditor agent and without a diff --git a/skills/web-validate/SKILL.md b/skills/web-validate/SKILL.md index 5e5ebed..7168333 100644 --- a/skills/web-validate/SKILL.md +++ b/skills/web-validate/SKILL.md @@ -299,7 +299,12 @@ Options : 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-`; 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 share files: diff --git a/templates/deploy/PROCEDURE.md b/templates/deploy/PROCEDURE.md index a4d4103..d8aca95 100644 --- a/templates/deploy/PROCEDURE.md +++ b/templates/deploy/PROCEDURE.md @@ -1,7 +1,6 @@ #!/usr/bin/env bash # === 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. -# @config push_deploy_tags=false # NOTE grammar: glob=:each repeats the command per matching file (e.g. psql -f ); # glob=:list runs once + lists matching files as VERIFY items; when= is conditional. # Style: one command per line, as typed in an interactive session — step 1 opens