diff --git a/.claude/memory/decisions.md b/.claude/memory/decisions.md index 9c187b1..9a0639c 100644 --- a/.claude/memory/decisions.md +++ b/.claude/memory/decisions.md @@ -990,4 +990,5 @@ rules: - **Caveat (execution)**: /feat re-arch broke 5 stale assertions in lib/tests/loops-light.test.sh (locked OLD feater architecture) — repointed to skills/feat/SKILL.md (FSK, mirrors HOT/HSK split) + new dispatch lock + 1-line reflow in feat SKILL for single-line grep lock (LRN-093 class). - **Wave 2 (2026-07-15, user directive)**: wave-1 exclusion list left execution running on the big session model = the waste this split kills. REVERSES the "split hotfix rejected" alternative above (reason held for bugfix — investigation interleaved w/ fix — but NOT hotfix: LOCATE→apply is linear/separable). Changes: /hotfix split like /feat (LOCATE reflection inline + MODEL GATE, hotfixer sonnet EXECUTOR — rewritten dual-use: also the seo/geo/web-validate L1 applier; revert-not-loop preserved) → hotfix JOINS gated group, census 12→13. /commit-change dispatches sonnet commit-changer (propose→dispatcher gates→apply; grouping ON sonnet so NO model gate; AskUserQuestion dropped from agent). /release-candidate dispatches new sonnet release-executor (2 spans prep/finish; when-to-release + push + version-number decision STAY in dispatcher). /doc → doc-syncer (sonnet) dispatch; /status → status-reporter (kept HAIKU — right tier for read-only collection; win = off big model, not the tier). Gate exclusion list now = commit-change/doc/status/release-candidate. Consumer-staleness swept (LRN-113): feat Rule 1 DOWNGRADE + feat commit-split both repointed off the bare executor agents to the /hotfix + /commit-change skills. - **Wave 3 (2026-07-15/16, user directive)**: split the last two inline execution-carrying agents like /feat. /bugfix: investigation+diagnosis+contract inline behind the gate; bugfixer = sonnet EXECUTOR (fix + regression test from a closed FIX PLAN; no Agent/AskUserQuestion; BUGFIX-EXEC REPORT). verify+secure loop stays in main loop, executor = its re-dispatched dev (verify-secure-loop.md intro now: BOTH consumers dispatched, no inline branch). FINISHES reversing the "split bugfix rejected" carve-out (hotfix went wave 2, bugfix now) — investigation↔fix coupling accepted, mitigated by structured DIAGNOSIS + verify loop. /code-clean: PHASE-1 audit + validation gate inline (reflection); code-cleaner = sonnet PHASE-2 EXECUTOR (delete approved dead code, inline-load refactorer, re-audit) — refactor NOW on sonnet (inline-load pin was inert on big model). exported-symbol per-item consent stays AT THE GATE. Consumer-staleness swept: hotfix deeper-bug escalation → /bugfix skill (not bare agent); onboard STEP 6 + tour Phase B read-only-audit → general-purpose/analyzer (big model, NEVER the sonnet executor — audit stays big). Both skills STAY gated. Also: Explore built-in kept inheriting session (search feeds reflection = big deserved; custom sonnet override created then reverted — built-in already inherits + no owned prompt). census 36→42, loops-light repointed 35/0. -- **Reference**: spec `docs/superpowers/specs/2026-07-15-model-routing-design.md` + plan `docs/superpowers/plans/2026-07-15-model-routing.md` (transient, BDR-065 lifecycle), branch `feature/model-routing`. +- **Wave 4 (2026-07-16)**: client-handover doc-gen → sonnet, REDACTION-ONLY (user flipped from whole-writer after the full read). Key finding: nested audits (/seo,/harden,/web-validate — gated wave 1) must run BIG either way → whole-writer = ~7 extra gate-yields + resumable state machine on a CLIENT deliverable for ~0 extra sonnet work. Design: client-handover-writer TRIMMED to ship pipeline (STEP 1-8, all interactive gates native on big, nested audits inherit big) + doc-gen orchestration (resolve questions/NAP/precheck/overwrite/client-name inline → PACKAGE) → dispatches NEW sonnet handover-doc-writer (STEP 9-16: reads memory+git, synthesizes 6-chapter doc, word-count/skill-leak/anchor gates, renders HTML+PDF; GATE-FREE, no AskUserQuestion/Agent). client-handover JOINS gated group (orchestrates audits = reflection); its opus pin dropped (inherits big via inline-load). census 42→46. Branch feature/client-handover-dispatch (off develop, waves 1-3 merged first). +- **Reference**: spec `docs/superpowers/specs/2026-07-15-model-routing-design.md` + plan `docs/superpowers/plans/2026-07-15-model-routing.md` (transient, BDR-065 lifecycle), branches `feature/model-routing` (waves 1-3, merged), `feature/client-handover-dispatch` (wave 4). diff --git a/.claude/memory/journal.md b/.claude/memory/journal.md index cf6f231..3cdf920 100644 --- a/.claude/memory/journal.md +++ b/.claude/memory/journal.md @@ -386,3 +386,5 @@ rules: - model routing shipped on feature/model-routing: BDR-066 (reflection inline big / executors sonnet / blocking gate), /feat re-arch, census guard. client-handover conversion deferred to plan 2. - model routing WAVE 2 (same branch, user directive): doc/status dispatch their agent (sonnet/haiku pins effective); /hotfix split like /feat (joins gated group 12→13, hotfixer dual-use executor); /commit-change → sonnet commit-changer (propose/apply, gates relocated); /release-candidate → sonnet release-executor (human gates + version decision kept in dispatcher). Consumer-staleness swept (feat Rule 1 + commit-split). census 36/0, make test green. Branch still unmerged. - model routing WAVE 3 (same branch): /bugfix + /code-clean split like /feat — reflection inline, sonnet executors (bugfixer, code-cleaner). code-clean refactor now runs on sonnet (inline-load pin was inert). consumers rerouted (hotfix deeper-bug→/bugfix skill; onboard/tour read-only audit→big-model agent). Explore kept built-in (inherits big). census 42/0, loops-light 35/0. Branch still unmerged. +- model routing waves 1-3 MERGED into develop (e5c7c51); LRN-125 added. WAVE 4 started on feature/client-handover-dispatch (off develop): client-handover doc-gen → sonnet. REDACTION-ONLY (user flipped from whole-writer — nested audits must run big either way). client-handover-writer trimmed to ship pipeline (STEP 1-8 preserved byte-for-byte) + delegates writing to NEW sonnet handover-doc-writer (gate-free, STEP 9-16). client-handover joins gated group. census 46/0. NOTE: a Task-20 implementer ran `git checkout -- settings.json`, discarding user /model=opus working-tree state (LRN-098) — flagged to user (re-run /model). Lesson worth an LRN: constrain SDD implementers from git ops on files outside their task. +- wave-4 FINAL REVIEW (opus whole-branch): all 7 deliverable invariants hold, child gate-free, PACKAGE complete. Found 3 real regressions from the split — FIXED inline: (I2) DEPLOY_HINTS severed STEP2→STEP14 + (I3) --skip-seo flag dropped → both now forwarded via PACKAGE (parent resolved-list + dispatch template; child INPUT contract + gate); (I1) §7/§8 annex numbering drift in STEP 13/14 (operative steps said §6/§7 = stale 5-chapter scheme) realigned to authoritative §7/§8 + hard-rule renumbering M1/M2/M3 (Chapter 2/3/4 caps → 3/5/6; chapters 1–3 → 1–5, matching the gate windows). census lock added: lacks 'Agent(' on child (M5). census 47/0, shellcheck clean. Branch NOT merged (awaiting human signal). diff --git a/.claude/memory/learnings.md b/.claude/memory/learnings.md index a45b468..8e560f7 100644 --- a/.claude/memory/learnings.md +++ b/.claude/memory/learnings.md @@ -1248,3 +1248,16 @@ rules: - **why**: a dual-use agent inherits ONE pinned model. If its two uses sit on different tiers (audit=big, execution=sonnet), the pin silently mis-tiers one of them. hotfixer dual-use is fine because BOTH its uses are execution (same tier); code-cleaner's would have straddled tiers. - **future application**: before making an agent dual-use, check both consumers are on the SAME tier. Audit/reflection consumer + execution consumer → split the routing (audit → big-model agent, execution → sonnet executor); never overload one pinned agent. Distinct from [[LRN-113]] (sweep ALL consumers on a pattern fix) — this is WHICH agent a consumer routes to, not whether you found them all. - **cousin**: [[BDR-066]] (model routing: reflection/audit big, execution sonnet), [[LRN-113]] (consumer-staleness sweep on a pattern fix). + +## LRN-126 — splitting a monolith agent severs every IMPLICIT data path; forward each consumed field through the handoff contract + +- **pattern**: wave-4 redaction-only split (client-handover-writer monolith → reflection-parent + sonnet doc-writer child) silently dropped 2 inputs the extracted STEPs consumed. `DEPLOY_HINTS` (detected in parent STEP 2, consumed by child STEP 14) + `--skip-seo` flag (parsed from `$ARGUMENTS`, gated child STEP 13) worked in the monolith by shared scope; after the split they were dead — never added to the PACKAGE. Child rendered a §8 without platform tailoring; `--skip-seo` became a silent no-op. Caught only by the opus whole-branch review, not the census. +- **why**: in a monolith, `$ARGUMENTS`, detected vars, and STEP-N side-outputs are all in one scope — a later STEP reads them for free. The split turns that free read into a data path that MUST cross the parent→child contract explicitly. Every implicit read becomes a severed wire unless forwarded. +- **future application**: when splitting an agent, enumerate EVERY field the child reads (grep child for its input vocabulary — `PACKAGE.`, bare var names, `$ARGUMENTS` flags) and diff against what the parent SETS before dispatch. Any child-consumed field the parent never populates = severed path = renders a hole or a silent no-op. A census that checks shape (model pin, gate-free) will NOT catch this — needs a data-flow read. +- **cousin**: [[LRN-125]] (route consumer to right tier on a split), [[BDR-066]] (reflection/execution split), [[LRN-113]] (sweep ALL consumers). Distinct: 113/125 = WHICH agent/tier a consumer routes to; this = WHICH fields must cross the contract. + +## LRN-127 — SDD implementers must not run destructive git ops on files outside their task scope + +- **pattern**: a wave-4 fix-subagent ran `git checkout -- settings.json`, believing the model-value diff was a "test side-effect." It was the user's uncommitted `/model` → Opus switch ([[LRN-098]]), preserved all session. The checkout DISCARDED it — settings.json reverted to committed `claude-fable-5[1m]`. Implementer had no task-reason to touch settings.json; it acted on a file outside its diff. +- **why**: a fresh implementer sees only its task + a dirty tree; it can't know which unrelated dirty files are intentional user state vs. cruft. Destructive git ops (`checkout --`, `reset --hard`, `clean -fdx`) on out-of-scope files are irreversible and erase context the implementer never had. +- **future application**: dispatch briefs for SDD implementers / fix-subagents MUST bar destructive git ops outside the named task files. If the tree is dirty with unrelated changes, leave them — flag to controller, never revert. Controller owns cross-file git state; the executor touches only its own paths. Pairs with [[LRN-125]]/[[LRN-126]] as the "executor stays in its lane" family. diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index fafdf9c..8d17db9 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -28,12 +28,13 @@ unmerged — human gate. code-cleaner = PHASE-2 exec (refactor now runs on sonnet — inline-load pin was inert). Both skills STAY gated. census wave-3 + loops-light repoint (guarded). Supersedes BDR-050 bugfix carve-out. -- [ ] WAVE 4 — client-handover: DECIDED = dispatch the WHOLE writer (spec §5, - not redaction-only). Needs resumable-gate protocol (~8-11 AskUserQuestion - → GATE NEEDED yields, dispatcher asks + SendMessage-resumes) + force-big - on nested audit dispatches (STEP 3/4/7 — else audits inherit sonnet) + - MODEL GATE on the skill. NOT yet spec'd — dedicated pass after wave-3; - read writer 1123-1774 first. +- [x] WAVE 4 — client-handover (branch feature/client-handover-dispatch, off + develop). Shape FLIPPED to REDACTION-ONLY (full read: nested audits must + run big either way since /seo,/harden,/web-validate are gated → whole-writer + buys ~0 extra sonnet work for ~7 extra gate-yields). Design: parent + (client-handover-writer, inline=big) keeps STEP 1-8 pipeline + ALL gates + native + builds a PACKAGE; new sonnet handover-doc-writer does STEP 9-16 + pure write+render, gate-free. Tasks 19-22 in plan. + MODEL GATE on skill. ## 2026-07-08 — full back-merge release/1.0.0→develop (chore/backmerge-release-full) Genèse : la revue avait porté ~5/19 commits ; back-merge complet demandé. Cherry-pick par diff --git a/CHANGELOG.md b/CHANGELOG.md index 1160de4..5d2c29f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). - web-validate `--fix`: bundle applied via `hotfixer` at L1 instead of inline Edit (BDR-061 alignment). - Model routing wave 2 — the pure-execution + reflection-split skills stop running execution on the big session model. `/doc` and `/status` now **dispatch** their agent (doc-syncer sonnet, status-reporter haiku) instead of inline-loading it, so the pin takes effect. `/hotfix` split like `/feat`: reflection (LOCATE root cause) inline behind the model gate, the fix applied by a `hotfixer` sonnet executor (rewritten dual-use — it is also the seo/geo/web-validate L1 applier); revert-not-loop preserved; hotfix joins the gated group (13th). `/commit-change` dispatches a sonnet `commit-changer` (propose → dispatcher-owned approval gates → apply; grouping runs on sonnet, `AskUserQuestion` removed from the agent). `/release-candidate` dispatches a new sonnet `release-executor` for the mechanical spans (prep / finish+tag), the two human gates (when-to-release, push) and the version-number decision staying in the dispatcher. - Model routing wave 3 — the last two inline execution-carrying skills split like `/feat`. `/bugfix`: root-cause investigation, diagnosis and contract run inline behind the model gate; the fix + regression test are applied by a `bugfixer` sonnet executor (was a single inline agent), with the verify+secure loop staying in the main loop and the executor as its re-dispatched dev. `/code-clean`: the dead-code / style / structural audit and the approval gate run inline; a `code-cleaner` sonnet PHASE-2 executor then applies the approved scope — and the style/structural refactor (which inline-loads `refactorer`) now finally runs on sonnet, its pin having been inert under the old inline-load. Both skills stay gated (they keep reflection); their read-only-audit consumers (`onboard`, `tour`) reroute to a big-model agent so an audit never runs on the sonnet executor. Supersedes the BDR-050 "bugfix stays inline" carve-out. The built-in `Explore` search agent is deliberately left inheriting the session (search feeds reflection). +- Model routing wave 4 — client-handover doc-generation moved to sonnet (redaction-only). The ship-and-handover pipeline (baseline audits, fix loops, commit/push, deploy pause, live validate, gate) stays inline on the big session model in `client-handover-writer` — its interactive gates work natively and its nested `/seo`/`/harden`/`/web-validate` audits inherit the big model — and only the deliverable writing is delegated to a new sonnet `handover-doc-writer` (gate-free: reads memory + git, synthesizes the 6-chapter doc from a resolved PACKAGE, runs the word-count / skill-leak / anchor gates, renders branded HTML+PDF). `client-handover` joins the gated group (it orchestrates audits = reflection). Chosen over the whole-writer dispatch: the nested audits must run big either way, so whole-writer would have added ~7 gate-yields + a resumable state machine on a client deliverable for ~zero extra sonnet work. ### Security - **Magic MCP fully ask-gated** — all four `mcp__magic__*` tools (builder, refiner, inspiration, logo_search) moved to `permissions.ask` in `settings.json`; no magic call can auto-execute. The builder opens an unauthenticated local callback server (`127.0.0.1:9221+`, `Access-Control-Allow-Origin: *`, no token check) whose POST body is injected verbatim into the tool result the model consumes — the ask-gate is the mitigation on our side (BDR-059). diff --git a/README.md b/README.md index 6fda899..3b9c44f 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ reflection orchestrators. Execution runs on pinned subagents: | commit-changer, release-executor, code-cleaner | sonnet (pinned) | dispatched execution — grouping+commit / release spans / approved cleanup (the audit + approval gate stay in the dispatcher) | | doc-syncer, onboarder, scaffolder, refactorer, interviewer, plugin-advisor | sonnet (pinned) | workers | | status-reporter | haiku (pinned) | mechanical collector | -| client-handover-writer | opus (pinned, currently inert — inline-loaded; sonnet conversion planned) | deliverable writer | -| analyzer, seo-analyzer, geo-analyzer, validator-analyzer | inherit session (Fable/Opus) | reflection / audit / inline playbooks | +| handover-doc-writer | sonnet (pinned) | deliverable writer — synthesizes + renders the client doc from a resolved PACKAGE (dispatched by client-handover) | +| analyzer, seo-analyzer, geo-analyzer, validator-analyzer, client-handover-writer | inherit session (Fable/Opus) | reflection / audit / inline playbooks / ship-and-handover pipeline | | Explore (built-in) | inherit session (Fable/Opus) | search feeds reflection — kept on the big model, not pinned down | The pure-execution skills `/doc`, `/status`, `/commit-change`, diff --git a/agents/client-handover-writer.md b/agents/client-handover-writer.md index 9a52a38..5e5af96 100644 --- a/agents/client-handover-writer.md +++ b/agents/client-handover-writer.md @@ -1,8 +1,7 @@ --- name: client-handover-writer -description: Final ship-and-handover orchestrator — called by /client-handover. Runs SEO+GEO+HARDEN auto-fix loops to ≥17/20, gates on live VALIDATE, then writes the non-technical client deliverable (Markdown + branded HTML + PDF). +description: Final ship-and-handover orchestrator — called by /client-handover. Runs the audit/fix/gate pipeline (SEO+GEO+HARDEN to ≥17/20, live VALIDATE) inline on the big session model, then delegates the non-technical client deliverable (Markdown + branded HTML + PDF) to the sonnet-pinned handover-doc-writer. tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, AskUserQuestion, Agent -model: opus --- # CLIENT HANDOVER WRITER @@ -832,59 +831,21 @@ P2 (manual / requires user input): --- -## STEP 9 — LOAD MEMORY REGISTRIES +## STEP 9 — DOC-GEN ORCHESTRATION (resolve → assemble → delegate) (Only reached when STEP 8 gate passes.) -```bash -MEMORY_DIR=".claude/memory" -test -d "$MEMORY_DIR" || MEMORY_DIR="" -``` +The document itself — memory/git synthesis, the 6-chapter content, the +three content gates, and the branded HTML/PDF render — is no longer +produced here. That work moved to the sonnet `handover-doc-writer` +subagent. This step's job is narrower: resolve every interactive +decision and every detected fact that agent needs, assemble them into +one PACKAGE, and dispatch. Nothing below writes or renders the +deliverable. -If memory dir exists, read each file (full contents, parse manually): +### 9.1 — Q1 deploy chapter + Q2 language confirm -- `decisions.md` → list of BDR-XXX entries (date, title, decision, why, - alternatives, status) -- `learnings.md` → LRN-XXX entries -- `blockers.md` → BLK-XXX entries (open vs resolved) -- `journal.md` → date headings + 3-5 line session summaries -- `evals.md` → EVAL-XXX entries - -If memory dir missing or empty, proceed using only git data — flag in -final report that memory was unavailable. - ---- - -## STEP 10 — GIT HISTORY SUMMARY - -```bash -git log --reverse --format='%h|%aI|%an|%s' | head -200 -git log --name-only --format='---COMMIT---' | grep -v '^---' | sort -u | head -50 - -git log --diff-filter=A --name-only --format='' | sort -u | wc -l # added -git log --diff-filter=M --name-only --format='' | sort -u | wc -l # modified -git log --diff-filter=D --name-only --format='' | sort -u | wc -l # deleted - -git tag --sort=-creatordate | head -5 -``` - -For projects with 200+ commits, use a sub-agent to cluster commits into -phases (delegate via `Agent` tool with `subagent_type: "Explore"` or -`general-purpose`): - -> "Read `git log --reverse --format='%h|%aI|%s'` for this repo (full -> output). Cluster commits into 3-7 chronological phases based on commit -> message themes. For each phase: name, commit count, 2-line summary. -> Do NOT include dates or date ranges — the client document does not -> render them. Output JSON." - -For smaller projects, do it inline. - ---- - -## STEP 11 — ASK USER QUESTIONS - -### Q1 — Deploy chapter (default = SKIP) +**Q1 — Deploy chapter (default = SKIP).** **Default behavior**: deploy chapter is **NOT included**. Most client handovers go to non-technical owners who never touch the @@ -898,12 +859,13 @@ project signals justify it (e.g., `CLAUDE.md` explicitly mentions or the project README documents a hand-off intent). Even then, re-confirm before including. -**No flag, no signal → skip silently** (do not even ask). +**No flag, no signal → skip silently** (do not even ask). Set +`INCLUDE_DEPLOY=no`. -If `--include-deploy` IS present, jump to STEP 14 to render the -chapter without further prompting. +If `--include-deploy` IS present, set `INCLUDE_DEPLOY=yes` without +further prompting. -If user explicitly asks via Q1 (only when signals justify): +If signals justify asking: ``` Re-grounding: project = , branch = , all audits passed @@ -926,478 +888,56 @@ Options: - B) No — skip the deploy chapter (default, recommended for non-tech clients) ``` -(Translate to English if `LANG=en`.) +(Translate to English if `LANG=en`.) On A → `INCLUDE_DEPLOY=yes`. On B → +`INCLUDE_DEPLOY=no`. -### Q2 — Output language confirmation (only if auto-detection was ambiguous) +**Q2 — Output language confirmation** (only if the STEP 2 auto-detection +was ambiguous). Skip if confident. Only ask if ambiguous. The resolved +value feeds `LANG` in the PACKAGE. -Skip if confident. Only ask if ambiguous. +### 9.2 — Build the §4 NAP table -### Q3 — Web project: SEO/GEO manual chapter +Resolves the VALUES the doc-writer renders — the doc-writer does not +detect or prompt for any of these itself. -Included by default. Do NOT ask. Mention in final summary. - -If `IS_LOCAL_BUSINESS=true`, the chapter goes deeper on local listings. -If false, the chapter focuses on general directory + AI search. - ---- - -## STEP 12 — SYNTHESIZE THE DOCUMENT - -Generate the deliverable as a tight 4-chapter structure: what was needed, -what was done (lay summary), what the client must do, then technical -details for the curious. Translate headings to `LANG`. Tone: friendly, -concrete, no jargon. One short paragraph per idea. - -### Hard rules for this document - -0. **All section cross-references MUST be clickable markdown links.** - Whenever the doc body mentions a section by number (`§5.1`, `§6`, - `§6.2`, etc.), write it as a markdown link to the heading anchor: - - ``` - [§5.1](#51-choix-techniques-importants) - [§6](#6-annexe-plateformes-externes-visibilite) - [§6.2](#62-plateformes-prioritaires-semaine-1) - ``` - - The renderer (`scripts/handover-to-pdf.sh`) uses pandoc with - `--from=gfm+gfm_auto_identifiers` (or python-markdown's `toc` - extension as fallback). Both auto-generate heading IDs in the - GitHub-style slug: - - lowercase - - spaces → hyphens - - accents stripped (é→e, à→a, etc.) - - punctuation removed (`.`, `(`, `)`, `,`, `:`, `?`, `!`, - apostrophes) - - example: `### 6.2 Plateformes prioritaires (Semaine 1)` → - `id="62-plateformes-prioritaires-semaine-1"` - - After writing the doc, **verify links resolve**: - - ```bash - # Extract all anchor refs and all heading IDs, then check refs - # against IDs (set difference should be empty). - grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt - # Render once, then extract IDs: - grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt - comm -23 /tmp/refs.txt /tmp/ids.txt - # expected: empty. Each line printed = a broken anchor — fix. - ``` - - If you spot a broken anchor, regenerate the HTML once to inspect - the actual ID, then update the markdown ref to match. The TOC - line at the top of the doc and any "voir §N" cross-references - in §3 / §4 / §5 / §6.x sub-tables / §6.9 calendar must all - use the linked form. - -1. **Never name internal tools or skill identifiers in chapters 1–3.** - Forbidden tokens (do not appear, in any case, in the lay portion): - `/seo`, `/harden`, `/web-validate`, `/cso`, `/feat`, `/bugfix`, - `/ship-feature`, `/ship`, `/code-clean`, `/refactor`, `seo-analyzer`, - `geo-analyzer`, `validator-analyzer`, `harden`-as-product-name, - `SEO.md`, `HARDEN.md`, `VALIDATE.md`, `CSO.md`, `MAX_ITERATIONS`, - `ALL_PASS`, `SCORE_*`. Replace with what they correspond to in client - language: référencement / visibilité IA / sécurité / conformité - technique / audit interne. Internal tool names may appear ONLY in - chapter 4 ("Détails techniques") inside the optional glossary. -2. **Chapter 2 hard cap: 300 words max, zero technical jargon.** Plain - French (or plain English if `LANG=en`). No acronyms not already in - common usage (HTTPS is fine; CSP is not). Run `wc -w` against the - chapter body; if over 300, rewrite shorter. -3. **Chapter 3 is action-only.** Every bullet starts with a verb the - client can act on without a developer. -4. **Chapter 4 may use technical terms** (SEO, GEO, HSTS, CSP, etc.) but - each term gets a one-line plain-language definition the first time it - appears, or a glossary at the end of the chapter. - -### Document structure - -``` -# [Project name] — Compte rendu de livraison -## (or: HANDOVER — Project Recap) - -> Document préparé le YYYY-MM-DD à l'attention de [client name if known]. -> Ce document récapitule l'ensemble du travail réalisé sur votre projet -> du JJ/MM/AAAA au JJ/MM/AAAA. - -## 1. Ce qu'il fallait faire (et pourquoi) - -[Briefing + motivation. 100–180 words max. Two short paragraphs. -- §1.1 (the brief): what the client wanted, in their own words if - possible. Pull from the project journal's earliest entry, the README, - or the first commit message. -- §1.2 (the why): the underlying problem this project solves for the - client (no audience, weak online presence, manual process to - automate, broken legacy site, etc.). Concrete. Their reality, not - ours. - -End the chapter with a one-line success criterion in their words — -"À la livraison, vous deviez pouvoir ___." If unknown, omit rather -than invent.] - -## 2. Résultats — état de santé du site (avant / après) - -[Score table at the top, BEFORE the lay summary. Plain French -column labels — no internal tool names. Numbers OK (the whole -purpose of this chapter is the numbers). Follow with a short -"Lecture rapide" bulleted list (one bullet per axis) explaining -what each domain means and why the delta matters. - -| Domaine | Avant | Après | Statut | -|------------------------------------------------------|------------:|-------------:|:------:| -| Référencement Google (recherche classique) | /20 | /20 | OK | -| Visibilité IA (ChatGPT, Perplexity, Gemini, Claude) | /20 | /20 | OK | -| Sécurité du site (chiffrement, en-têtes, redirects) | /20 | /20 | OK | -| Conformité technique (HTML, CSS, accessibilité) | — | /20 | OK | - -(LANG=en column labels: "Domain" / "Before" / "After" / "Status". -Row labels: "Google search (classical)", "AI visibility (ChatGPT, -Perplexity, Gemini)", "Site security", "Technical compliance".) - -Add intro sentence: "Quatre dimensions auditées par des outils -indépendants. Toutes au-dessus du seuil 17/20 fixé pour livrer." - -Lecture rapide bullets — one per axis, each explaining the domain -in plain French and noting any notable jump (e.g., "Le score est -passé de quasi-nul à très haut grâce à ..."). Cite concrete -external validators when relevant (Mozilla Observatory, SSL Labs, -SecurityHeaders.com — these are recognized seals). - -DO NOT mention internal tool/skill names here (no /seo, /harden, -/web-validate, seo-analyzer, etc.). The lecture rapide IS where -client-facing axis names live.] - -## 3. Ce qui a été fait - -[**HARD CAP: 300 words. ZERO technical jargon.** This is the chapter the -client reads first, possibly the only one they read. - -Structure as a single short narrative + a tight bullet list of -user-visible benefits: - - Para 1 (3–5 sentences): the project today, in their words. What it - looks like to a visitor, what the client can do with it. NOT what - technologies were used. - - Bullet list (5–10 items): visible benefits, each phrased as something - the client or their visitors can now do that they couldn't before. - Pattern: "Vos visiteurs peuvent ___" / "Vous pouvez ___" / - "Le site est maintenant ___". - -Forbidden in this chapter: framework names, audit names, score numbers, -file paths, package names, command-line tool names, anything ending in -`.md`, `.json`, `.yaml`. If you cannot describe a feature without one -of those, the feature belongs in chapter 4, not here. - -After drafting, count words. Cap at 300. If over, cut paragraphs not -bullets — bullets are the value-dense part.] - -## 4. Vos informations officielles à utiliser partout (NAP) - -[**Position before §5 todo is REQUIRED**, not cosmetic. Client must -have NAP under their eyes BEFORE attacking platform creation actions. -Prose intro must start with "À lire avant d'attaquer le [§5](#5-...)" -and cross-reference §5 explicitly. - -Table content (FR variant — translate cells to EN if `LANG=en`, -keep column structure identical): - -| Champ | Valeur officielle à utiliser partout | -|------------------------|------------------------------------------------------------| -| Nom commercial | [from CLAUDE.md / README / first commit / AskUserQuestion] | -| Nom légal | [Kbis spelling — UPPERCASE if registered as such] | -| Adresse | [n° rue, code postal, ville, pays] | -| Téléphone | [+33 / national format] | -| E-mail pro | [contact@…] | -| Site web | [https://…] | -| SIRET | [if local business FR] | -| TVA | [if applicable; otherwise "non applicable (franchise…)"] | -| Coordonnées GPS | [lat, lon — for Google Maps consistency] | -| Catégorie principale | [the ONE primary category] | -| Catégories secondaires | [up to 3] | -| Description courte | [AUTO-DETECT from site hero / meta description / og:desc / llms.txt / JSON-LD LocalBusiness.description — see STEP 13 detection order] | -| Horaires | [per-day, with seasonal note if applicable] | - -End with two callouts: - -> **Conseil pratique** : enregistrer ce tableau en note dans votre -> téléphone. À chaque inscription sur une nouvelle plateforme, -> copier-coller depuis cette source unique — jamais de saisie à la -> main, jamais de reformulation. - -> **À vérifier avant de commencer le §5** : si une de ces valeurs -> n'est pas exacte, corrigez-la **ici d'abord**, puis appliquez la -> nouvelle valeur partout. - -Auto-detection rules: **`.claude/audits/NAP-KIT.md` FIRST when present** -— it is the user-confirmed canonical NAP produced by /seo (LRN-032: -on-site sources may all share one wrong seed; the kit is the only +Auto-detection rules, in order (stop at the first positive match per +field): **`.claude/audits/NAP-KIT.md` FIRST when present** — it is the +user-confirmed canonical NAP produced by /seo (LRN-032: on-site +sources may all share one wrong seed; the kit is the only user-validated source). Fields marked `UNCONFIRMED` there stay -`[À COMPLÉTER]` here. Only when no NAP-KIT exists, fall back to: -CLAUDE.md, .claude/memory/ journal/decisions, README.md, first commits, -and the live site. If a value cannot be confirmed, leave `[À COMPLÉTER]` -and warn in final report. Do NOT invent SIRET, GPS, or legal name — -those are too risky to fake.] +`[À COMPLÉTER]`. Only when no NAP-KIT exists, fall back to: +`CLAUDE.md`, `.claude/memory/` journal/decisions, `README.md`, first +commits, and the live site. Do NOT invent SIRET, GPS, or legal name — +those are too risky to fake; leave `[À COMPLÉTER]` if unconfirmed. -## 5. Ce qui vous reste à faire +Resolve each field: `nom_commercial`, `nom_legal`, `adresse`, +`telephone`, `email`, `site_web`, `siret`, `tva`, `gps`, +`categorie_principale`, `categories_secondaires`, +`description_courte` (auto-detect from site hero / meta description / +og:desc / llms.txt / JSON-LD `LocalBusiness.description`), `horaires`. -[Action-only checklist for the client. Pull from: -**`.claude/audits/HUMAN-ACTIONS.md` FIRST when present** (the /seo//geo -audit-end checklist — carry its automation notes, vulgarized), then open -`blockers.md` entries, ongoing-monitoring items, external platforms to -claim, content updates only the client can make, deploy steps if -self-hosted. If any axis passed via the code-ceiling rule (STEP 8), -its unlocking user actions appear HERE with their expected score gain -("+X points quand fait") — that is the contract that made the gate pass. +**`nom_commercial` is the one field that must not ship as +`[À COMPLÉTER]`** — the deliverable's cover page and §1 brief depend on +it. If the detection above doesn't confirm it, ask: -Format as a checklist grouped by cadence. Every line starts with a -verb. Every line is something the client can do without a developer. - -### Une fois (à faire dans les premières semaines) -- [ ] Réclamer la fiche Google Business Profile et la vérifier (lien : ...) -- [ ] Compléter le profil Apple Business Connect (lien : ...) -- [ ] Vérifier la cohérence Nom / Adresse / Téléphone sur toutes les - plateformes — voir l'annexe à la fin du document -- [ ] [Si vous gérez l'hébergement vous-même : configurer le certificat - de sécurité (renouvellement automatique recommandé)] -- [ ] [Si vous gérez l'hébergement vous-même : programmer une sauvegarde - quotidienne] - -**NEVER include**: "Sauvegarder ce document hors du dépôt (PDF, email)". -Client has no access to the dev git repository — that line is a -dev-only concept and confuses the deliverable. The PDF is delivered -to them directly. STEP 14.5 explicitly removes it if it ever sneaks in. - -**Intro note**: add one line above the "Une fois" subheading so the -client understands the mixed-state list: - -> Les cases déjà cochées correspondent à ce qui a déjà été validé. - -(English equivalent if `LANG=en`: "Items already checked have been -validated.") - -The actual pre-check pass runs in STEP 14.5 (after §5 + §7 are drafted, -before STEP 15 writes to disk). Do NOT pre-check items here — STEP 14.5 -does it based on project signals + WebSearch + AskUserQuestion. - -### Mensuel -- [ ] Ajouter ou mettre à jour 5 photos sur Google Business -- [ ] Répondre aux avis Google (positifs et négatifs) sous 48 h -- [ ] Vérifier que le site est toujours en ligne (test simple : ouvrir - l'URL depuis un autre appareil) -- [ ] [Si système de gestion de contenu : mettre à jour les contenus - saisonniers] - -### Trimestriel -- [ ] Faire un test de visibilité IA : taper le nom du commerce dans - ChatGPT, Perplexity, Gemini. Noter ce qui s'affiche. -- [ ] Demander à 3–5 clients de laisser un avis Google -- [ ] Publier un post Google Business (offre, événement, actualité) - -### Annuel -- [ ] Mettre à jour la photo de couverture Google Business -- [ ] Vérifier que les horaires saisonniers sont bons -- [ ] Renouveler les noms de domaine - -### Quand quelque chose change dans la vie du commerce -- [ ] Changement d'adresse, de téléphone ou d'horaires → modifier - d'abord sur Google Business, puis sur toutes les autres - plateformes (la cohérence est cruciale) - -[Adapt cadences to project type. For SaaS / non-local: replace -Google Business cadences with appropriate platforms (Slack, App Store, -Play Store, Trustpilot, G2, Capterra, etc.). For pure tooling / -internal projects, this chapter may shrink to a 5-line "à surveiller" -list — that is fine, do not pad.] - -## 6. Détails techniques (pour les curieux) - -[Same content as before but consolidated and labelled as the -technical-depth chapter. Internal tool names may appear here. -The client is not required to read this chapter. The score table -is NOT here — promoted to §2 for impact. Add a one-liner referencing -back: "Les scores avant / après ont été déplacés au §2 pour -visibilité."] - -### 6.1 Choix techniques importants - -[Vulgarize 3–7 BDR entries. Design, framework, security, hosting -decisions the client would care about. One paragraph each: -what was chosen, why over the alternative, what it changes for the -client. Drop entries the client cannot act on or care about.] - -### 6.2 Comment on en est arrivé là (phases) - -[3–7 phases. For each: what was done, why it mattered, in technical -detail this time. Reference commit clusters from STEP 10. Plain phase -names, not skill names. - -**Do NOT include dates, date ranges, sprint numbers, or any -chronological markers** ("22 avril", "23–24 avril", "Sprint 1", -"Semaine 2", etc.). Phases are themes, not a timeline. The client -does not need to know the exact timing — they need to understand -what was done and why. Lead each bullet with the phase name in bold, -followed by what was done. Forbidden tokens before write: -`\b\d{1,2}\s+(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)\b`, -`\bsprint\s+\d+\b`, `\bsemaine\s+\d+\b`.] - -Example — correct format (no dates): -> - **Audit + conformité légale.** Mentions légales et politique de -> confidentialité publiées, HTTPS forcé, premières corrections -> SEO. Risque RGPD jusqu'à 20 M€ neutralisé. -> - **Refonte technique.** Le fichier monolithique de 1 554 lignes -> démonté en 12 morceaux PHP réutilisables. - -Wrong — has date prefix: -> - **22 avril — Audit + conformité légale.** ... - -### 6.3 Glossaire (optionnel) - -[Include only if at least 4 of the terms below appear in chapter 4. -Format: term — one-line plain-language definition. Sort alphabetically. -This is the ONLY place internal tooling names may be mentioned by -their internal label, and only when explaining what they correspond -to.] - -- **SEO (référencement classique)** — ensemble des pratiques pour - apparaître dans Google, Bing, DuckDuckGo. -- **GEO (visibilité IA)** — équivalent du SEO pour les moteurs par IA - comme ChatGPT, Perplexity, Gemini. -- **HSTS** — en-tête HTTP qui force la navigation en HTTPS. -- **CSP (Content Security Policy)** — règle qui limite ce que le - navigateur charge depuis le site, pour bloquer les injections. -- **WCAG** — standard d'accessibilité (AA = niveau recommandé). -- **Schema.org / JSON-LD** — annotations cachées qui aident moteurs et - IA à comprendre le contenu. -- **llms.txt** — fichier qui dit aux moteurs IA quel est le contenu - important du site. - -## 7. Annexe — Plateformes externes (web) - -[NAP table is NOT here — promoted to §4. This annex starts directly -with the platform sub-sections (§7.1 Plateformes prioritaires, §7.2 -Réseaux sociaux, etc.). Add a one-line callout in the chapter intro: -"Le NAP a été déplacé en tête au [§4] pour que vous l'ayez sous les -yeux avant d'attaquer les actions du [§5]. Référez-vous-y à chaque -inscription — c'est la source de vérité unique."] - -## 8. Annexe — Build & déploiement (optionnel) - ---- - -*Document généré automatiquement à partir de l'historique du projet et -des audits de santé. Pour toute question, contactez [contact].* +``` +AskUserQuestion: + "Quel est le nom commercial exact du client, tel qu'il doit + apparaître partout (Google Business, factures, document de + livraison) ?" ``` -### Tone rules +Every other field that can't be confirmed stays `[À COMPLÉTER]` — the +doc-writer renders it as-is and flags it in its own report; do not +invent a value here. -1. Address the client directly ("votre site", "vous pouvez"). -2. Chapters 1–3: replace every tech term with a user-facing equivalent. -3. No abbreviations the client wouldn't use (HTTPS yes, CSP no — unless - in chapter 4 with definition). -4. Concrete numbers > adjectives. -5. Short paragraphs. Bullet lists for things you can count. -6. **Score deltas explained in plain words**. Never just dump numbers. -7. **Chapter 3 is action-oriented**. Every line starts with a verb. - Every line is something the client can do without a developer. -8. **No skill-name leaks in chapters 1–3.** See "Hard rules" above. +### 9.3 — Platform precheck detection (§5 / §7 checkboxes) ---- +Skip if `PROJECT_TYPE != web`. Produces `PRECHECK_DONE` — the +platforms already confirmed done, so the doc-writer pre-checks the +matching boxes instead of leaving everything unchecked. -## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only) - -If `PROJECT_TYPE=web` AND `--skip-seo` NOT set, append this chapter -as **§6 Annexe — Plateformes externes** in the 5-chapter structure -(see STEP 12). Replace the §6 stub with the full content rendered from -the resource file. - -Read the resource file: -`$HOME/.claude/skills/client-handover/checklists/seo-geo-manual.md` - -That file contains the canonical platform list with registration URLs in -both FR and EN. Use the section matching `LANG` and `IS_LOCAL_BUSINESS`. - -If the file is unreachable, fall back to the inline platform list at the -bottom of this agent. - -The chapter must include: - -1. **Pourquoi c'est important** (1 paragraph). Site is technically - optimized; visibility on Google, ChatGPT, directories depends on - actions only the client can take. - -2. **NAP consistency** — **NOTE**: the NAP table itself is NOT - rendered here in §7. It was promoted to its own dedicated chapter - **§4 ("Vos informations officielles à utiliser partout (NAP)")** - per the structure decision in STEP 12 (so the client has the - values under their eyes BEFORE attacking platform creation). - - In this §7 annex chapter, just emit a one-line callout pointing - back to §4: - - > Le NAP a été déplacé en tête au [§4](#4-vos-informations-officielles-a-utiliser-partout-nap) - > pour que vous l'ayez sous les yeux **avant** d'attaquer les - > actions ci-dessous. Référez-vous-y à chaque inscription — - > c'est la source de vérité unique. - - The actual table content (with auto-detection rules for each - field, including the **Description courte** row pulled from - site hero / meta description / og:desc / llms.txt / JSON-LD - LocalBusiness.description) is defined in the §4 template at - STEP 12. Do NOT duplicate the table here. - -3. **Platform checklist** (priority-ordered table per `IS_LOCAL_BUSINESS`). - Each row: Plateforme | Pourquoi | Lien d'inscription | Action | Statut. - -4. **AI search visibility (GEO)**. Plain explanation + actions: Wikidata, - Knowledge Panel, llms.txt, periodic re-audit. - -5. **Reviews & reputation**. - -6. **Photos & content**. - -7. **Schedule** (Semaine 1 / Mois 1 / Mois 3 / Trimestriel). - -8. **Outils gratuits pour vérifier votre présence**. - -Cross-link this chapter from §4 (owner responsibilities — "Ce qui vous -reste à faire"). Items in this §6 annex that are recurring belong in -§4's cadence checklist (Mensuel / Trimestriel / Annuel). - ---- - -## STEP 14 — BUILD & DEPLOY CHAPTER (only if Q1=Yes) - -If included, this becomes **§7 Annexe — Build & déploiement** in the -5-chapter structure (see STEP 12). For each `DEPLOY_HINTS` match, -generate a short subsection: -1. What this means (1 paragraph). -2. First-time setup (numbered steps + signup link). -3. Day-to-day deploy (typical command / click sequence). -4. How to know it worked (where to check URL, where to find logs). -5. What it costs (free tier, when paid kicks in — `WebSearch` for - 2026 pricing if not in repo). -6. Who to call when it breaks (status page, support link). - -If no deploy hints, offer 2-3 standard options: -- Static site → Netlify / Vercel / Cloudflare Pages -- Webapp → Fly.io / Render / Vercel / Railway -- CLI / library → npm / PyPI / crates.io / Homebrew - -For each: signup + 5-step deploy walkthrough. - ---- - -## STEP 14.5 — PRE-CHECK COMPLETED ITEMS (web/local-business) - -Skip if `PROJECT_TYPE != web`. Runs AFTER STEP 12 + STEP 13 (in-memory -body drafted), BEFORE STEP 15 (write). - -**Goal**: pre-check (`[x]` markdown / `☑` Unicode) every checkbox in -§5 (todo) + §7 (platforms annex) that corresponds to an action -**already done**, so the client only sees what's actually left to do. - -### Scope +**Scope.** **INCLUDE** (auto-pre-check candidates): - §5 "Une fois — à faire dans..." block (one-shot platform creation / @@ -1414,7 +954,7 @@ body drafted), BEFORE STEP 15 (write). - Lines containing recurring-action verbs: "demander", "tester", "ajouter", "publier", "vérifier régulièrement", "répondre". -### Detection signals (apply in order, stop at first positive match) +**Detection signals** (apply in order, stop at first positive match): For each in-scope checkbox, attempt to confirm "done" via: @@ -1437,11 +977,11 @@ For each in-scope checkbox, attempt to confirm "done" via: Confirm done if the search returns the actual business listing matching the platform's URL pattern. **Capture the public URL** — - useful to insert into the doc body as evidence - (`Fiche en ligne : https://...`). + carried in `PRECHECK_DONE` so the doc-writer can insert it as + evidence (`Fiche en ligne : https://...`). 5. **Unknown** — couldn't confirm via 1-4 → add to `UNKNOWNS` list. -### Batch unknowns via AskUserQuestion +**Batch unknowns via AskUserQuestion.** Group `UNKNOWNS` into themed batches (max 4 questions, max 4 options each, `multiSelect: true`). Suggested groupings: @@ -1450,324 +990,114 @@ each, `multiSelect: true`). Suggested groupings: - "Cartographie + sectoriels" (Mappy, Vroomly, Foursquare, Trustpilot) - "Annuaires généralistes" (Justacote, Hoodspot, Le Bottin, Nextdoor) -Items the user selects → mark done. Items the user does NOT select -→ stay unchecked. If `UNKNOWNS` is empty, skip (no questions asked). +Items the user selects → mark done. Items the user does NOT select → +stay unchecked. If `UNKNOWNS` is empty, skip (no questions asked). -### Apply pre-checks to in-memory body +`PRECHECK_DONE` = the final list of confirmed-done platforms/items +(name + evidence URL when captured via WebSearch). -For each "done" checkbox: -- §5 markdown: `- [ ]` → `- [x]`. -- §7 Unicode: `- ☐` → `- ☑`. -- Optionally rewrite surrounding text: - - Add a short confirmation phrase in **bold** (e.g., "**Fiche - Google Business Profile créée et vérifiée.**"). - - For platforms detected via WebSearch with a public URL, append - the URL as evidence (`Fiche en ligne : https://...`). - - Sub-items dependent on a parent platform existing stay `☐` so - the client sees what depth-checks remain. - -### Cleanup pass (always) - -- **Remove** any line containing "Sauvegarder ce document hors du - dépôt" — client has no repo access, dev-only concept. -- **Add intro note** to §5 (above "Une fois" subheading) if any - item was pre-checked: - - > Les cases déjà cochées correspondent à ce qui a déjà été validé. - - (`LANG=en`: "Items already checked have been validated.") - -### Verification +### 9.4 — Resolve OUTPUT (path + overwrite decision) ```bash -# At least one pre-check expected for any project with real history. -grep -cE '^- \[x\]|^- ☑' "$OUTPUT_MD" -# Expected: > 0 unless project is fresh and has zero external presence. +OUTPUT_PATH="LIVRAISON.md"; [ "$LANG" = "en" ] && OUTPUT_PATH="HANDOVER.md" +# honor --output from $ARGUMENTS if present +test -f "$OUTPUT_PATH" && echo EXISTS ``` -Then re-run STEP 15 word-count + skill-leak gates after these edits. - ---- - -## STEP 15 — WRITE MARKDOWN OUTPUT - -Default output path: project root. -- `LIVRAISON.md` if `LANG=fr` -- `HANDOVER.md` if `LANG=en` - -If a file at that path already exists, AskUserQuestion: -- A) Overwrite (recommended if previous version is stale) -- B) Save as `LIVRAISON-YYYY-MM-DD.md` (versioned) -- C) Skip writing — display in conversation only - -Write the file with the `Write` tool. - -Sanity checks (do them in this order, before STEP 16): - -```bash -wc -l # expect 250-900 lines -grep -c "^## " # expect 6-8 top-level chapters - # §1, §2, §3, §4, §5, §6, [§7 web], [§8 deploy] -``` - -**Chapter 3 word-count gate** (lay summary "Ce qui a été fait" — §3 -since §2 = score table). Extract the body of `## 3. Ce qui a été fait` -(or `## 3. What we did` if `LANG=en`) and run `wc -w` on it. -**Hard cap: 300 words.** If over, edit the chapter (remove paragraphs, -keep bullets) and re-write before moving to STEP 16. Do not skip this -gate — §3 is the lay narrative the client reads first after the score -table. - -```bash -awk '/^## 3\. /{flag=1; next} /^## 4\. /{flag=0} flag' "$OUTPUT" | wc -w -# expected: ≤ 300 -``` - -**Skill-name leak gate.** Forbidden tokens must NOT appear in chapters -1–5 (the lay portion: brief, scores, lay summary, NAP, todo). -Chapter 6 (Détails techniques) may use them in the optional glossary. - -```bash -awk '/^## 1\./{flag=1} /^## 6\./{flag=0} flag' "$OUTPUT" \ - | grep -niE '/(seo|harden|web-validate|validate|cso|feat|bugfix|ship-feature|ship|code-clean|refactor)\b|seo-analyzer|geo-analyzer|validator-analyzer|SEO\.md|HARDEN\.md|VALIDATE\.md|CSO\.md|MAX_ITERATIONS|ALL_PASS|SCORE_[A-Z_]+' -# expected: no matches. Each match is a leak — rewrite the offending -# chapter in client language before STEP 16. -``` - -**Anchor-resolution gate** (clickable section refs work). - -```bash -grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt -grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt -comm -23 /tmp/refs.txt /tmp/ids.txt -# expected: empty. Each line printed = a broken anchor — fix the ref -# in markdown (most likely a stale anchor from an earlier renumbering). -``` - -If either gate fails, fix and re-write the markdown before continuing. - ---- - -## STEP 16 — RENDER BRANDED HTML + PDF - -Always produce a branded `.html` next to the `.md`. Produce a branded -`.pdf` when a PDF engine is available on the host. The file is the -client-visible deliverable. - -### Inputs already known - -| Variable | Source | -|-------------------|---------------------------------------------| -| `OUTPUT_MD` | path written in STEP 15 | -| `LANG` | from STEP 1 | -| `PROJECT_NAME` | `PROJECT_ROOT` basename or `package.json` `name` | -| `CLIENT_NAME` | from journal first entry, README, or AskUserQuestion | -| `PROJECT_PERIOD` | ` → ` (DD/MM/YYYY) | -| `PROJECT_URL` | `DEPLOYED_URL` from STEP 6 (or `—` if none) | - -If `CLIENT_NAME` is unknown after best-effort detection, ask once with -AskUserQuestion: `"Nom du client à afficher sur la couverture du PDF -(ou laisser vide pour ne rien afficher)?"`. A blank answer becomes `—`. - -### Run the renderer - -```bash -PROJECT_NAME="$PROJECT_NAME" \ -CLIENT_NAME="$CLIENT_NAME" \ -PROJECT_PERIOD="$PROJECT_PERIOD" \ -PROJECT_URL="$PROJECT_URL" \ -LANG="$LANG" \ -"$HOME/.claude/skills/client-handover/scripts/handover-to-pdf.sh" \ - "$OUTPUT_MD" -``` - -The renderer: -1. Converts the markdown to HTML using the first available engine - (pandoc > python-markdown > `npx marked`). -2. Wraps the body in the ZenQuality template (cover page + branded - typography Inter + Playfair Display, ZenQuality green palette - `#1A3A25 / #2D5A3D / #4A7C59 / #87A878`, **white cover** - (`--white-pure`) with black-deep title and green-forest accents - (eyebrow, meta labels, footer); subtle radial sage + forest tints - add depth. Cream `#F5F0EB` reserved for body code/blockquote - accents — not page bg). -3. Embeds the ZenQuality logo (default: `https://zenquality.fr/assets/logo-horizontal-1024.png`; - override with `LOGO_URL` env var to use a local file). -4. Emits `LIVRAISON.html` (or `HANDOVER.html`) next to the `.md`. -5. Tries PDF engines in order: weasyprint > wkhtmltopdf > chromium > - chromium-browser > google-chrome. First match writes - `LIVRAISON.pdf` (or `HANDOVER.pdf`). -6. If no PDF engine is available, exits with code 2 and prints - install hints. The HTML file is still produced and viewable — - the user can "Print → Save as PDF" from any modern browser. - -### Exit code handling - -| `$?` | Meaning | Action | -|------|-----------------------------------------------|--------| -| 0 | HTML and PDF written | continue to STEP 17 | -| 2 | HTML written, no PDF engine on host | continue to STEP 17 — final report mentions PDF as MISSING and lists install commands | -| 1 | Fatal (bad args, unwritable dir, conv error) | escalate to user with the script's stderr | - -### Re-rendering on overwrite (option B in STEP 15) - -If STEP 15 chose option B (`LIVRAISON-YYYY-MM-DD.md` versioned), -the renderer produces matching `LIVRAISON-YYYY-MM-DD.html` and -`LIVRAISON-YYYY-MM-DD.pdf`. Pass the versioned path as `$OUTPUT_MD`. - ---- - -## STEP 17 — FINAL REPORT - -Output to the user: +If the target file does not exist → `OUTPUT = overwrite ` +(nothing to ask; it's a fresh write). If it exists, ask: ``` -DONE — ship-and-handover pipeline complete. - -OUTPUT: - Markdown: - HTML: - PDF: (or: NOT GENERATED — see install hints below) -LANGUAGE: fr | en -PROJECT TYPE: web (local-business) | web | cli | library | mobile | other -COMMITS ANALYZED: from to - -PIPELINE RESULT (web): - SEO classique /20 → /20 ✅ (iterations: ) - GEO (IA) /20 → /20 ✅ (iterations: ) - HARDEN /20 → /20 ✅ (iterations: ) - VALIDATE — → /20 ✅ (post-deploy) - -PIPELINE RESULT (non-web): - CSO /20 → /20 ✅ (iterations: ) - -PIPELINE COMMITS: (pushed: yes/no) -DEPLOY: confirmed at — URL: -DECISIONS VULGARIZED: -BLOCKERS REMAINING: (open) - -DOC SECTIONS WRITTEN: - §1 Ce qu'il fallait faire (et pourquoi) - §2 Résultats — état de santé (avant / après) (score table, impact) - §3 Ce qui a été fait (≤ 300 mots, sans jargon) - §4 Vos informations officielles (NAP) (source-of-truth, before todo) - §5 Ce qui vous reste à faire (action checklist) - §6 Détails techniques (choix, phases, glossaire) - §7 Annexe — plateformes externes (web only, NAP table not duplicated) - §8 Annexe — build & déploiement (only if requested) - -Next steps for the user: -1. Open (or the .html) — verify cover page, branding, - §2 score table renders right after §1, §4 NAP table renders before - §5 todo list (clickable section refs work in PDF). Adjust .md and - re-run STEP 16 to regenerate. -2. Read end-to-end before sending — fill any [À COMPLÉTER] / - [À CONFIRMER] markers (NAP fields in §4 especially). -3. Save a copy outside the repo (the .pdf is already client-ready). -4. Walk through §5 (ce qui vous reste à faire) with the client - during the handover meeting — that's the part they MUST act on. - -[If PDF was NOT generated, append:] -PDF NOT GENERATED — no PDF engine on this host. Install one of: - - weasyprint pip install --user weasyprint (or: pipx install weasyprint) - - wkhtmltopdf apt install wkhtmltopdf - - chromium apt install chromium-browser -Then re-run only STEP 16 (the .md does not need to change). +AskUserQuestion: + "A file already exists at ." + - A) Overwrite (recommended if previous version is stale) + - B) Save as `LIVRAISON-YYYY-MM-DD.md` (versioned) + - C) Skip writing — display in conversation only ``` -If anything was skipped or uncertain, list under `CONCERNS:`. +Resolve `OUTPUT` = `overwrite ` | `versioned ` | +`skip-write`, per the answer. ---- +### 9.5 — Resolve CLIENT_NAME -## VOICE RULES (the whole document) - -- **Vulgarize, don't dumb down.** -- **No emojis** unless the project itself uses them prominently. -- **No marketing fluff.** -- **Concrete numbers > adjectives.** -- **Lead with the user benefit.** -- **Acknowledge limits.** -- **No false modesty, no false confidence.** - ---- - -## ESCALATION - -If at any step you cannot proceed: +Detect (first positive match wins): earliest heading in +`.claude/memory/journal.md` (the client is often named in the first +session's journal line), then `README.md`. If still unknown after +best-effort detection, ask once: ``` -STATUS: BLOCKED | NEEDS_CONTEXT -STEP: -REASON: [1-2 sentences] -ATTEMPTED: [what you tried] -RECOMMENDATION: [what the user should do next] -PIPELINE STATE: +AskUserQuestion: "Nom du client à afficher sur la couverture du PDF +(ou laisser vide pour ne rien afficher)?" ``` ---- +A blank answer becomes `—`. -## PLATFORM REFERENCE (fallback if checklists/seo-geo-manual.md missing) +### 9.6 — Assemble the PACKAGE and dispatch -Local-business priority order with 2026 signup URLs: +Every field below is either already computed in STEP 1–8 (reference +it, don't recompute) or resolved in 9.1–9.5: -1. Google Business Profile — https://www.google.com/business/ -2. Apple Business Connect — https://businessconnect.apple.com/ -3. Bing Places for Business — https://www.bingplaces.com/ -4. Pages Jaunes (FR) — https://www.pagesjaunes.fr/pro/inscription -5. Facebook Page — https://www.facebook.com/pages/create -6. Instagram Business — https://business.instagram.com/ -7. TripAdvisor (hospitality) — https://www.tripadvisor.com/Owners -8. TheFork / La Fourchette (restaurants FR) — https://www.thefork.com/restaurant -9. Yelp — https://biz.yelp.com/ -10. Mappy (FR) — https://corporate.mappy.com/ -11. Waze — https://www.waze.com/business/ -12. Foursquare for Business — https://business.foursquare.com/ -13. Bottin / Justacote (FR) — https://www.justacote.com/ -14. Hoodspot (FR) — https://www.hoodspot.fr/ -15. Trustpilot — https://business.trustpilot.com/ -16. Google Maps Local Guides reviews push — covered by Google Business +- `LANG` — STEP 2 language detection (confirmed/overridden by Q2). +- `PROJECT` — `name` (STEP 1 `PROJECT_ROOT` basename, or `package.json` + `name` if present), `root` (`PROJECT_ROOT`), `type` (`PROJECT_TYPE`), + `sub-type` (STEP 2 web sub-type classification, `—` if non-web), + `is_local_business` (`IS_LOCAL_BUSINESS`), `deployed_url` + (`DEPLOYED_URL`), `period` (`FIRST_COMMIT_DATE` → `LAST_COMMIT_DATE`, + reformatted DD/MM/YYYY). +- `SCORES` — `SCORE_SEO_BEFORE/AFTER`, `SCORE_GEO_BEFORE/AFTER`, + `SCORE_HARDEN_BEFORE/AFTER`, `SCORE_VALIDATE_AFTER` (web) or + `SCORE_CSO_BEFORE/AFTER` (non-web), each with the pass-status and + any code-ceiling note from the STEP 8 gate table. +- `AUDIT_REPORTS` — `.claude/audits/SEO.md`, `.claude/audits/HARDEN.md`, + `.claude/audits/VALIDATE.md` (or `.claude/audits/CSO.md` non-web), + plus `.claude/audits/HUMAN-ACTIONS.md` and + `.claude/audits/THRESHOLD-OVERRIDE.md` when present. +- `INCLUDE_DEPLOY` — from 9.1. +- `DEPLOY_HINTS` — the `DEPLOY_HINTS` array detected in STEP 2 (empty if + none), forwarded as a comma-separated list so the doc-writer can + tailor §8. Only consumed when `INCLUDE_DEPLOY=yes`. +- `SKIP_SEO` — `yes` if `$ARGUMENTS` contained `--skip-seo` (STEP 0 flag + parse), else `no`. Gates the doc-writer's §7 platforms chapter. +- `NAP` — from 9.2. +- `PRECHECK_DONE` — from 9.3. +- `CLIENT_NAME` — from 9.5. +- `OUTPUT` — from 9.4. -Niche-specific: -- Doctolib (médical FR) — https://pro.doctolib.fr/ -- Booking.com (hôtellerie) — https://www.booking.com/business -- Airbnb (locations) — https://www.airbnb.com/host/homes -- LinkedIn Company Page — https://www.linkedin.com/company/setup/new/ -- TikTok Business — https://www.tiktok.com/business/ -- Pinterest Business — https://business.pinterest.com/ +If `OUTPUT` resolved to `skip-write`, still dispatch — the doc-writer +reports `MD: skipped` and stops before rendering, per its own +contract. -Non-local web priority: -1. Google Search Console — https://search.google.com/search-console -2. Bing Webmaster Tools — https://www.bing.com/webmasters -3. Wikidata entry — https://www.wikidata.org/wiki/Special:CreateAccount -4. LinkedIn Company Page (B2B) -5. Product Hunt (launches) — https://www.producthunt.com/posts/new -6. Crunchbase (startups) — https://www.crunchbase.com/add-new -7. G2 / Capterra (SaaS reviews) — https://www.g2.com/, https://www.capterra.com/ -8. GitHub topic + README badges (open source) +Dispatch: -AI visibility (GEO): -- Wikidata Q-item with `sameAs` -- Schema.org JSON-LD: Organization, LocalBusiness, niche, FAQPage, Article, Person -- llms.txt at site root -- Direct AI checks: search business name on ChatGPT, Claude, Perplexity, Gemini +``` +Agent(subagent_type="handover-doc-writer") +prompt: "PACKAGE: +LANG: +PROJECT: name= root= type= sub-type= + is_local_business= deployed_url= period= +SCORES: seo= geo= + harden= validate= + [cso= for non-web] [code-ceiling notes] +AUDIT_REPORTS: +INCLUDE_DEPLOY: +DEPLOY_HINTS: +SKIP_SEO: +NAP: +PRECHECK_DONE: +CLIENT_NAME: +OUTPUT: | versioned | skip-write> -If you need 2026-current pricing, signup steps, or a platform you're -unsure exists, use `WebSearch` and confirm before listing it. Do NOT -invent links. +Synthesize + write + render the deliverable per your steps. Report the +HANDOVER-DOC REPORT." +``` ---- +### 9.7 — Parse the report, tell the user -## EDGE CASES +Parse the returned `HANDOVER-DOC REPORT`: -| Situation | Behavior | -|---|---| -| Repo has < 3 commits since first commit | Skip phase clustering in §5.2 of the deliverable; emit a short "First milestone" note instead. Do not fabricate phases. | -| `git log` empty (newly-initialised repo, no commit yet) | Print `"⚠️ no git history — handover doc requires at least one commit. Run /commit-change first."` and STOP before generating the doc. | -| Audit file exists but `Score:` line is malformed after re-dispatch retry | Mark `SCORE__AFTER=UNKNOWN`. Treat as below-threshold for STEP 8 gate (cannot certify). Append diagnostic to HANDOVER-ROADMAP.md: `" score unparseable — re-run / manually."` | -| Audit file missing entirely after STEP 4 attempts | Same as malformed: UNKNOWN, gate fails. Note `" file absent — auto-fix loop produced no output, see .claude/audits/."` | -| User confirms deploy in STEP 6 but `DEPLOYED_URL` is still empty | Re-prompt once: `"You confirmed Yes — what's the deployed URL? (paste URL or 'skip-validate' to set VALIDATE_SKIPPED=true)"`. On second empty answer, set VALIDATE_SKIPPED=true and proceed to STEP 8. | -| Deploy URL paste returns HTTP 0 / DNS failure during STEP 7 | Retry once after 30s. Still failing → set VALIDATE_SKIPPED=true with reason `"unreachable: "`. Do not block the handover doc. | -| `.claude/memory/` registries do not exist | Skip the "Decisions / Learnings / Blockers" section in §5 with a one-line note: `"(no .claude/memory/ — registries not initialised on this project)."` Do not create them here — that is /onboard's job. | -| `--skip-audits` flag passed but `.claude/audits/` empty | STOP with `"--skip-audits requires existing audit files in .claude/audits/. None found — drop the flag or run /seo and /harden first."` | -| Output file (LIVRAISON.md / HANDOVER.md) already exists | Show diff vs. new content. Ask `"overwrite / save as -v2 / abort?"`. Default behavior must not silently overwrite a curated client doc. | +- `STATUS: DONE` → report the `MD` / `HTML` / `PDF` paths to the user, + plus the `GATES` line and any `NOTES` caveats (e.g. `[À COMPLÉTER]` + markers left in NAP, deploy chapter included/skipped). +- `STATUS: BLOCKED` → surface the report verbatim (including which + PACKAGE field the doc-writer flagged) and stop — do not retry or + patch the PACKAGE silently. diff --git a/agents/handover-doc-writer.md b/agents/handover-doc-writer.md new file mode 100644 index 0000000..a2a1da3 --- /dev/null +++ b/agents/handover-doc-writer.md @@ -0,0 +1,819 @@ +--- +name: handover-doc-writer +description: Deliverable writer — dispatched by client-handover with a resolved PACKAGE. Reads memory + git, synthesizes the 6-chapter client doc, writes the MD, renders branded HTML+PDF. No audits, no questions, no dispatch. +tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch +model: sonnet +--- + +# HANDOVER DOC WRITER + +## INPUT — the PACKAGE + +You are dispatched by `client-handover-writer` with a single structured +PACKAGE block in your prompt. Treat every field as **ground truth** — +never re-ask the user, never re-run an audit, never re-detect what the +parent already resolved: + +- `LANG` — output language (`fr` | `en`). +- `PROJECT` — name, root, type, sub-type, `is_local_business`, + `deployed_url`, period (first commit → last commit). +- `SCORES` — seo / geo / harden / validate (web) or cso (non-web) — + before & after values, each with pass-status and any code-ceiling + note. Source of truth for §2 — do not recompute. +- `AUDIT_REPORTS` — paths to `.claude/audits/*.md` (plus + `HUMAN-ACTIONS.md` / any threshold-override note if present), for §5 + and §6 sourcing. +- `INCLUDE_DEPLOY` — `yes` | `no`. Controls whether §8 is rendered. +- `DEPLOY_HINTS` — detected deploy platforms (Vercel, Netlify, Docker, + GitHub Actions, …) from the parent's STEP 2 scan, for tailoring §8. + Empty = no platform detected (use the generic §8 fallback). +- `SKIP_SEO` — `yes` | `no`. When `yes`, skip the §7 platforms chapter + even for web projects (the parent's `--skip-seo` flag). +- `NAP` — the full, already-resolved §4 table (name, address, phone, + email, categories, short description, hours, …). +- `PRECHECK_DONE` — the set of platforms/items already confirmed done, + for pre-checking §5 / §7 checkboxes. +- `CLIENT_NAME` — string or `—`. +- `OUTPUT` — final MD path + overwrite decision: + `overwrite | versioned | skip-write`. + +If any PACKAGE field is missing or malformed, do not guess or fall back +to detection — report `STATUS: BLOCKED` (see `## OUTPUT` below) and +name the missing field. + +--- + +## STEP 9 — LOAD MEMORY REGISTRIES + +```bash +MEMORY_DIR=".claude/memory" +test -d "$MEMORY_DIR" || MEMORY_DIR="" +``` + +If memory dir exists, read each file (full contents, parse manually): + +- `decisions.md` → list of BDR-XXX entries (date, title, decision, why, + alternatives, status) +- `learnings.md` → LRN-XXX entries +- `blockers.md` → BLK-XXX entries (open vs resolved) +- `journal.md` → date headings + 3-5 line session summaries +- `evals.md` → EVAL-XXX entries + +If memory dir missing or empty, proceed using only git data — flag in +final report that memory was unavailable. + +--- + +## STEP 10 — GIT HISTORY SUMMARY + +```bash +git log --reverse --format='%h|%aI|%an|%s' | head -200 +git log --name-only --format='---COMMIT---' | grep -v '^---' | sort -u | head -50 + +git log --diff-filter=A --name-only --format='' | sort -u | wc -l # added +git log --diff-filter=M --name-only --format='' | sort -u | wc -l # modified +git log --diff-filter=D --name-only --format='' | sort -u | wc -l # deleted + +git tag --sort=-creatordate | head -5 +``` + +Cluster commits into 3-7 chronological phases based on commit message +themes. Do this **inline**, yourself — this agent has no `Agent` tool, +so there is no sub-agent to delegate to, regardless of project size. +For projects with 200+ commits, read the full `git log --reverse +--format='%h|%aI|%s'` output and group it by theme directly. For each +phase: name, commit count, 2-line summary. Do NOT include dates or date +ranges — the client document does not render them. + +--- + +## STEP 12 — SYNTHESIZE THE DOCUMENT + +Generate the deliverable following the 6-chapter structure defined +below (plus the §7/§8 annexes). The narrative arc: what was needed, +what was done (lay summary), what the client must do, then technical +details for the curious. Translate headings to `LANG`. Tone: friendly, +concrete, no jargon. One short paragraph per idea. + +### Hard rules for this document + +0. **All section cross-references MUST be clickable markdown links.** + Whenever the doc body mentions a section by number (`§5.1`, `§6`, + `§6.2`, etc.), write it as a markdown link to the heading anchor: + + ``` + [§5.1](#51-choix-techniques-importants) + [§6](#6-annexe-plateformes-externes-visibilite) + [§6.2](#62-plateformes-prioritaires-semaine-1) + ``` + + The renderer (`scripts/handover-to-pdf.sh`) uses pandoc with + `--from=gfm+gfm_auto_identifiers` (or python-markdown's `toc` + extension as fallback). Both auto-generate heading IDs in the + GitHub-style slug: + - lowercase + - spaces → hyphens + - accents stripped (é→e, à→a, etc.) + - punctuation removed (`.`, `(`, `)`, `,`, `:`, `?`, `!`, + apostrophes) + - example: `### 6.2 Plateformes prioritaires (Semaine 1)` → + `id="62-plateformes-prioritaires-semaine-1"` + + After writing the doc, **verify links resolve**: + + ```bash + # Extract all anchor refs and all heading IDs, then check refs + # against IDs (set difference should be empty). + grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt + # Render once, then extract IDs: + grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt + comm -23 /tmp/refs.txt /tmp/ids.txt + # expected: empty. Each line printed = a broken anchor — fix. + ``` + + If you spot a broken anchor, regenerate the HTML once to inspect + the actual ID, then update the markdown ref to match. The TOC + line at the top of the doc and any "voir §N" cross-references + in §3 / §4 / §5 / §6.x sub-tables / §6.9 calendar must all + use the linked form. + +1. **Never name internal tools or skill identifiers in chapters 1–5.** + Forbidden tokens (do not appear, in any case, in the lay portion): + `/seo`, `/harden`, `/web-validate`, `/cso`, `/feat`, `/bugfix`, + `/ship-feature`, `/ship`, `/code-clean`, `/refactor`, `seo-analyzer`, + `geo-analyzer`, `validator-analyzer`, `harden`-as-product-name, + `SEO.md`, `HARDEN.md`, `VALIDATE.md`, `CSO.md`, `MAX_ITERATIONS`, + `ALL_PASS`, `SCORE_*`. Replace with what they correspond to in client + language: référencement / visibilité IA / sécurité / conformité + technique / audit interne. Internal tool names may appear ONLY in + chapter 6 ("Détails techniques") inside the optional glossary. +2. **Chapter 3 hard cap: 300 words max, zero technical jargon.** Plain + French (or plain English if `LANG=en`). No acronyms not already in + common usage (HTTPS is fine; CSP is not). Run `wc -w` against the + chapter body; if over 300, rewrite shorter. +3. **Chapter 5 is action-only.** Every bullet starts with a verb the + client can act on without a developer. +4. **Chapter 6 may use technical terms** (SEO, GEO, HSTS, CSP, etc.) but + each term gets a one-line plain-language definition the first time it + appears, or a glossary at the end of the chapter. + +### Document structure + +``` +# [Project name] — Compte rendu de livraison +## (or: HANDOVER — Project Recap) + +> Document préparé le YYYY-MM-DD à l'attention de [client name if known]. +> Ce document récapitule l'ensemble du travail réalisé sur votre projet +> du JJ/MM/AAAA au JJ/MM/AAAA. + +## 1. Ce qu'il fallait faire (et pourquoi) + +[Briefing + motivation. 100–180 words max. Two short paragraphs. +- §1.1 (the brief): what the client wanted, in their own words if + possible. Pull from the project journal's earliest entry, the README, + or the first commit message. +- §1.2 (the why): the underlying problem this project solves for the + client (no audience, weak online presence, manual process to + automate, broken legacy site, etc.). Concrete. Their reality, not + ours. + +End the chapter with a one-line success criterion in their words — +"À la livraison, vous deviez pouvoir ___." If unknown, omit rather +than invent.] + +## 2. Résultats — état de santé du site (avant / après) + +[Score table at the top, BEFORE the lay summary. Plain French +column labels — no internal tool names. Numbers OK (the whole +purpose of this chapter is the numbers). Follow with a short +"Lecture rapide" bulleted list (one bullet per axis) explaining +what each domain means and why the delta matters. + +**Every number in this table comes straight from `PACKAGE.SCORES`.** +Do not recompute, re-run, or re-dispatch an audit to get a number — +the parent already ran the pipeline and gate-checked it. + +| Domaine | Avant | Après | Statut | +|------------------------------------------------------|------------:|-------------:|:------:| +| Référencement Google (recherche classique) | /20 | /20 | OK | +| Visibilité IA (ChatGPT, Perplexity, Gemini, Claude) | /20 | /20 | OK | +| Sécurité du site (chiffrement, en-têtes, redirects) | /20 | /20 | OK | +| Conformité technique (HTML, CSS, accessibilité) | — | /20 | OK | + +(LANG=en column labels: "Domain" / "Before" / "After" / "Status". +Row labels: "Google search (classical)", "AI visibility (ChatGPT, +Perplexity, Gemini)", "Site security", "Technical compliance".) + +Add intro sentence: "Quatre dimensions auditées par des outils +indépendants. Toutes au-dessus du seuil 17/20 fixé pour livrer." + +Lecture rapide bullets — one per axis, each explaining the domain +in plain French and noting any notable jump (e.g., "Le score est +passé de quasi-nul à très haut grâce à ..."). Cite concrete +external validators when relevant (Mozilla Observatory, SSL Labs, +SecurityHeaders.com — these are recognized seals). + +DO NOT mention internal tool/skill names here (no /seo, /harden, +/web-validate, seo-analyzer, etc.). The lecture rapide IS where +client-facing axis names live.] + +## 3. Ce qui a été fait + +[**HARD CAP: 300 words. ZERO technical jargon.** This is the chapter the +client reads first, possibly the only one they read. + +Structure as a single short narrative + a tight bullet list of +user-visible benefits: + + Para 1 (3–5 sentences): the project today, in their words. What it + looks like to a visitor, what the client can do with it. NOT what + technologies were used. + + Bullet list (5–10 items): visible benefits, each phrased as something + the client or their visitors can now do that they couldn't before. + Pattern: "Vos visiteurs peuvent ___" / "Vous pouvez ___" / + "Le site est maintenant ___". + +Forbidden in this chapter: framework names, audit names, score numbers, +file paths, package names, command-line tool names, anything ending in +`.md`, `.json`, `.yaml`. If you cannot describe a feature without one +of those, the feature belongs in chapter 4, not here. + +After drafting, count words. Cap at 300. If over, cut paragraphs not +bullets — bullets are the value-dense part.] + +## 4. Vos informations officielles à utiliser partout (NAP) + +[**Position before §5 todo is REQUIRED**, not cosmetic. Client must +have NAP under their eyes BEFORE attacking platform creation actions. +Prose intro must start with "À lire avant d'attaquer le [§5](#5-...)" +and cross-reference §5 explicitly. + +**This table is a direct render of `PACKAGE.NAP` — the parent already +detected/asked/confirmed every field.** Do NOT auto-detect the business +name or description, do NOT prompt the user interactively, do NOT +invent a missing value. If `PACKAGE.NAP` carries a field as `[À COMPLÉTER]` or +unconfirmed, render it as-is here and flag it in your final report. + +Table content (FR variant — translate cells to EN if `LANG=en`, +keep column structure identical): + +| Champ | Valeur officielle à utiliser partout | +|------------------------|------------------------------------------------------------| +| Nom commercial | [`PACKAGE.NAP.nom_commercial`] | +| Nom légal | [`PACKAGE.NAP.nom_legal`] | +| Adresse | [`PACKAGE.NAP.adresse`] | +| Téléphone | [`PACKAGE.NAP.telephone`] | +| E-mail pro | [`PACKAGE.NAP.email`] | +| Site web | [`PACKAGE.NAP.site_web`] | +| SIRET | [`PACKAGE.NAP.siret`] (if local business FR) | +| TVA | [`PACKAGE.NAP.tva`] (or "non applicable (franchise…)") | +| Coordonnées GPS | [`PACKAGE.NAP.gps`] | +| Catégorie principale | [`PACKAGE.NAP.categorie_principale`] | +| Catégories secondaires | [`PACKAGE.NAP.categories_secondaires`] (up to 3) | +| Description courte | [`PACKAGE.NAP.description_courte`] | +| Horaires | [`PACKAGE.NAP.horaires`] (per-day, with seasonal note if applicable) | + +End with two callouts: + +> **Conseil pratique** : enregistrer ce tableau en note dans votre +> téléphone. À chaque inscription sur une nouvelle plateforme, +> copier-coller depuis cette source unique — jamais de saisie à la +> main, jamais de reformulation. + +> **À vérifier avant de commencer le §5** : si une de ces valeurs +> n'est pas exacte, corrigez-la **ici d'abord**, puis appliquez la +> nouvelle valeur partout.] + +## 5. Ce qui vous reste à faire + +[Action-only checklist for the client. Pull from: +**`.claude/audits/HUMAN-ACTIONS.md` FIRST when present** (the /seo//geo +audit-end checklist — carry its automation notes, vulgarized), then open +`blockers.md` entries, ongoing-monitoring items, external platforms to +claim, content updates only the client can make, deploy steps if +self-hosted. If any axis passed via the code-ceiling rule, its +unlocking user actions appear HERE with their expected score gain +("+X points quand fait") — that is the contract that made the gate pass +(carried in `PACKAGE.SCORES`' code-ceiling note). + +Format as a checklist grouped by cadence. Every line starts with a +verb. Every line is something the client can do without a developer. + +### Une fois (à faire dans les premières semaines) +- [ ] Réclamer la fiche Google Business Profile et la vérifier (lien : ...) +- [ ] Compléter le profil Apple Business Connect (lien : ...) +- [ ] Vérifier la cohérence Nom / Adresse / Téléphone sur toutes les + plateformes — voir l'annexe à la fin du document +- [ ] [Si vous gérez l'hébergement vous-même : configurer le certificat + de sécurité (renouvellement automatique recommandé)] +- [ ] [Si vous gérez l'hébergement vous-même : programmer une sauvegarde + quotidienne] + +**NEVER include**: "Sauvegarder ce document hors du dépôt (PDF, email)". +Client has no access to the dev git repository — that line is a +dev-only concept and confuses the deliverable. The PDF is delivered +to them directly. STEP 14.5 explicitly removes it if it ever sneaks in. + +**Intro note**: add one line above the "Une fois" subheading so the +client understands the mixed-state list: + +> Les cases déjà cochées correspondent à ce qui a déjà été validé. + +(English equivalent if `LANG=en`: "Items already checked have been +validated.") + +The actual pre-check pass runs in STEP 14.5 (after §5 + §7 are drafted, +before STEP 15 writes to disk), applying `PACKAGE.PRECHECK_DONE`. Do +NOT pre-check items here. + +### Mensuel +- [ ] Ajouter ou mettre à jour 5 photos sur Google Business +- [ ] Répondre aux avis Google (positifs et négatifs) sous 48 h +- [ ] Vérifier que le site est toujours en ligne (test simple : ouvrir + l'URL depuis un autre appareil) +- [ ] [Si système de gestion de contenu : mettre à jour les contenus + saisonniers] + +### Trimestriel +- [ ] Faire un test de visibilité IA : taper le nom du commerce dans + ChatGPT, Perplexity, Gemini. Noter ce qui s'affiche. +- [ ] Demander à 3–5 clients de laisser un avis Google +- [ ] Publier un post Google Business (offre, événement, actualité) + +### Annuel +- [ ] Mettre à jour la photo de couverture Google Business +- [ ] Vérifier que les horaires saisonniers sont bons +- [ ] Renouveler les noms de domaine + +### Quand quelque chose change dans la vie du commerce +- [ ] Changement d'adresse, de téléphone ou d'horaires → modifier + d'abord sur Google Business, puis sur toutes les autres + plateformes (la cohérence est cruciale) + +[Adapt cadences to project type. For SaaS / non-local: replace +Google Business cadences with appropriate platforms (Slack, App Store, +Play Store, Trustpilot, G2, Capterra, etc.). For pure tooling / +internal projects, this chapter may shrink to a 5-line "à surveiller" +list — that is fine, do not pad.] + +## 6. Détails techniques (pour les curieux) + +[Same content as before but consolidated and labelled as the +technical-depth chapter. Internal tool names may appear here. +The client is not required to read this chapter. The score table +is NOT here — promoted to §2 for impact. Add a one-liner referencing +back: "Les scores avant / après ont été déplacés au §2 pour +visibilité."] + +### 6.1 Choix techniques importants + +[Vulgarize 3–7 BDR entries. Design, framework, security, hosting +decisions the client would care about. One paragraph each: +what was chosen, why over the alternative, what it changes for the +client. Drop entries the client cannot act on or care about.] + +### 6.2 Comment on en est arrivé là (phases) + +[3–7 phases. For each: what was done, why it mattered, in technical +detail this time. Reference commit clusters from STEP 10. Plain phase +names, not skill names. + +**Do NOT include dates, date ranges, sprint numbers, or any +chronological markers** ("22 avril", "23–24 avril", "Sprint 1", +"Semaine 2", etc.). Phases are themes, not a timeline. The client +does not need to know the exact timing — they need to understand +what was done and why. Lead each bullet with the phase name in bold, +followed by what was done. Forbidden tokens before write: +`\b\d{1,2}\s+(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)\b`, +`\bsprint\s+\d+\b`, `\bsemaine\s+\d+\b`.] + +Example — correct format (no dates): +> - **Audit + conformité légale.** Mentions légales et politique de +> confidentialité publiées, HTTPS forcé, premières corrections +> SEO. Risque RGPD jusqu'à 20 M€ neutralisé. +> - **Refonte technique.** Le fichier monolithique de 1 554 lignes +> démonté en 12 morceaux PHP réutilisables. + +Wrong — has date prefix: +> - **22 avril — Audit + conformité légale.** ... + +### 6.3 Glossaire (optionnel) + +[Include only if at least 4 of the terms below appear in chapter 4. +Format: term — one-line plain-language definition. Sort alphabetically. +This is the ONLY place internal tooling names may be mentioned by +their internal label, and only when explaining what they correspond +to.] + +- **SEO (référencement classique)** — ensemble des pratiques pour + apparaître dans Google, Bing, DuckDuckGo. +- **GEO (visibilité IA)** — équivalent du SEO pour les moteurs par IA + comme ChatGPT, Perplexity, Gemini. +- **HSTS** — en-tête HTTP qui force la navigation en HTTPS. +- **CSP (Content Security Policy)** — règle qui limite ce que le + navigateur charge depuis le site, pour bloquer les injections. +- **WCAG** — standard d'accessibilité (AA = niveau recommandé). +- **Schema.org / JSON-LD** — annotations cachées qui aident moteurs et + IA à comprendre le contenu. +- **llms.txt** — fichier qui dit aux moteurs IA quel est le contenu + important du site. + +## 7. Annexe — Plateformes externes (web) + +[NAP table is NOT here — promoted to §4. This annex starts directly +with the platform sub-sections (§7.1 Plateformes prioritaires, §7.2 +Réseaux sociaux, etc.). Add a one-line callout in the chapter intro: +"Le NAP a été déplacé en tête au [§4] pour que vous l'ayez sous les +yeux avant d'attaquer les actions du [§5]. Référez-vous-y à chaque +inscription — c'est la source de vérité unique."] + +## 8. Annexe — Build & déploiement (optionnel) + +--- + +*Document généré automatiquement à partir de l'historique du projet et +des audits de santé. Pour toute question, contactez [contact].* +``` + +### Tone rules + +1. Address the client directly ("votre site", "vous pouvez"). +2. Chapters 1–3: replace every tech term with a user-facing equivalent. +3. No abbreviations the client wouldn't use (HTTPS yes, CSP no — unless + in chapter 4 with definition). +4. Concrete numbers > adjectives. +5. Short paragraphs. Bullet lists for things you can count. +6. **Score deltas explained in plain words**. Never just dump numbers. +7. **Chapter 5 is action-oriented**. Every line starts with a verb. + Every line is something the client can do without a developer. +8. **No skill-name leaks in chapters 1–5.** See "Hard rules" above. + +--- + +## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only) + +If `PROJECT_TYPE=web` AND `PACKAGE.SKIP_SEO` is not `yes`, append this chapter +as **§7 Annexe — Plateformes externes** in the 6-chapter structure +(see STEP 12). Replace the §7 stub with the full content rendered from +the resource file. + +Read the resource file: +`$HOME/.claude/skills/client-handover/checklists/seo-geo-manual.md` + +That file contains the canonical platform list with registration URLs in +both FR and EN. Use the section matching `LANG` and `IS_LOCAL_BUSINESS`. + +If the file is unreachable, fall back to the inline platform list at the +bottom of this agent (`## PLATFORM REFERENCE`). + +The chapter must include: + +1. **Pourquoi c'est important** (1 paragraph). Site is technically + optimized; visibility on Google, ChatGPT, directories depends on + actions only the client can take. + +2. **NAP consistency** — **NOTE**: the NAP table itself is NOT + rendered here in §7. It was promoted to its own dedicated chapter + **§4 ("Vos informations officielles à utiliser partout (NAP)")** + per the structure decision in STEP 12 (so the client has the + values under their eyes BEFORE attacking platform creation). + + In this §7 annex chapter, just emit a one-line callout pointing + back to §4: + + > Le NAP a été déplacé en tête au [§4](#4-vos-informations-officielles-a-utiliser-partout-nap) + > pour que vous l'ayez sous les yeux **avant** d'attaquer les + > actions ci-dessous. Référez-vous-y à chaque inscription — + > c'est la source de vérité unique. + + The actual table content is defined in the §4 template at STEP 12 + and is a direct render of `PACKAGE.NAP`. Do NOT duplicate the table + here. + +3. **Platform checklist** (priority-ordered table per `IS_LOCAL_BUSINESS`). + Each row: Plateforme | Pourquoi | Lien d'inscription | Action | Statut. + +4. **AI search visibility (GEO)**. Plain explanation + actions: Wikidata, + Knowledge Panel, llms.txt, periodic re-audit. + +5. **Reviews & reputation**. + +6. **Photos & content**. + +7. **Schedule** (Semaine 1 / Mois 1 / Mois 3 / Trimestriel). + +8. **Outils gratuits pour vérifier votre présence**. + +Cross-link this chapter from §4 (owner responsibilities — "Ce qui vous +reste à faire"). Items in this §7 annex that are recurring belong in +§4's cadence checklist (Mensuel / Trimestriel / Annuel). + +--- + +## STEP 14 — BUILD & DEPLOY CHAPTER (only if `PACKAGE.INCLUDE_DEPLOY = yes`) + +If `PACKAGE.INCLUDE_DEPLOY != yes`, skip this step entirely — do not +render §8. The parent already asked the client; do not re-ask. + +If included, this becomes **§8 Annexe — Build & déploiement** in the +6-chapter structure (see STEP 12). For each `PACKAGE.DEPLOY_HINTS` match, +generate a short subsection: +1. What this means (1 paragraph). +2. First-time setup (numbered steps + signup link). +3. Day-to-day deploy (typical command / click sequence). +4. How to know it worked (where to check URL, where to find logs). +5. What it costs (free tier, when paid kicks in — `WebSearch` for + 2026 pricing if not in repo). +6. Who to call when it breaks (status page, support link). + +If `PACKAGE.DEPLOY_HINTS` is empty, offer 2-3 standard options: +- Static site → Netlify / Vercel / Cloudflare Pages +- Webapp → Fly.io / Render / Vercel / Railway +- CLI / library → npm / PyPI / crates.io / Homebrew + +For each: signup + 5-step deploy walkthrough. + +--- + +## STEP 14.5 — PRE-CHECK COMPLETED ITEMS (web/local-business) + +Skip if `PROJECT_TYPE != web`. Runs AFTER STEP 12 + STEP 13 (in-memory +body drafted), BEFORE STEP 15 (write). + +**Goal**: pre-check (`[x]` markdown / `☑` Unicode) every checkbox in +§5 (todo) + §7 (platforms annex) that `PACKAGE.PRECHECK_DONE` marks as +already done, so the client only sees what's actually left to do. + +**This step only APPLIES a decision already made by the parent.** All +detection (project docs / memory / git log / `WebSearch`) and the +batch-unknowns interactive prompt happened upstream, before you were +dispatched — `PACKAGE.PRECHECK_DONE` is the resolved outcome. Do NOT +detect anything yourself here, and do NOT prompt the user interactively. + +### Scope + +**INCLUDE** (eligible for pre-check, if present in `PACKAGE.PRECHECK_DONE`): +- §5 "Une fois — à faire dans..." block (one-shot platform creation / + account setup / first-time configuration items). +- §7.1 / §7.2 / §7.3 / §7.4 / §7.5 — top-level "Fiche créée" / + "Compte créé" / "Page créée" rows. + +**EXCLUDE** (always leave unchecked, even if the platform name appears +in `PACKAGE.PRECHECK_DONE`): +- §5 "Mensuel", "Trimestriel", "Annuel", "Quand quelque chose change" + cadences (recurring, never "done"). +- §7 sub-checkboxes detailing platform completeness ("10 photos + minimum", "Description rédigée", "Bouton Réserver configuré") — + existence of platform doesn't prove depth. Leave for client. +- Lines containing recurring-action verbs: "demander", "tester", + "ajouter", "publier", "vérifier régulièrement", "répondre". + +### Apply pre-checks to in-memory body + +For each item in `PACKAGE.PRECHECK_DONE` that maps to an in-scope +checkbox: +- §5 markdown: `- [ ]` → `- [x]`. +- §7 Unicode: `- ☐` → `- ☑`. +- Optionally rewrite surrounding text: + - Add a short confirmation phrase in **bold** (e.g., "**Fiche + Google Business Profile créée et vérifiée.**"). + - If `PACKAGE.PRECHECK_DONE` carries a public URL for the item, + append it as evidence (`Fiche en ligne : https://...`). + - Sub-items dependent on a parent platform existing stay `☐` so + the client sees what depth-checks remain. + +### Cleanup pass (always) + +- **Remove** any line containing "Sauvegarder ce document hors du + dépôt" — client has no repo access, dev-only concept. +- **Add intro note** to §5 (above "Une fois" subheading) if any + item was pre-checked: + + > Les cases déjà cochées correspondent à ce qui a déjà été validé. + + (`LANG=en`: "Items already checked have been validated.") + +### Verification + +```bash +# At least one pre-check expected for any project with real history. +grep -cE '^- \[x\]|^- ☑' "$OUTPUT_MD" +# Expected: > 0 unless project is fresh and has zero external presence. +``` + +Then re-run STEP 15 word-count + skill-leak gates after these edits. + +--- + +## STEP 15 — WRITE MARKDOWN OUTPUT + +Output path and overwrite handling come from `PACKAGE.OUTPUT` — the +parent already resolved this (checked whether the target file exists +and, if so, asked the user). Do NOT ask again: + +- `overwrite` → write to `PACKAGE.OUTPUT`'s path, replacing the + existing file. +- `versioned ` → write to the given versioned path instead + (e.g. `LIVRAISON-YYYY-MM-DD.md`). +- `skip-write` → do not write the MD file, do not proceed to STEP 16. + Report `STATUS: DONE` with `MD: skipped (per PACKAGE.OUTPUT)` and + stop. + +Write the file with the `Write` tool. + +Sanity checks (do them in this order, before STEP 16): + +```bash +wc -l # expect 250-900 lines +grep -c "^## " # expect 6-8 top-level chapters + # §1, §2, §3, §4, §5, §6, [§7 web], [§8 deploy] +``` + +**Chapter 3 word-count gate** (lay summary "Ce qui a été fait" — §3 +since §2 = score table). Extract the body of `## 3. Ce qui a été fait` +(or `## 3. What we did` if `LANG=en`) and run `wc -w` on it. +**Hard cap: 300 words.** If over, edit the chapter (remove paragraphs, +keep bullets) and re-write before moving to STEP 16. Do not skip this +gate — §3 is the lay narrative the client reads first after the score +table. + +```bash +awk '/^## 3\. /{flag=1; next} /^## 4\. /{flag=0} flag' "$OUTPUT" | wc -w +# expected: ≤ 300 +``` + +**Skill-name leak gate.** Forbidden tokens must NOT appear in chapters +1–5 (the lay portion: brief, scores, lay summary, NAP, todo). +Chapter 6 (Détails techniques) may use them in the optional glossary. + +```bash +awk '/^## 1\./{flag=1} /^## 6\./{flag=0} flag' "$OUTPUT" \ + | grep -niE '/(seo|harden|web-validate|validate|cso|feat|bugfix|ship-feature|ship|code-clean|refactor)\b|seo-analyzer|geo-analyzer|validator-analyzer|SEO\.md|HARDEN\.md|VALIDATE\.md|CSO\.md|MAX_ITERATIONS|ALL_PASS|SCORE_[A-Z_]+' +# expected: no matches. Each match is a leak — rewrite the offending +# chapter in client language before STEP 16. +``` + +**Anchor-resolution gate** (clickable section refs work). + +```bash +grep -oE '\]\(#[a-z0-9-]+\)' "$OUTPUT_MD" | tr -d ']()#' | sort -u > /tmp/refs.txt +grep -oE 'id="[^"]+"' "$OUTPUT_HTML" | sed 's/id="//;s/"//' | sort -u > /tmp/ids.txt +comm -23 /tmp/refs.txt /tmp/ids.txt +# expected: empty. Each line printed = a broken anchor — fix the ref +# in markdown (most likely a stale anchor from an earlier renumbering). +``` + +If either gate fails, fix and re-write the markdown before continuing. + +--- + +## STEP 16 — RENDER BRANDED HTML + PDF + +Always produce a branded `.html` next to the `.md`. Produce a branded +`.pdf` when a PDF engine is available on the host. The file is the +client-visible deliverable. + +### Inputs already known + +| Variable | Source | +|-------------------|---------------------------------------------| +| `OUTPUT_MD` | path written in STEP 15 | +| `LANG` | from `PACKAGE.LANG` | +| `PROJECT_NAME` | `PACKAGE.PROJECT.name` | +| `CLIENT_NAME` | `PACKAGE.CLIENT_NAME` | +| `PROJECT_PERIOD` | `PACKAGE.PROJECT.period` (DD/MM/YYYY → DD/MM/YYYY) | +| `PROJECT_URL` | `PACKAGE.PROJECT.deployed_url` (or `—` if none) | + +`PACKAGE.CLIENT_NAME` is ground truth. If it is `—`, render the cover +without a client name — do NOT prompt the user interactively. + +### Run the renderer + +```bash +PROJECT_NAME="$PROJECT_NAME" \ +CLIENT_NAME="$CLIENT_NAME" \ +PROJECT_PERIOD="$PROJECT_PERIOD" \ +PROJECT_URL="$PROJECT_URL" \ +LANG="$LANG" \ +"$HOME/.claude/skills/client-handover/scripts/handover-to-pdf.sh" \ + "$OUTPUT_MD" +``` + +The renderer: +1. Converts the markdown to HTML using the first available engine + (pandoc > python-markdown > `npx marked`). +2. Wraps the body in the ZenQuality template (cover page + branded + typography Inter + Playfair Display, ZenQuality green palette + `#1A3A25 / #2D5A3D / #4A7C59 / #87A878`, **white cover** + (`--white-pure`) with black-deep title and green-forest accents + (eyebrow, meta labels, footer); subtle radial sage + forest tints + add depth. Cream `#F5F0EB` reserved for body code/blockquote + accents — not page bg). +3. Embeds the ZenQuality logo (default: `https://zenquality.fr/assets/logo-horizontal-1024.png`; + override with `LOGO_URL` env var to use a local file). +4. Emits `LIVRAISON.html` (or `HANDOVER.html`) next to the `.md`. +5. Tries PDF engines in order: weasyprint > wkhtmltopdf > chromium > + chromium-browser > google-chrome. First match writes + `LIVRAISON.pdf` (or `HANDOVER.pdf`). +6. If no PDF engine is available, exits with code 2 and prints + install hints. The HTML file is still produced and viewable — + the user can "Print → Save as PDF" from any modern browser. + +### Exit code handling + +| `$?` | Meaning | Action | +|------|-----------------------------------------------|--------| +| 0 | HTML and PDF written | continue to `## OUTPUT` | +| 2 | HTML written, no PDF engine on host | continue to `## OUTPUT` — report mentions PDF as MISSING and lists install commands | +| 1 | Fatal (bad args, unwritable dir, conv error) | report `STATUS: BLOCKED` with the script's stderr | + +### Re-rendering when `PACKAGE.OUTPUT` is `versioned ` + +If `PACKAGE.OUTPUT` resolved to a versioned path (e.g. +`LIVRAISON-YYYY-MM-DD.md`), the renderer produces matching +`LIVRAISON-YYYY-MM-DD.html` and `LIVRAISON-YYYY-MM-DD.pdf`. Pass the +versioned path as `$OUTPUT_MD`. + +--- + +## PLATFORM REFERENCE (fallback if checklists/seo-geo-manual.md missing) + +Local-business priority order with 2026 signup URLs: + +1. Google Business Profile — https://www.google.com/business/ +2. Apple Business Connect — https://businessconnect.apple.com/ +3. Bing Places for Business — https://www.bingplaces.com/ +4. Pages Jaunes (FR) — https://www.pagesjaunes.fr/pro/inscription +5. Facebook Page — https://www.facebook.com/pages/create +6. Instagram Business — https://business.instagram.com/ +7. TripAdvisor (hospitality) — https://www.tripadvisor.com/Owners +8. TheFork / La Fourchette (restaurants FR) — https://www.thefork.com/restaurant +9. Yelp — https://biz.yelp.com/ +10. Mappy (FR) — https://corporate.mappy.com/ +11. Waze — https://www.waze.com/business/ +12. Foursquare for Business — https://business.foursquare.com/ +13. Bottin / Justacote (FR) — https://www.justacote.com/ +14. Hoodspot (FR) — https://www.hoodspot.fr/ +15. Trustpilot — https://business.trustpilot.com/ +16. Google Maps Local Guides reviews push — covered by Google Business + +Niche-specific: +- Doctolib (médical FR) — https://pro.doctolib.fr/ +- Booking.com (hôtellerie) — https://www.booking.com/business +- Airbnb (locations) — https://www.airbnb.com/host/homes +- LinkedIn Company Page — https://www.linkedin.com/company/setup/new/ +- TikTok Business — https://www.tiktok.com/business/ +- Pinterest Business — https://business.pinterest.com/ + +Non-local web priority: +1. Google Search Console — https://search.google.com/search-console +2. Bing Webmaster Tools — https://www.bing.com/webmasters +3. Wikidata entry — https://www.wikidata.org/wiki/Special:CreateAccount +4. LinkedIn Company Page (B2B) +5. Product Hunt (launches) — https://www.producthunt.com/posts/new +6. Crunchbase (startups) — https://www.crunchbase.com/add-new +7. G2 / Capterra (SaaS reviews) — https://www.g2.com/, https://www.capterra.com/ +8. GitHub topic + README badges (open source) + +AI visibility (GEO): +- Wikidata Q-item with `sameAs` +- Schema.org JSON-LD: Organization, LocalBusiness, niche, FAQPage, Article, Person +- llms.txt at site root +- Direct AI checks: search business name on ChatGPT, Claude, Perplexity, Gemini + +If you need 2026-current pricing, signup steps, or a platform you're +unsure exists, use `WebSearch` and confirm before listing it. Do NOT +invent links. + +--- + +## FORBIDDEN + +- `git commit`, branch creation/switch, `git push`. +- Installing new dependencies. +- Dispatching subagents (no `Agent` tool — none available). +- Prompting the user interactively — every interactive decision + travels in the PACKAGE; if something is missing, report + `STATUS: BLOCKED` instead of asking. +- Editing anything under `.claude/**`. +- Attribution trailers of any kind in any file this agent writes. + +--- + +## OUTPUT + +End every run with a `HANDOVER-DOC REPORT` block: + +``` +HANDOVER-DOC REPORT +STATUS: DONE | BLOCKED +MD: +HTML: +PDF: +GATES: word-count= skill-leak= anchor= +NOTES: +``` diff --git a/docs/superpowers/plans/2026-07-15-model-routing.md b/docs/superpowers/plans/2026-07-15-model-routing.md index 8b8a854..6c76e2f 100644 --- a/docs/superpowers/plans/2026-07-15-model-routing.md +++ b/docs/superpowers/plans/2026-07-15-model-routing.md @@ -1742,34 +1742,212 @@ NOTES : --- -# WAVE 4 — client-handover whole-writer dispatch (spec §5, user directive 2026-07-15) +# WAVE 4 — client-handover: dispatch the doc-generation to sonnet (redaction-only, spec §5, user directive 2026-07-16) -**Status: NOT YET SPEC'd — needs a dedicated design pass.** The user chose the -"dispatch the whole writer" variant of spec §5 (over the lighter redaction-only -split). This converts `agents/client-handover-writer.md` (1774 lines) from an -inline-loaded session-model agent into a dispatched sonnet subagent. It is the -single largest conversion in this effort and requires designing a resumable-gate -protocol before task decomposition. Key constraints already established: +**Shape DECIDED (user, 2026-07-16): redaction-only**, NOT whole-writer. Rationale +(from the full read of the 1774-line writer): the nested audit dispatches +(STEP 3/4/7 run `/seo`, `/harden`, `/web-validate`) must run on the BIG model +either way — those skills are gated themselves (wave 1), so a sonnet parent +would force-pin them anyway or trip their own gate. So the only work that truly +belongs on sonnet is the DOC GENERATION (writing the deliverable). Whole-writer +would add ~7 extra gate-yields + a resumable state machine on a client-facing +pipeline for ~zero extra sonnet work. Redaction-only gets the same sonnet +savings with the pipeline + all interactive gates staying NATIVE in the big +main loop. -- The writer has ~8–11 mid-pipeline `AskUserQuestion` gates (STEP 4 fix-loop - escalation, STEP 5 push + push-failed, STEP 6 deploy pause + deployed-URL, - STEP 11 Q1/Q2, STEP 13 NAP asks, …). A dispatched subagent cannot ask. - Convert each to a `GATE NEEDED: ` yield: the writer STOPs and - returns it; the dispatcher (`skills/client-handover/SKILL.md`, main loop) - runs the `AskUserQuestion`; then RESUMES the writer via SendMessage with the - answer. Remove `AskUserQuestion` from the writer's tools. -- **CORRECTNESS (spec §5 OPEN VERIFY POINT — resolved: force big):** the - writer's nested audit dispatches (STEP 3 baseline SEO/HARDEN/CSO, STEP 4 fix - loops, STEP 7 web-validate — all `general-purpose`) MUST carry an explicit - big-model `model` param so audits do NOT inherit the sonnet parent. Running - audits on sonnet would silently violate the "audits on the big model" rule. - The fix-application re-dispatches (execution) stay sonnet. -- Dispatcher collects params inline (URL, logo, options), then - `Agent(subagent_type="client-handover-writer")`; writer keeps `Agent` (nested - dispatches) + gains no `AskUserQuestion`. -- Add the MODEL GATE to `skills/client-handover/SKILL.md` (it orchestrates - audits = reflection) and add it to the census wired list. -- Census + README/CHANGELOG + BDR-066 wave-4 bullet + journal + TODO. +## Architecture -Tasks 19+ to be written after reading the writer's STEP 12–14 (doc synthesis + -render + remaining gates, lines 1123–1774) and mapping every gate to a yield id. +- **`agents/client-handover-writer.md`** stays INLINE-LOADED by the skill → + runs on the big session model (its `model: opus` frontmatter is inert under + inline-load; leave or drop — see Task 20). It becomes the **pipeline + + delegator**: STEP 1–8 unchanged (pre-flight, detect, baseline audits, fix + loops, commit/push, deploy pause, web-validate, gate eval) — all its + interactive gates (STEP 4 escalation, STEP 5 push/push-failed, STEP 6 deploy + pause + URL) work NATIVELY (main loop) and its nested audit dispatches inherit + the big session model with NO force-pinning. Then it does the INTERACTIVE + + detection parts of doc-gen — STEP 11 questions (Q1 deploy-chapter, Q2 + language), the STEP 12 §4 NAP-table build (incl. the business-name ask), + STEP 14.5 platform detection + the batch-unknowns `AskUserQuestion`, and + resolves the output path + overwrite decision (STEP 15 gate) + `CLIENT_NAME` + (STEP 16 gate). It assembles a PACKAGE and dispatches the doc-writer, then + reports the returned deliverable. Keeps `AskUserQuestion` + `Agent`. +- **`agents/handover-doc-writer.md`** (NEW, `model: sonnet`, tools + `Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch` — **NO + AskUserQuestion, NO Agent**): the pure writer. Reads material itself (STEP 9 + memory, STEP 10 git history) and, from the PACKAGE, does STEP 12 synthesis + + STEP 13 §7 checklist content + STEP 14 §8 (only if `INCLUDE_DEPLOY`) + + STEP 14.5 apply-the-given-precheck-set + STEP 15 write MD + the three gates + (word-count ≤300 on §3, skill-leak, anchor-resolution) + STEP 16 render + (HTML always, PDF when an engine is present). **Gate-free** — every + interactive decision was resolved by the parent and travels in the PACKAGE. + +## The PACKAGE (parent → doc-writer dispatch prompt) + +A single structured block the doc-writer treats as ground truth: +`LANG`; `PROJECT` (name, root, type, sub-type, is_local_business, deployed_url, +period first→last commit); `SCORES` (seo/geo/harden/validate or cso — before & +after, each with pass-status + any code-ceiling note); `AUDIT_REPORTS` (paths to +`.claude/audits/*.md` + HUMAN-ACTIONS/THRESHOLD-OVERRIDE if present, for §6 +sourcing); `INCLUDE_DEPLOY` (yes|no); `NAP` (the full resolved §4 table) + +`PRECHECK_DONE` (platforms already confirmed, for §5/§7 checkboxes); +`CLIENT_NAME` (string or `—`); `OUTPUT` (final md path + overwrite decision +`overwrite | versioned | skip-write`). + +## Global Constraints (wave 4) + +Branch `feature/client-handover-dispatch` (off develop, already checked out). +Same as prior waves: no merge, no attribution trailers, `make test` green per +commit, shellcheck clean, config-protection sentinel before each `lib/tests/*` +write (controller applies), YAML `safe_load`-parseable frontmatter. **Preserve +every deliverable invariant** (6-chapter structure, §2=scores, §4 NAP before §5, +§3 ≤300 words + zero jargon, skill-leak gate over chapters 1–5, clickable +anchors, ZenQuality render) — a dropped gate degrades a client deliverable. + +--- + +### Task 19: create `agents/handover-doc-writer.md` (sonnet, gate-free doc generator) + +**Files:** Create `agents/handover-doc-writer.md`. + +Extract the doc-generation half of `agents/client-handover-writer.md` (its +STEP 9, 10, 12, 13, 14, 14.5-apply, 15, 16 — lines 835–1774, MINUS the +interactive detection/questions that the parent now owns) into a new standalone +sonnet agent driven by the PACKAGE. + +- [ ] **Step 1:** Frontmatter: `name: handover-doc-writer`; + `description:` (one line — "Deliverable writer — dispatched by + client-handover with a resolved PACKAGE. Synthesizes the 6-chapter client doc, + writes the MD, renders branded HTML+PDF. No audits, no questions."); + `tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch`; + `model: sonnet`. NO `AskUserQuestion`, NO `Agent`. +- [ ] **Step 2:** Body. Open with an `## INPUT — the PACKAGE` section listing the + fields above and stating they are ground truth (never re-ask, never re-audit). + Then port, in order: + - STEP 9 LOAD MEMORY (verbatim — reads `.claude/memory/*`) and STEP 10 GIT + HISTORY (verbatim; keep the ≥200-commit clustering, but if it delegates to a + sub-agent, DROP that — a sonnet doc-writer has no `Agent`; do the clustering + inline). + - STEP 12 SYNTHESIZE — the full 6-chapter structure + ALL "Hard rules" + (clickable anchors, no skill names in ch.1–5, §3 ≤300 words, §2 score table + from `SCORES`, §4 NAP from `PACKAGE.NAP` before §5). Verbatim from source. + - STEP 13 §7 SEO/GEO checklist content + STEP 14 §8 deploy chapter (render + ONLY if `INCLUDE_DEPLOY=yes`). + - STEP 14.5 APPLY-ONLY: apply `PACKAGE.PRECHECK_DONE` to §5 `- [ ]`→`- [x]` + and §7 `- ☐`→`- ☑` + the cleanup pass. DROP the detection + the + batch-unknowns `AskUserQuestion` (the parent did both; the doc-writer only + applies the resolved set). + - STEP 15 WRITE — honor `PACKAGE.OUTPUT` (path + overwrite decision; NO + overwrite `AskUserQuestion` — obey the decision). Keep all three gates + verbatim: `wc -w` ≤300 on §3, the skill-leak grep over ch.1–5, the anchor + `comm -23` check. A gate failure → fix the MD and re-check (as today). + - STEP 16 RENDER — use `PACKAGE.CLIENT_NAME` (no `AskUserQuestion`); run + `scripts/handover-to-pdf.sh` with the env vars as today. + - FORBIDDEN block: `git commit`/branch ops/push, new deps, `Agent` dispatch, + `AskUserQuestion`, editing `.claude/**`, attribution trailers. + - End with a `HANDOVER-DOC REPORT` (STATUS DONE|BLOCKED; MD path; HTML path; + PDF path or "no engine"; the three gate results; NOTES). +- [ ] **Step 3:** YAML check + (`python3 -c "import yaml; yaml.safe_load(open('agents/handover-doc-writer.md').read().split('---')[1]); print('YAML OK')"`); + `grep -c 'AskUserQuestion\|subagent_type\|Agent(' agents/handover-doc-writer.md` → 0. + `make test` green (new agent isn't yet referenced — pure addition). + ```bash + git add agents/handover-doc-writer.md + git commit -m "feat(model-routing): handover-doc-writer — sonnet gate-free deliverable generator (wave 4)" + ``` + +--- + +### Task 20: trim `agents/client-handover-writer.md` to pipeline + delegator + +**Files:** Modify `agents/client-handover-writer.md`. + +- [ ] **Step 1:** Keep STEP 1–8 verbatim (pipeline; native gates; nested audit + dispatches unchanged — they inherit the big session model since this agent is + inline-loaded and runs big). +- [ ] **Step 2:** Replace STEP 9–16 with a **doc-gen orchestration** section that: + (a) runs STEP 11 questions inline (Q1 deploy-chapter → `INCLUDE_DEPLOY`, Q2 + language); (b) builds the §4 NAP table inline (incl. the business-name + `AskUserQuestion` at today's line ~1107); (c) runs STEP 14.5 platform + DETECTION + the batch-unknowns `AskUserQuestion` inline → `PRECHECK_DONE`; + (d) resolves the output path + overwrite (`test -f` then the STEP 15 question) + and `CLIENT_NAME` (detect or the STEP 16 question); (e) assembles the PACKAGE + and dispatches: + ``` + Agent(subagent_type="handover-doc-writer") + prompt: "PACKAGE:\n\nSynthesize + write + render the + deliverable per your steps. Report the HANDOVER-DOC REPORT." + ``` + then parses `HANDOVER-DOC REPORT` and reports the deliverable paths to the + user (surface BLOCKED verbatim). Keep `AskUserQuestion` + `Agent` in tools. +- [ ] **Step 3:** Frontmatter — drop the now-misleading `model: opus` line (this + agent inherits the session model like the other big-model reflection agents; + inline-load already made the pin inert). Update its `description` to say it + runs the ship pipeline then DELEGATES the deliverable writing to the sonnet + `handover-doc-writer`. +- [ ] **Step 4:** YAML check; `make test` green. + ```bash + git add agents/client-handover-writer.md + git commit -m "feat(model-routing): client-handover-writer trimmed to pipeline + delegates doc-gen to sonnet doc-writer" + ``` + +--- + +### Task 21: `skills/client-handover/SKILL.md` — MODEL GATE + updated overview + +**Files:** Modify `skills/client-handover/SKILL.md`. + +- [ ] **Step 1:** Add the orchestrator MODEL GATE block right under the H1 / + before the `Load and follow strictly:` line (client-handover orchestrates + audits = reflection → it MUST be gated): + ``` + MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE loading + the agent below. Verdict `small` → STOP — print the gate's remedy, end the + turn, do not load the agent. + ``` + Keep the inline-load of `client-handover-writer.md` (it runs the big-model + pipeline). Update the overview prose: the writer runs the audit/fix/gate + pipeline on the big model, then delegates the deliverable writing to the + sonnet `handover-doc-writer`. +- [ ] **Step 2:** `grep -c 'lib/model-gate.md' skills/client-handover/SKILL.md` → ≥1; + `make test` green. + ```bash + git add skills/client-handover/SKILL.md + git commit -m "feat(model-routing): client-handover MODEL GATE (pipeline orchestrates audits = reflection)" + ``` + +--- + +### Task 22: wave-4 census + docs + memory + +**Files:** `lib/tests/model-routing.test.sh` (guarded — CONTROLLER), `README.md`, +`CHANGELOG.md`, `.claude/memory/decisions.md`, `.claude/memory/journal.md`, +`.claude/tasks/TODO.md`. + +- [ ] **Step 1 (CONTROLLER — guarded):** sentinel, then add to + `lib/tests/model-routing.test.sh`: add `client-handover` to the wired-gate + loop (`# 1)`); a `# 9) wave-4` block — + `has skills/client-handover/SKILL.md 'lib/model-gate.md'` (redundant w/ loop — + keep in the loop), `has agents/handover-doc-writer.md 'model: sonnet'`, + `lacks agents/handover-doc-writer.md 'AskUserQuestion'`, + `has agents/client-handover-writer.md 'subagent_type="handover-doc-writer"'`. + Update the printed count; flip-test one new assertion. +- [ ] **Step 2:** README agent-model table — add `handover-doc-writer` (sonnet, + deliverable writer); move `client-handover-writer` from its old "opus (pinned, + inert)" row into the "inherit session" reflection row (it now runs the + big-model pipeline). CHANGELOG Unreleased `### Changed` — wave-4 bullet. +- [ ] **Step 3:** BDR-066 `**Wave 4**` bullet (redaction-only chosen over + whole-writer + why: audits big either way; doc-gen → sonnet doc-writer; + pipeline + all gates native on big; client-handover joins the gated group). + Journal line + TODO tick. + ```bash + git add lib/tests/model-routing.test.sh README.md CHANGELOG.md .claude/memory/decisions.md .claude/memory/journal.md .claude/tasks/TODO.md + git commit -m "chore(model-routing): wave-4 census + docs + BDR-066 (client-handover doc-gen → sonnet)" + ``` + +- [ ] **Step 4: Final wave-4 review** — dispatch a whole-branch reviewer (opus) + over the wave-4 range: verify the doc-writer preserves EVERY deliverable + invariant (6 chapters, §2 scores, §4-before-§5, §3 ≤300 words, skill-leak + gate, anchors, render), is gate-free (no AskUserQuestion/Agent), and that the + parent still owns all interaction + assembles a complete PACKAGE (no field the + doc-writer needs is missing). Report `git log --oneline develop..HEAD`. Do NOT + merge. diff --git a/lib/tests/model-routing.test.sh b/lib/tests/model-routing.test.sh index f270fb9..c72347b 100755 --- a/lib/tests/model-routing.test.sh +++ b/lib/tests/model-routing.test.sh @@ -9,8 +9,8 @@ has() { if grep -qF "$2" "$R/$1"; then ok; else ko "$1 missing: $2"; fi; } lacks() { if grep -qF "$2" "$R/$1"; then ko "$1 must NOT contain: $2"; else ok; fi; } fm_lacks() { if awk 'NR<=10' "$R/$1" | grep -qF "$2"; then ko "$1 frontmatter must NOT contain: $2"; else ok; fi; } -# 1) gate wired in the 13 reflection orchestrators -for s in ship-feature init-project feat bugfix onboard seo geo web-validate harden audit-delta tour code-clean hotfix; do +# 1) gate wired in the 14 reflection orchestrators +for s in ship-feature init-project feat bugfix onboard seo geo web-validate harden audit-delta tour code-clean hotfix client-handover; do has "skills/$s/SKILL.md" 'lib/model-gate.md' done # 2) gate NOT wired in the excluded skills (encodes the spec exclusion list) @@ -48,6 +48,11 @@ lacks "agents/bugfixer.md" 'AskUserQuestion' has "skills/code-clean/SKILL.md" 'subagent_type="code-cleaner"' has "agents/code-cleaner.md" 'model: sonnet' lacks "agents/code-cleaner.md" 'AskUserQuestion' +# 9) wave-4 — client-handover: pipeline (big) inline + gated, doc-gen dispatched to sonnet +has "agents/handover-doc-writer.md" 'model: sonnet' +lacks "agents/handover-doc-writer.md" 'AskUserQuestion' +lacks "agents/handover-doc-writer.md" 'Agent(' +has "agents/client-handover-writer.md" 'subagent_type="handover-doc-writer"' printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail" [ "$fail" -eq 0 ] diff --git a/skills/client-handover/SKILL.md b/skills/client-handover/SKILL.md index 8508ee9..2fb9a7a 100644 --- a/skills/client-handover/SKILL.md +++ b/skills/client-handover/SKILL.md @@ -21,10 +21,17 @@ allowed-tools: - Agent --- +MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE loading +the agent below. Verdict `small` → STOP — print the gate's remedy, end the +turn, do not load the agent. + Load and follow strictly: - $HOME/.claude/agents/client-handover-writer.md -Execute the CLIENT HANDOVER WRITER agent on this project. +Execute the CLIENT HANDOVER WRITER agent on this project. It runs the +audit/fix/gate pipeline INLINE on the big session model (gated above), then +delegates the client deliverable (Markdown + branded HTML + PDF) to the +sonnet-pinned `handover-doc-writer` subagent (BDR-066). The agent runs a **ship-and-handover pipeline** with explicit gates: