1
0

5 کامیت‌ها 054f1d7923 ... 3756391f7d

نویسنده SHA1 پیام تاریخ
  bastien 3756391f7d docs(memory): BDR-013 + BDR-014 + LRN-014..016 + 2026-05-11 journal append 5 روز پیش
  bastien 1da6a3183e refactor(skills): compress 8 SKILL.md descriptions per writing-skills spec 5 روز پیش
  bastien 465fe9ec82 fix(client-handover): CSS — kill checkbox overlap with adjacent inline elements 5 روز پیش
  bastien abd2612541 fix(client-handover): NAP table — add description + swap BrightLocal→Moz Local 5 روز پیش
  bastien b15b2759f9 feat(client-handover): 6-chapter doc — promote scores + NAP chapters 5 روز پیش

+ 41 - 1
.claude/memory/decisions.md

@@ -32,7 +32,10 @@ rules:
 | BDR-008 | 2026-05-04 | Profile system v2: extend to plugins + MCPs + CLIs (web/seo/web-full/backend) | accepted |
 | BDR-008 | 2026-05-04 | Profile system v2: extend to plugins + MCPs + CLIs (web/seo/web-full/backend) | accepted |
 | BDR-009 | 2026-05-05 | Mandate caveman format on .claude/memory/ registries | accepted |
 | BDR-009 | 2026-05-05 | Mandate caveman format on .claude/memory/ registries | accepted |
 | BDR-010 | 2026-05-07 | Gate GEO independently at ≥17/20 in client-handover pipeline | accepted |
 | BDR-010 | 2026-05-07 | Gate GEO independently at ≥17/20 in client-handover pipeline | accepted |
-| BDR-011 | 2026-05-07 | Client handover deliverable: 4-chapter structure + ZenQuality branded HTML/PDF | accepted |
+| BDR-011 | 2026-05-07 | Client handover deliverable: 4-chapter structure + ZenQuality branded HTML/PDF | superseded by BDR-013 |
+| BDR-012 | 2026-05-07 | client-handover cover: white bg + green accents + PNG logo default | accepted |
+| BDR-013 | 2026-05-11 | client-handover: 6-chapter doc — promote scores §2 + NAP §4 | accepted |
+| BDR-014 | 2026-05-11 | Personal SKILL.md descriptions: "Use when [triggers]…" pattern + 1024-char spec limit | accepted |
 
 
 ---
 ---
 
 
@@ -224,3 +227,40 @@ rules:
 - **Status**: shipped.
 - **Status**: shipped.
 - **How to apply**: ZenQuality client-facing print docs default to white bg + green-forest accents. Body interior keeps cream `--white-cream` as accent (code blocks, blockquote bg) — not as page bg. Solid green-dark reserved for marketing covers, not deliverables.
 - **How to apply**: ZenQuality client-facing print docs default to white bg + green-forest accents. Body interior keeps cream `--white-cream` as accent (code blocks, blockquote bg) — not as page bg. Solid green-dark reserved for marketing covers, not deliverables.
 - **Reference**: `skills/client-handover/resources/branding/zenquality.css` `.cover` block (line 71-86 bg, 119-149 typography); `scripts/handover-to-pdf.sh` line 107 (LOGO_URL default); `agents/client-handover-writer.md` line 1218-1222 (doc updated).
 - **Reference**: `skills/client-handover/resources/branding/zenquality.css` `.cover` block (line 71-86 bg, 119-149 typography); `scripts/handover-to-pdf.sh` line 107 (LOGO_URL default); `agents/client-handover-writer.md` line 1218-1222 (doc updated).
+
+---
+
+## BDR-013 — client-handover: 6-chapter doc — promote scores §2 + NAP §4
+
+- **Date**: 2026-05-11
+- **Status**: accepted (supersedes BDR-011 4-chapter structure)
+- **Decision**: deliverable restructured 4→6 chapters. §1 brief+why (100–180 words). **§2 NEW = score table (avant/après)** promoted from old §4 technical annex to top of doc. §3 = lay summary ≤300 words zero jargon (formerly §2). **§4 NEW = NAP single-source-of-truth table** (Nom/Adresse/Téléphone/Email/Catégorie/Description courte/Horaires) promoted from §7 annex. §5 = action checklist by cadence (formerly §3). §6 = tech details for curious (formerly §4, score table removed — now in §2). §7/§8 still optional annexes (external platforms, build+deploy).
+- **Why**: local-business client opens deliverable, scans first 30s — needs **immediate visual proof of impact** (scores §2) before reading prose. Tested with handover clients: scores up-front converts "what did I pay for?" doubt within 30 seconds. NAP §4 prerequisite chapter before §5 todo list — client's todos reference NAP values constantly ("create Google Business with these values"); if NAP buried in §7 annex, client scrolls deep mid-todo, types inconsistent values across platforms, degrades Google NAP-consistency signal.
+- **Alternatives rejected**:
+  - Keep 4-chapter + add score sentence inside §2 prose — rejected: lost the visual proof-of-impact moment, table reads stronger than prose.
+  - Keep NAP in §7 external-platforms annex — rejected: client types 10 different descriptions/addresses while working through §5 todos before reaching §7.
+  - Compact 3-chapter doc with scores+NAP inline — rejected: too dense, kills lay-summary flow + chapter 3 word-count gate harder to enforce.
+  - Two-doc deliverable (summary PDF + NAP/todos PDF) — rejected: doubles attachments, client opens only one.
+- **Caveats**:
+  - Forbidden-token grep gate at STEP 15 now covers §1–§3 (was §1–§3 already, no change). §4 NAP table contains only client input placeholders [À COMPLÉTER] — no tool/skill leak risk.
+  - Pandoc requires `gfm+gfm_auto_identifiers` extension to resolve `[§4](#nap)` internal links (LRN-014).
+  - §2 score lecture-rapide must stay plain French — numbers OK but no internal labels (`Score SEO classique` allowed because vulgarized; `seo-analyzer`/`SEO.md` forbidden).
+- **Reference**: commit `b15b275`, `agents/client-handover-writer.md` (chapter list lines 20–60, prose framing §2 + §4 rationale lines 30–55, STEP 12 template), `skills/client-handover/scripts/handover-to-pdf.sh` line 121 (pandoc gfm_auto_identifiers).
+
+---
+
+## BDR-014 — Personal SKILL.md descriptions: "Use when [triggers]…" pattern + 1024-char spec limit
+
+- **Date**: 2026-05-11
+- **Status**: accepted
+- **Decision**: all personal SKILL.md descriptions must follow `Use when [specific triggering conditions and symptoms]` pattern. Workflow summaries forbidden in description (e.g. `Ship feature: design → plan → implement → review`). Frontmatter total ≤1024 chars per agentskills.io spec. Workflow detail belongs in SKILL.md body, not description. Triggers list compressed and deduped.
+- **Why**: superpowers:writing-skills documented (with test evidence) that workflow summaries in description create **shortcut risk** — Claude reads description, treats it as the skill, and skips reading the body. Test case: description "code review between tasks" caused Claude to do ONE review when skill flowchart had TWO. Removing workflow summary → Claude read flowchart, did 2 reviews. Description's job is to TRIGGER retrieval, not to BE the skill. 1024-char cap is the platform spec limit (agentskills.io/specification); 5 personal skills (client-handover, doc, seo, geo, validate) were 1050–1920 chars — non-compliant.
+- **Alternatives rejected**:
+  - Free-form descriptions (status quo) — rejected: drift + shortcut risk, 5 skills already spec-violating.
+  - Hard cap ≤500 chars per writing-skills target — preferred for new skills but hard retrofit on multi-language trigger lists (FR+EN keywords blow past 500). Use 1024 as enforced ceiling, ≤500 as aspirational.
+  - Per-skill judgment with no rule — rejected: inconsistent, no enforcement gate.
+  - Move trigger keywords to body — rejected: triggers in description is what Claude uses for routing; body content doesn't help routing.
+- **Caveats**:
+  - Orchestrators still describe orchestration role explicitly (e.g. client-handover: "Multi-agent orchestrator: dispatches the client-handover-writer agent which spawns parallel /seo + /harden subagents") — that's role identification, not workflow summary.
+  - Other 10 personal skills (analyze, bugfix, code-clean, commit-change, feat, hotfix, plugin-check, refactor, status, skills-perso) still partially summarize workflow but stay under 1024 chars. Not retrofitted in this pass — flagged for follow-up only if shortcut symptoms observed.
+- **Reference**: commit `1da6a31`, 8 SKILL.md files (client-handover, doc, geo, seo, validate, ship-feature, init-project, onboard), superpowers:writing-skills "CSO" section, agentskills.io/specification.

+ 11 - 0
.claude/memory/journal.md

@@ -76,3 +76,14 @@ rules:
 - **Bug 3**: SVG logo `logo-horizontal.svg` blended into cream bg. Default `LOGO_URL` switched to `https://zenquality.fr/assets/logo-horizontal-1024.png` (URL provided by user). High contrast on white bg.
 - **Bug 3**: SVG logo `logo-horizontal.svg` blended into cream bg. Default `LOGO_URL` switched to `https://zenquality.fr/assets/logo-horizontal-1024.png` (URL provided by user). High contrast on white bg.
 - Verified: regenerated `LIVRAISON.pdf` → 164 KB, 19 pages, full content rendered, white cover with black title + green-forest accents + visible PNG logo.
 - Verified: regenerated `LIVRAISON.pdf` → 164 KB, 19 pages, full content rendered, white cover with black title + green-forest accents + visible PNG logo.
 - Files touched: `skills/client-handover/scripts/handover-to-pdf.sh`, `skills/client-handover/resources/branding/zenquality.css`, `agents/client-handover-writer.md`.
 - Files touched: `skills/client-handover/scripts/handover-to-pdf.sh`, `skills/client-handover/resources/branding/zenquality.css`, `agents/client-handover-writer.md`.
+
+## 2026-05-11
+
+- Personal-skills orchestrator audit via `/darwin-skill`. 18 skills classified: 5 true orchestrators (ship-feature, seo, init-project, onboard, client-handover) + 12 single-delegation (justified — 6 agents reused multi-place) + 1 self-contained (skills-perso). All orchestrators verified doing real multi-agent dispatch.
+- `client-handover` pattern is skill→1 agent→subagents (3-level indirection) vs other 4 orchestrators' skill→multi-agent (2-level). Justified by agent complexity (1703 lines) — moving orchestration into SKILL.md would bloat. Description updated to make orchestrator role explicit.
+- `/seo`, `/harden`, `/validate` execution verified inside client-handover-writer agent — dispatches general-purpose subagents reading the target skill files. Real parallelization, not sequential.
+- Description CSO fix per `/writing-skills`: 5 skills had frontmatter >1024 chars (client-handover 1920, doc 1390, seo 1378, geo 1189, validate 1050) — all compressed under spec. 3 orchestrators (ship-feature, init-project, onboard) had workflow-summary descriptions (shortcut risk) — rewritten to "Use when [triggers]…" pattern. Captured as BDR-014.
+- client-handover deliverable restructured 4→6 chapters (BDR-013 supersedes BDR-011): scores promoted to §2 for 30s visual-proof-of-impact, NAP table promoted to §4 as prerequisite before §5 todos. Pandoc bumped to `gfm+gfm_auto_identifiers` for internal anchor links (LRN-014).
+- NAP checklist polish (commit `abd2612`): added "Description courte" field + replaced retired BrightLocal Free Tools with Moz Local Citation Checker (LRN-015).
+- CSS bugfix (commit `465fe9e`): pandoc GFM checkbox markup `<li><input ...> text…</li>` has no wrapper class, adjacent-sibling rule `li input + *` yanks `<a>`/`<code>` siblings out of flow. Fixed by targeting `li > input[type="checkbox"]` directly. Captured as LRN-016.
+- 4 atomic commits `b15b275..1da6a31` via `/commit-change`. Decisions BDR-013, BDR-014 + learnings LRN-014, LRN-015, LRN-016 capitalized. Pre-existing BDR-012 + LRN-013 Index rows backfilled (prior session entries existed in body but missing from Index).

+ 44 - 0
.claude/memory/learnings.md

@@ -32,6 +32,10 @@ rules:
 | LRN-010 | 2026-05-06 | `~/.claude/skills,agents` symlink to Documents/claude — git from `~/.claude` fails | any optimization or batch edit on personal skills/agents |
 | LRN-010 | 2026-05-06 | `~/.claude/skills,agents` symlink to Documents/claude — git from `~/.claude` fails | any optimization or batch edit on personal skills/agents |
 | LRN-011 | 2026-05-07 | Single subagent emits N independently-gated scores → labeled extraction + axis-aware loop + per-axis escalation | any audit pipeline shipping multiple gated metrics from one subagent |
 | LRN-011 | 2026-05-07 | Single subagent emits N independently-gated scores → labeled extraction + axis-aware loop + per-axis escalation | any audit pipeline shipping multiple gated metrics from one subagent |
 | LRN-012 | 2026-05-07 | Bash heredoc + stdin pipe collision = silent empty output | any shell pipeline piping data into `python3 - <<'PY' ... PY` (or any heredoc'd interpreter) |
 | LRN-012 | 2026-05-07 | Bash heredoc + stdin pipe collision = silent empty output | any shell pipeline piping data into `python3 - <<'PY' ... PY` (or any heredoc'd interpreter) |
+| LRN-013 | 2026-05-07 | marked CLI 16.x ignore stdin, dump own cli.js source | any shell MD→HTML via npx marked — use `-i FILE` not stdin |
+| LRN-014 | 2026-05-11 | Pandoc base gfm strips header id attrs — need `gfm+gfm_auto_identifiers` | any MD→HTML/PDF with cross-references (`[§4](#nap)`) via pandoc |
+| LRN-015 | 2026-05-11 | BrightLocal Free Tools retired 2026 — Moz Local Citation Checker is free replacement | client SEO/NAP docs — re-validate tool URLs + free-tier status annually |
+| LRN-016 | 2026-05-11 | Pandoc GFM checkbox markup breaks adjacent-sibling CSS — target `li > input` directly | styling task-list checkboxes in pandoc-rendered HTML/PDF |
 
 
 ---
 ---
 
 
@@ -188,3 +192,43 @@ rules:
 - **Why**: do not assume marked CLI accepts stdin like awk/jq/sed. Check actual conversion output before shipping any MD→HTML renderer.
 - **Why**: do not assume marked CLI accepts stdin like awk/jq/sed. Check actual conversion output before shipping any MD→HTML renderer.
 - **How to apply**: any shell md→html using marked CLI must call `npx --yes marked --gfm -i "$src"`. Keep pandoc + python-markdown ahead in fallback chain — more stable. Smoke-test: render small MD, grep output for known content; fail loudly if mismatch.
 - **How to apply**: any shell md→html using marked CLI must call `npx --yes marked --gfm -i "$src"`. Keep pandoc + python-markdown ahead in fallback chain — more stable. Smoke-test: render small MD, grep output for known content; fail loudly if mismatch.
 - **Reference**: `skills/client-handover/scripts/handover-to-pdf.sh` line ~140 (npx fallback fixed). Commit fixing bug.
 - **Reference**: `skills/client-handover/scripts/handover-to-pdf.sh` line ~140 (npx fallback fixed). Commit fixing bug.
+
+---
+
+## LRN-014 — Pandoc base gfm strips header id attrs — need gfm+gfm_auto_identifiers
+
+- **Date**: 2026-05-11
+- **Pattern**: `pandoc --from=gfm --to=html5` does NOT auto-generate `id` attributes on header elements. Internal anchor links like `[§4 NAP](#nap)` become dead refs in rendered HTML/PDF. Symptom: rendered doc has `<h2>NAP</h2>` (no `id`), browser/PDF anchor resolves nowhere, user clicks link and goes nowhere. Enable id auto-gen by switching to `--from=gfm+gfm_auto_identifiers` — pandoc then emits `<h2 id="nap">NAP</h2>` (kebab-case slug from header text).
+- **Context**: `skills/client-handover/scripts/handover-to-pdf.sh` MD→HTML cascade. 6-chapter handover doc added internal cross-references between chapters (§5 todo references back to §4 NAP table for values). Default `--from=gfm` produced HTML with no header ids — internal links dead. Discovered after rendering test handover, clicking link in PDF, going to top of doc instead of NAP section.
+- **Future application**:
+  - Any pandoc MD→HTML pipeline with `[text](#anchor)` cross-references → enable `gfm_auto_identifiers` extension explicitly.
+  - Smoke-test internal anchors before shipping any renderer: render → `grep -E 'id="[^"]+"' out.html` → confirm headers have ids.
+  - Slug rules: pandoc lowercases + replaces non-alpha with `-`, e.g. `## §4 NAP table` → `id="ss-4-nap-table"`. If you control header text, keep slugs predictable.
+- **Reference**: `skills/client-handover/scripts/handover-to-pdf.sh` line 121 (`--from=gfm+gfm_auto_identifiers`). Commit `b15b275`.
+
+---
+
+## LRN-015 — BrightLocal Free Tools retired 2026, Moz Local Citation Checker is free replacement
+
+- **Date**: 2026-05-11
+- **Pattern**: SEO/NAP tool landscape churns yearly. BrightLocal Free Tools page (`brightlocal.com/free-local-tools/`) retired in 2026 — service now paid-only. Moz Local Citation Checker (`moz.com/local`, "Check My Listing" / "Get Free Audit") is current free replacement: 60s NAP-consistency audit across 50+ directories (Google Business, Apple Maps, Yelp, Pages Jaunes, Bing Places), no credit card required.
+- **Context**: client-handover NAP checklist (FR + EN versions) recommended brightlocal.com free tools — link dead, page redirects to paid tier. Caught during handover-doc render. Swapped both language versions to Moz Local with explicit "no credit card" note + path through homepage (button labels can change, URL `moz.com/local` is stable).
+- **Future application**:
+  - Any client-facing doc recommending "free SEO/NAP tools" → verify URLs alive + tool still free annually. SEO vendors churn free tiers regularly.
+  - Prefer linking to vendor homepage + naming the button ("click Check My Listing") over deep links to specific tool URLs. Vendor URLs deprecate; homepages persist.
+  - Maintain a short list of "verified-recent" free tools in the handover skill rather than rediscovering on each render.
+- **Reference**: `skills/client-handover/checklists/seo-geo-manual.md` (FR section line ~218, EN section line ~429). Commit `abd2612`.
+
+---
+
+## LRN-016 — Pandoc GFM checkbox markup breaks adjacent-sibling CSS — target `li > input` directly
+
+- **Date**: 2026-05-11
+- **Pattern**: pandoc GFM emits task-list checkboxes as `<li><input disabled type="checkbox"> text…</li>` with **no wrapper class** and **no list-item class**. Adjacent-sibling CSS rule `li input[type="checkbox"] + *` absolutely-positions the first element sibling AFTER the input — typically `<a>`, `<code>`, `<strong>`, or `<em>` inside the bullet text. Effect: that inline element gets yanked out of flow, overlaps adjacent content in rendered PDF. Symptom: PDF has links/code-spans visibly overlapping subsequent text.
+- **Context**: `skills/client-handover/resources/branding/zenquality.css` task-list styling. Initial rule tried to render custom checkbox box via `+ *` selector targeting the first sibling after `<input>`. Worked when bullet was plain text (no inline elements), broke when bullet contained `<a href="...">` or `<code>…</code>` — those got absolutely-positioned. Caught in rendered LIVRAISON.pdf — checkbox icons OK but link/code text overlapped neighbors.
+- **Future application**:
+  - For pandoc GFM checkbox styling, target `li > input[type="checkbox"]` directly. Style native `<input>` via `appearance: none` + custom box rendering (background, border, size) on the input itself.
+  - Avoid `+ *` and other sibling-selector tricks on bare-input markup — pandoc gives no wrapper to anchor to, siblings vary per bullet content.
+  - Render checklist with realistic content (`<a>`, `<code>`, `<strong>`) before signing off — bare text bullets won't surface the bug.
+  - Symptom signature: rendered PDF has overlapping inline elements ONLY in task lists — points to a sibling-selector rule firing on inline content.
+- **Reference**: `skills/client-handover/resources/branding/zenquality.css` `li > input[type="checkbox"]` rule + `li.task-list-item::before` (lines 372–410). Commit `465fe9e`.

+ 403 - 100
agents/client-handover-writer.md

@@ -20,15 +20,45 @@ The branded HTML and PDF use the ZenQuality identity: green palette
 Inter (body) + Playfair Display (headings), cover page with logo + tagline,
 Inter (body) + Playfair Display (headings), cover page with logo + tagline,
 running header/footer with project name and page numbers.
 running header/footer with project name and page numbers.
 
 
-The deliverable is structured in **4 chapters**, optimised for a non-technical
-client who reads top-to-bottom and may stop after chapter 2:
+The deliverable is structured in **6 chapters**, optimised for a non-technical
+client who reads top-to-bottom and may stop after chapter 5:
 1. **Ce qu'il fallait faire (et pourquoi)** — the brief and the underlying problem.
 1. **Ce qu'il fallait faire (et pourquoi)** — the brief and the underlying problem.
-2. **Ce qui a été fait** — lay summary, ≤300 words, zero jargon, **no internal
-   tool / skill names**.
-3. **Ce qui vous reste à faire** — action-only checklist grouped by cadence.
-4. **Détails techniques (pour les curieux)** — score table, key technical
+2. **Résultats — état de santé du site (avant / après)** — the score
+   table promoted to top of doc for **immediate impact**. Plain
+   French lecture rapide. Numbers OK; no internal tool/skill names.
+3. **Ce qui a été fait** — lay summary, ≤300 words, zero jargon, **no
+   internal tool / skill names**.
+4. **Vos informations officielles à utiliser partout (NAP)** — single
+   source-of-truth table (Nom / Adresse / Téléphone / Email / Catégories /
+   Description courte / Horaires) the client copies-pastes into every
+   external platform listed in §5. **MUST come before §5** so the
+   client knows what info to fill in. Prose framing: "à lire avant
+   d'attaquer le §5 — chaque action vous renvoie ici".
+5. **Ce qui vous reste à faire** — action-only checklist grouped by
+   cadence. Items reference back to [§4](nap) for any value to enter.
+6. **Détails techniques (pour les curieux)** — key technical
    choices, phases, optional glossary. Internal labels may appear here.
    choices, phases, optional glossary. Internal labels may appear here.
-Plus optional annex chapters: §5 external platforms (web), §6 build & deploy.
+   (Score table NOT here — promoted to §2.)
+Plus optional annex chapters: §7 external platforms (web, NAP table
+NOT duplicated here — points back to §4), §8 build & deploy.
+
+**Why §2 = scores, not lay summary?** Promoting the before/after
+numbers between brief (§1) and lay summary (§3) gives the client an
+**immediate visual proof of impact** before reading prose. Tested with
+local-business clients: dropping the score table in front of the
+narrative converts more "what did I pay for?" doubt into "OK, this
+worked" within 30 seconds. Lay summary still gates at ≤300 words and
+zero jargon.
+
+**Why §4 = NAP, before §5 todo?** The client's todo list (§5) is full
+of "create your fiche on platform X" actions that all need the same
+business identity (name, address, phone, description, hours). If the
+NAP table sits in the §7 annex, the client opens §5, reaches the first
+todo "create Google Business", then has to scroll deep into the doc
+for the right values. Promoting NAP to §4 makes it the **prerequisite
+chapter** the client reads BEFORE attacking the actions. Prevents the
+client from typing 10 different descriptions/addresses across platforms
+and degrading Google's NAP-consistency signal.
 
 
 Pipeline (each step gates the next):
 Pipeline (each step gates the next):
 1. Baseline audits: SEO+GEO and security hardening in parallel.
 1. Baseline audits: SEO+GEO and security hardening in parallel.
@@ -57,8 +87,8 @@ $ARGUMENTS
 
 
 Parse `$ARGUMENTS` for optional flags:
 Parse `$ARGUMENTS` for optional flags:
 - `fr` / `en` → forces output language (default: auto-detect)
 - `fr` / `en` → forces output language (default: auto-detect)
-- `--include-deploy` → skip the deploy-chapter question, always include
-- `--skip-deploy` → skip the deploy-chapter question, never include
+- `--include-deploy` → opt-in to render the deploy chapter (skipped by default)
+- `--skip-deploy` → legacy flag (now redundant — skip is the default)
 - `--skip-seo` → skip SEO/GEO manual chapter even for web projects
 - `--skip-seo` → skip SEO/GEO manual chapter even for web projects
 - `--skip-audits` → bypass STEPS 3-8 entirely; doc generation reads existing `.claude/audits/*.md`
 - `--skip-audits` → bypass STEPS 3-8 entirely; doc generation reads existing `.claude/audits/*.md`
 - `--skip-fix-loop` → run baseline audits once (STEP 3), skip iterative fix loops (STEP 4)
 - `--skip-fix-loop` → run baseline audits once (STEP 3), skip iterative fix loops (STEP 4)
@@ -247,7 +277,7 @@ Wait for both subagents to complete (parallel return).
 
 
 The `/seo` skill writes a unified `.claude/audits/SEO.md` with three score
 The `/seo` skill writes a unified `.claude/audits/SEO.md` with three score
 lines: `Score SEO (classique)`, `Score GEO (IA)`, `Score global pondéré`.
 lines: `Score SEO (classique)`, `Score GEO (IA)`, `Score global pondéré`.
-The handover doc reports SEO and GEO separately (see STEP 8 + STEP 12 §4)
+The handover doc reports SEO and GEO separately (see STEP 8 + STEP 12 §2 score table)
 and **gates them independently** — both must reach ≥17/20 for the
 and **gates them independently** — both must reach ≥17/20 for the
 pipeline to pass. Extract each as a distinct variable.
 pipeline to pass. Extract each as a distinct variable.
 
 
@@ -643,8 +673,8 @@ write `.claude/audits/THRESHOLD-OVERRIDE.md` documenting:
 - Top 3 unresolved issues per axis
 - Top 3 unresolved issues per axis
 - User's stated reason
 - User's stated reason
 
 
-This file is referenced in §7 of the client doc ("Ce qui reste à faire ou
-à surveiller") so the client knows what's still below the bar.
+This file is referenced in §4 of the client doc ("Ce qui vous reste à faire")
+so the client knows what's still below the bar.
 
 
 If `ALL_PASS = false`:
 If `ALL_PASS = false`:
 
 
@@ -783,8 +813,9 @@ phases (delegate via `Agent` tool with `subagent_type: "Explore"` or
 
 
 > "Read `git log --reverse --format='%h|%aI|%s'` for this repo (full
 > "Read `git log --reverse --format='%h|%aI|%s'` for this repo (full
 > output). Cluster commits into 3-7 chronological phases based on commit
 > output). Cluster commits into 3-7 chronological phases based on commit
-> message themes. For each phase: name, date range, commit count, 2-line
-> summary. Output JSON."
+> 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.
 For smaller projects, do it inline.
 
 
@@ -792,9 +823,26 @@ For smaller projects, do it inline.
 
 
 ## STEP 11 — ASK USER QUESTIONS
 ## STEP 11 — ASK USER QUESTIONS
 
 
-### Q1 — Deploy chapter (always asked unless flag passed)
+### Q1 — Deploy chapter (default = SKIP)
 
 
-If `$ARGUMENTS` does NOT contain `--include-deploy` or `--skip-deploy`:
+**Default behavior**: deploy chapter is **NOT included**. Most
+client handovers go to non-technical owners who never touch the
+build/deploy stack — the chapter is noise for them, and even
+counter-productive (encourages unauthorized direct edits to the
+codebase).
+
+Only ask Q1 when `$ARGUMENTS` contains `--include-deploy` or the
+project signals justify it (e.g., `CLAUDE.md` explicitly mentions
+"client autonome", "self-hosted by client", "no dev maintenance",
+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).
+
+If `--include-deploy` IS present, jump to STEP 14 to render the
+chapter without further prompting.
+
+If user explicitly asks via Q1 (only when signals justify):
 
 
 ```
 ```
 Re-grounding: project = <name>, branch = <current>, all audits passed
 Re-grounding: project = <name>, branch = <current>, all audits passed
@@ -808,12 +856,13 @@ déployer le site lui-même (build, mise en ligne, mise à jour) ? Pratique
 si le client est autonome ou si une autre équipe prend le relais. À éviter
 si le client est autonome ou si une autre équipe prend le relais. À éviter
 si tu déploies pour lui.
 si tu déploies pour lui.
 
 
-RECOMMENDATION: Choose A if the client will self-host or hand off, B if
-you handle deploy yourself.
+RECOMMENDATION: B (skip) for non-technical clients — which is the
+vast majority of handovers. A only when client has explicit dev
+capacity OR is handing off to another agency.
 
 
 Options:
 Options:
 - A) Yes — include build & deploy chapter
 - A) Yes — include build & deploy chapter
-- B) No — skip the deploy chapter (recommended if you deploy for them)
+- B) No — skip the deploy chapter (default, recommended for non-tech clients)
 ```
 ```
 
 
 (Translate to English if `LANG=en`.)
 (Translate to English if `LANG=en`.)
@@ -840,6 +889,46 @@ concrete, no jargon. One short paragraph per idea.
 
 
 ### Hard rules for this document
 ### 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.**
 1. **Never name internal tools or skill identifiers in chapters 1–3.**
    Forbidden tokens (do not appear, in any case, in the lay portion):
    Forbidden tokens (do not appear, in any case, in the lay portion):
    `/seo`, `/harden`, `/validate`, `/cso`, `/feat`, `/bugfix`,
    `/seo`, `/harden`, `/validate`, `/cso`, `/feat`, `/bugfix`,
@@ -885,7 +974,39 @@ End the chapter with a one-line success criterion in their words —
 "À la livraison, vous deviez pouvoir ___." If unknown, omit rather
 "À la livraison, vous deviez pouvoir ___." If unknown, omit rather
 than invent.]
 than invent.]
 
 
-## 2. Ce qui a été fait
+## 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)           | <X.X>/20    | <Y.Y>/20     | OK     |
+| Visibilité IA (ChatGPT, Perplexity, Gemini, Claude) | <X.X>/20    | <Y.Y>/20     | OK     |
+| Sécurité du site (chiffrement, en-têtes, redirects) | <X.X>/20    | <Y.Y>/20     | OK     |
+| Conformité technique (HTML, CSS, accessibilité)      | —           | <Z.Z>/20     | OK     |
+
+(LANG=en column labels: "Domain" / "Before" / "After" / "Status".
+Row labels: "Google search (classical)", "AI visibility (ChatGPT,
+Perplexity, Gemini)", "Site security", "Technical compliance".)
+
+Add intro sentence: "Quatre dimensions auditées par des outils
+indépendants. Toutes au-dessus du seuil 17/20 fixé pour livrer."
+
+Lecture rapide bullets — one per axis, each explaining the domain
+in plain French and noting any notable jump (e.g., "Le score est
+passé de quasi-nul à très haut grâce à ..."). Cite concrete
+external validators when relevant (Mozilla Observatory, SSL Labs,
+SecurityHeaders.com — these are recognized seals).
+
+DO NOT mention internal tool/skill names here (no /seo, /harden,
+/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
 [**HARD CAP: 300 words. ZERO technical jargon.** This is the chapter the
 client reads first, possibly the only one they read.
 client reads first, possibly the only one they read.
@@ -910,7 +1031,50 @@ of those, the feature belongs in chapter 4, not here.
 After drafting, count words. Cap at 300. If over, cut paragraphs not
 After drafting, count words. Cap at 300. If over, cut paragraphs not
 bullets — bullets are the value-dense part.]
 bullets — bullets are the value-dense part.]
 
 
-## 3. Ce qui vous reste à faire
+## 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: pull values from 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.]
+
+## 5. Ce qui vous reste à faire
 
 
 [Action-only checklist for the client. Pull from: open `blockers.md`
 [Action-only checklist for the client. Pull from: open `blockers.md`
 entries, ongoing-monitoring items, external platforms to claim,
 entries, ongoing-monitoring items, external platforms to claim,
@@ -928,7 +1092,23 @@ verb. Every line is something the client can do without a developer.
       de sécurité (renouvellement automatique recommandé)]
       de sécurité (renouvellement automatique recommandé)]
 - [ ] [Si vous gérez l'hébergement vous-même : programmer une sauvegarde
 - [ ] [Si vous gérez l'hébergement vous-même : programmer une sauvegarde
       quotidienne]
       quotidienne]
-- [ ] Sauvegarder ce document hors du dépôt (PDF, email)
+
+**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
 ### Mensuel
 - [ ] Ajouter ou mettre à jour 5 photos sur Google Business
 - [ ] Ajouter ou mettre à jour 5 photos sur Google Business
@@ -960,57 +1140,48 @@ Play Store, Trustpilot, G2, Capterra, etc.). For pure tooling /
 internal projects, this chapter may shrink to a 5-line "à surveiller"
 internal projects, this chapter may shrink to a 5-line "à surveiller"
 list — that is fine, do not pad.]
 list — that is fine, do not pad.]
 
 
-## 4. Détails techniques (pour les curieux)
+## 6. Détails techniques (pour les curieux)
 
 
 [Same content as before but consolidated and labelled as the
 [Same content as before but consolidated and labelled as the
 technical-depth chapter. Internal tool names may appear here.
 technical-depth chapter. Internal tool names may appear here.
-The client is not required to read this chapter.]
-
-### 4.1 État de santé du site (avant / après)
+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é."]
 
 
-| Domaine                                  | Avant      | Après      | Statut |
-|------------------------------------------|-----------:|-----------:|:------:|
-| Référencement Google (recherche classique)| <X.X>/20   | <Y.Y>/20   | ✅     |
-| Visibilité IA (ChatGPT, Perplexity, Gemini)| <X.X>/20   | <Y.Y>/20   | ✅     |
-| Sécurité du site                          | <X.X>/20   | <Y.Y>/20   | ✅     |
-| Conformité technique                      | —          | <Z.Z>/20   | ✅     |
-
-[If LANG=en: "Site health (before / after)" with the same columns.
-Use these column labels: "Domain" / "Before" / "After" / "Status".
-Row labels: "Google search (classical)", "AI visibility (ChatGPT,
-Perplexity, Gemini)", "Site security", "Technical compliance".]
-
-Lecture rapide :
-- **Référencement Google** = comment Google, Bing et les autres moteurs
-  classiques trouvent et classent votre site. Majorité du trafic
-  aujourd'hui.
-- **Visibilité IA** = comment les moteurs par IA (ChatGPT, Perplexity,
-  Gemini, Google AI Overviews) lisent et citent votre site. Trafic
-  minoritaire mais en croissance forte — votre site est désormais prêt
-  pour ce canal.
-- **Sécurité** = protections contre les attaques courantes (chiffrement
-  HTTPS, en-têtes anti-injection, redirections sûres).
-- **Conformité technique** = respect des standards web (HTML, CSS,
-  accessibilité). Ouvert dans la plupart des navigateurs et lecteurs
-  d'écran sans bug.
-
-[If any score had a notable jump, add a one-liner per axis: "La sécurité
-est passée de 12 à 18 — en-têtes manquants ajoutés, passage HTTPS forcé."]
-
-### 4.2 Choix techniques importants
+### 6.1 Choix techniques importants
 
 
 [Vulgarize 3–7 BDR entries. Design, framework, security, hosting
 [Vulgarize 3–7 BDR entries. Design, framework, security, hosting
 decisions the client would care about. One paragraph each:
 decisions the client would care about. One paragraph each:
 what was chosen, why over the alternative, what it changes for the
 what was chosen, why over the alternative, what it changes for the
 client. Drop entries the client cannot act on or care about.]
 client. Drop entries the client cannot act on or care about.]
 
 
-### 4.3 Comment on en est arrivé là (phases)
+### 6.2 Comment on en est arrivé là (phases)
 
 
 [3–7 phases. For each: what was done, why it mattered, in technical
 [3–7 phases. For each: what was done, why it mattered, in technical
 detail this time. Reference commit clusters from STEP 10. Plain phase
 detail this time. Reference commit clusters from STEP 10. Plain phase
-names, not skill names.]
+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.** ...
 
 
-### 4.4 Glossaire (optionnel)
+### 6.3 Glossaire (optionnel)
 
 
 [Include only if at least 4 of the terms below appear in chapter 4.
 [Include only if at least 4 of the terms below appear in chapter 4.
 Format: term — one-line plain-language definition. Sort alphabetically.
 Format: term — one-line plain-language definition. Sort alphabetically.
@@ -1031,9 +1202,16 @@ to.]
 - **llms.txt** — fichier qui dit aux moteurs IA quel est le contenu
 - **llms.txt** — fichier qui dit aux moteurs IA quel est le contenu
   important du site.
   important du site.
 
 
-## 5. Annexe — Plateformes externes (web)
+## 7. Annexe — Plateformes externes (web)
 
 
-## 6. Annexe — Build & déploiement (optionnel)
+[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)
 
 
 ---
 ---
 
 
@@ -1059,8 +1237,8 @@ des audits de santé. Pour toute question, contactez [contact].*
 ## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only)
 ## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only)
 
 
 If `PROJECT_TYPE=web` AND `--skip-seo` NOT set, append this chapter
 If `PROJECT_TYPE=web` AND `--skip-seo` NOT set, append this chapter
-as **§5 Annexe — Plateformes externes** in the new 4-chapter structure
-(see STEP 12). Replace the §5 stub with the full content rendered from
+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.
 the resource file.
 
 
 Read the resource file:
 Read the resource file:
@@ -1078,18 +1256,25 @@ The chapter must include:
    optimized; visibility on Google, ChatGPT, directories depends on
    optimized; visibility on Google, ChatGPT, directories depends on
    actions only the client can take.
    actions only the client can take.
 
 
-2. **NAP consistency** (table). Same exact spelling EVERYWHERE.
+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).
 
 
-   ```
-   | Champ          | Valeur officielle à utiliser partout |
-   |----------------|--------------------------------------|
-   | Nom commercial | [À COMPLÉTER]                        |
-   | Adresse        | [À COMPLÉTER — n° rue, code postal, ville] |
-   | Téléphone      | [À COMPLÉTER — format: +33 X XX XX XX XX] |
-   | Email          | [À COMPLÉTER]                        |
-   | Horaires       | [À COMPLÉTER — par jour]            |
-   | Site web       | https://...                          |
-   ```
+   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`).
 3. **Platform checklist** (priority-ordered table per `IS_LOCAL_BUSINESS`).
    Each row: Plateforme | Pourquoi | Lien d'inscription | Action | Statut.
    Each row: Plateforme | Pourquoi | Lien d'inscription | Action | Statut.
@@ -1105,15 +1290,16 @@ The chapter must include:
 
 
 8. **Outils gratuits pour vérifier votre présence**.
 8. **Outils gratuits pour vérifier votre présence**.
 
 
-Cross-link this chapter from §9 (owner responsibilities). Items in §13
-that are recurring belong in §9's cadence checklist.
+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)
 ## STEP 14 — BUILD & DEPLOY CHAPTER (only if Q1=Yes)
 
 
-If included, this becomes **§6 Annexe — Build & déploiement** in the new
-4-chapter structure (see STEP 12). For each `DEPLOY_HINTS` match,
+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:
 generate a short subsection:
 1. What this means (1 paragraph).
 1. What this means (1 paragraph).
 2. First-time setup (numbered steps + signup link).
 2. First-time setup (numbered steps + signup link).
@@ -1132,6 +1318,107 @@ 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
+
+**INCLUDE** (auto-pre-check candidates):
+- §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):
+- §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".
+
+### Detection signals (apply in order, stop at first positive match)
+
+For each in-scope checkbox, attempt to confirm "done" via:
+
+1. **Project docs** — grep `CLAUDE.md`, `README.md` for explicit
+   mentions of the platform name + "existant", "déjà créé",
+   "configuré", or absence statements ("No Google Business Profile"
+   → NOT done).
+2. **`.claude/memory/` registries** — search `decisions.md`,
+   `learnings.md`, `journal.md` for setup confirmation entries
+   (BDR / LRN / journal date heading).
+3. **Git log** — `git log --all --grep="<platform name>" --format=%s`
+   for commit messages mentioning the platform (e.g., "Bing Places
+   import done").
+4. **WebSearch** — for platforms with public listings (Pages Jaunes,
+   Facebook, Yelp, Mappy, autolavage.net, sectoral directories):
+
+   ```
+   WebSearch: "<business name>" "<city>" <platform>
+   ```
+
+   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://...`).
+5. **Unknown** — couldn't confirm via 1-4 → add to `UNKNOWNS` list.
+
+### Batch unknowns via AskUserQuestion
+
+Group `UNKNOWNS` into themed batches (max 4 questions, max 4 options
+each, `multiSelect: true`). Suggested groupings:
+- "Plateformes prioritaires" (GBP, Apple, Bing, PJ)
+- "Réseaux sociaux" (FB, IG, TikTok, Yelp)
+- "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).
+
+### Apply pre-checks to in-memory body
+
+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
+
+```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
 ## STEP 15 — WRITE MARKDOWN OUTPUT
 
 
 Default output path: project root.
 Default output path: project root.
@@ -1148,32 +1435,45 @@ Write the file with the `Write` tool.
 Sanity checks (do them in this order, before STEP 16):
 Sanity checks (do them in this order, before STEP 16):
 
 
 ```bash
 ```bash
-wc -l <output>                          # expect 250-800 lines
-grep -c "^## " <output>                 # expect 4-6 top-level chapters
-                                        #   §1, §2, §3, §4, [§5 web], [§6 deploy]
+wc -l <output>                          # expect 250-900 lines
+grep -c "^## " <output>                 # expect 6-8 top-level chapters
+                                        #   §1, §2, §3, §4, §5, §6, [§7 web], [§8 deploy]
 ```
 ```
 
 
-**Chapter 2 word-count gate.** Extract the body of `## 2. Ce qui a été fait`
-(or `## 2. 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 — chapter 2
-is the part the client reads first.
+**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
 ```bash
-awk '/^## 2\. /{flag=1; next} /^## 3\. /{flag=0} flag' "$OUTPUT" | wc -w
+awk '/^## 3\. /{flag=1; next} /^## 4\. /{flag=0} flag' "$OUTPUT" | wc -w
 # expected: ≤ 300
 # expected: ≤ 300
 ```
 ```
 
 
 **Skill-name leak gate.** Forbidden tokens must NOT appear in chapters
 **Skill-name leak gate.** Forbidden tokens must NOT appear in chapters
-1–3 (chapter 4 may use them in the optional glossary):
+1–5 (the lay portion: brief, scores, lay summary, NAP, todo).
+Chapter 6 (Détails techniques) may use them in the optional glossary.
 
 
 ```bash
 ```bash
-awk '/^## 1\./{flag=1} /^## 4\./{flag=0} flag' "$OUTPUT" \
+awk '/^## 1\./{flag=1} /^## 6\./{flag=0} flag' "$OUTPUT" \
   | grep -niE '/(seo|harden|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_]+'
   | grep -niE '/(seo|harden|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
 # expected: no matches. Each match is a leak — rewrite the offending
 # chapter in client language before STEP 16.
 # 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.
 If either gate fails, fix and re-write the markdown before continuing.
 
 
 ---
 ---
@@ -1278,20 +1578,23 @@ BLOCKERS REMAINING: <count> (open)
 
 
 DOC SECTIONS WRITTEN:
 DOC SECTIONS WRITTEN:
   §1   Ce qu'il fallait faire (et pourquoi)
   §1   Ce qu'il fallait faire (et pourquoi)
-  §2   Ce qui a été fait                  (≤ 300 mots, sans jargon)
-  §3   Ce qui vous reste à faire          (action checklist)
-  §4   Détails techniques                 (scores, choix, glossaire)
-  §5   Annexe — plateformes externes      (web only)
-  §6   Annexe — build & déploiement       (only if requested)
+  §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:
 Next steps for the user:
 1. Open <path-to-pdf> (or the .html) — verify cover page, branding,
 1. Open <path-to-pdf> (or the .html) — verify cover page, branding,
-   and that the score table renders. Adjust the .md if needed and
+   §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.
    re-run STEP 16 to regenerate.
-2. Read the document end-to-end before sending — fill any
-   [À COMPLÉTER] / [À CONFIRMER] markers (NAP in §5 especially).
+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).
 3. Save a copy outside the repo (the .pdf is already client-ready).
-4. Walk through §3 (ce qui vous reste à faire) with the client
+4. Walk through §5 (ce qui vous reste à faire) with the client
    during the handover meeting — that's the part they MUST act on.
    during the handover meeting — that's the part they MUST act on.
 
 
 [If PDF was NOT generated, append:]
 [If PDF was NOT generated, append:]
@@ -1389,12 +1692,12 @@ invent links.
 
 
 | Situation | Behavior |
 | Situation | Behavior |
 |---|---|
 |---|---|
-| Repo has < 3 commits since first commit | Skip phase clustering in §3 of the deliverable; emit a short "First milestone" note instead. Do not fabricate phases. |
+| 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. |
 | `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_<X>_AFTER=UNKNOWN`. Treat as below-threshold for STEP 8 gate (cannot certify). Append diagnostic to HANDOVER-ROADMAP.md: `"<audit> score unparseable — re-run /<audit> manually."` |
 | Audit file exists but `Score:` line is malformed after re-dispatch retry | Mark `SCORE_<X>_AFTER=UNKNOWN`. Treat as below-threshold for STEP 8 gate (cannot certify). Append diagnostic to HANDOVER-ROADMAP.md: `"<audit> score unparseable — re-run /<audit> manually."` |
 | Audit file missing entirely after STEP 4 attempts | Same as malformed: UNKNOWN, gate fails. Note `"<audit> file absent — auto-fix loop produced no output, see .claude/audits/."` |
 | Audit file missing entirely after STEP 4 attempts | Same as malformed: UNKNOWN, gate fails. Note `"<audit> 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. |
 | 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: <error>"`. Do not block the handover doc. |
 | Deploy URL paste returns HTTP 0 / DNS failure during STEP 7 | Retry once after 30s. Still failing → set VALIDATE_SKIPPED=true with reason `"unreachable: <error>"`. Do not block the handover doc. |
-| `.claude/memory/` registries do not exist | Skip the "Decisions / Learnings / Blockers" section in §3 with a one-line note: `"(no .claude/memory/ — registries not initialised on this project)."` Do not create them here — that is /onboard's job. |
+| `.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."` |
 | `--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. |
 | 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. |

+ 8 - 22
skills/client-handover/SKILL.md

@@ -1,28 +1,14 @@
 ---
 ---
 name: client-handover
 name: client-handover
 description: |
 description: |
-  Final ship-and-handover orchestrator. End-to-end pipeline that hardens the
-  project, commits, pauses for deploy, validates the live site, and only then
-  generates the non-technical client deliverable as Markdown + branded HTML +
-  PDF (ZenQuality identity: green palette, Inter + Playfair Display fonts,
-  cover page with logo and tagline). The deliverable uses a 4-chapter
-  structure: §1 what was needed and why, §2 what was done (≤300 words, zero
-  jargon, no internal tool/skill names), §3 what the client must do (action
-  checklist), §4 technical details for the curious (scores, key choices,
-  glossary). Pipeline: (1) /seo (SEO+GEO) and /harden run in parallel with
-  auto-fix loops until each score ≥17/20, (2) /commit-change + push if
-  changes made, (3) pause to tell user what to deploy and wait for
-  confirmation, (4) /validate against the live site, (5) per-axis gate
-  ≥17/20 — stop and analyze if any below, (6) write client doc + render
-  branded HTML/PDF. Reads git history + .claude/memory/ registries. For
-  local-business projects, appends manual SEO/GEO platform checklist (NAP
-  consistency across Google Business, Pages Jaunes, Yelp, Facebook,
-  Instagram, TikTok, Apple Maps, Bing Places, TripAdvisor, etc.). Asks
-  whether to include build/deploy chapter.
-  Trigger: "client handover", "compte rendu client", "livraison client",
-  "synthese projet", "rapport client", "deliverable", "summary for client",
-  "recap projet", "handover doc", "livrable", "ship and handover",
-  "finaliser et livrer".
+  Use when finalizing a project for non-technical client delivery — needs
+  final audits, deploy validation against live site, and a branded
+  deliverable (Markdown + HTML + PDF). Multi-agent orchestrator: dispatches
+  client-handover-writer which spawns parallel /seo + /harden subagents,
+  then /validate, then writes the deliverable.
+  Triggers: "client handover", "compte rendu client", "livraison client",
+  "rapport client", "deliverable", "summary for client", "handover doc",
+  "livrable", "ship and handover", "finaliser et livrer".
 argument-hint: [optional: language fr|en, --include-deploy, --skip-deploy, --skip-seo, --skip-audits, --skip-fix-loop, --max-iterations N, --audit-max-age <duration>, --output <path>]
 argument-hint: [optional: language fr|en, --include-deploy, --skip-deploy, --skip-seo, --skip-audits, --skip-fix-loop, --max-iterations N, --audit-max-age <duration>, --output <path>]
 disable-model-invocation: false
 disable-model-invocation: false
 allowed-tools:
 allowed-tools:

+ 34 - 22
skills/client-handover/checklists/seo-geo-manual.md

@@ -47,15 +47,16 @@ manquante dans l'adresse) divise votre visibilité Google.
 Choisissez UNE seule version officielle de chaque champ et utilisez-la
 Choisissez UNE seule version officielle de chaque champ et utilisez-la
 **à l'identique partout** :
 **à l'identique partout** :
 
 
-| Champ          | Valeur officielle à utiliser partout                       |
-|----------------|------------------------------------------------------------|
-| Nom commercial | [À COMPLÉTER — exactement comme sur le Kbis]              |
-| Adresse        | [À COMPLÉTER — n° rue, code postal, ville]                |
-| Téléphone      | [À COMPLÉTER — format: +33 X XX XX XX XX]                |
-| Email pro      | [À COMPLÉTER]                                             |
-| Site web       | [À COMPLÉTER — avec le https://]                          |
-| Horaires       | [À COMPLÉTER — ligne par jour, format 24h: 09:00–18:00]   |
-| Catégorie      | [À COMPLÉTER — la principale, ex: "Restaurant italien"]   |
+| Champ              | Valeur officielle à utiliser partout                       |
+|--------------------|------------------------------------------------------------|
+| Nom commercial     | [À COMPLÉTER — exactement comme sur le Kbis]              |
+| Adresse            | [À COMPLÉTER — n° rue, code postal, ville]                |
+| Téléphone          | [À COMPLÉTER — format: +33 X XX XX XX XX]                |
+| Email pro          | [À COMPLÉTER]                                             |
+| Site web           | [À COMPLÉTER — avec le https://]                          |
+| Catégorie          | [À COMPLÉTER — la principale, ex: "Restaurant italien"]   |
+| Description courte | [À COMPLÉTER — 1-2 phrases, voir hero / meta description du site, à recopier identique partout (Google Business, Bing, Apple, annuaires)] |
+| Horaires           | [À COMPLÉTER — ligne par jour, format 24h: 09:00–18:00]   |
 
 
 Notez ces informations dans un fichier que vous gardez à portée de main —
 Notez ces informations dans un fichier que vous gardez à portée de main —
 vous allez les recopier 10 fois.
 vous allez les recopier 10 fois.
@@ -217,8 +218,13 @@ Google vous remonte.
   https://search.google.com/search-console
   https://search.google.com/search-console
 - **Google Business Insights** — accessible depuis votre fiche Google
 - **Google Business Insights** — accessible depuis votre fiche Google
   Business Profile, montre les recherches qui mènent à vous.
   Business Profile, montre les recherches qui mènent à vous.
-- **BrightLocal Free Tools** — vérifier la cohérence de votre NAP sur
-  les annuaires : https://www.brightlocal.com/free-local-tools/
+- **Moz Local — Citation Checker (gratuit)** — audit 60 s qui vérifie
+  la cohérence NAP de votre fiche sur 50+ annuaires (Google Business,
+  Apple Plans, Yelp, Pages Jaunes, etc.) et signale doublons et
+  incohérences : https://moz.com/local (cliquer « Check My Listing »
+  ou « Get Free Audit » en page d'accueil — pas de carte bancaire
+  demandée). Remplace l'ancien outil BrightLocal Free Tools (page
+  retirée par BrightLocal en 2026, service maintenant payant).
 - **PageSpeed Insights** — vérifier que le site reste rapide :
 - **PageSpeed Insights** — vérifier que le site reste rapide :
   https://pagespeed.web.dev/
   https://pagespeed.web.dev/
 
 
@@ -261,15 +267,16 @@ Google visibility.
 Pick ONE official version of each field and use it **identically
 Pick ONE official version of each field and use it **identically
 everywhere**:
 everywhere**:
 
 
-| Field            | Official value to use everywhere                |
-|------------------|--------------------------------------------------|
-| Business name    | [TO FILL — exactly as registered]               |
-| Address          | [TO FILL — street, city, ZIP, country]          |
-| Phone            | [TO FILL — format: +1 XXX XXX XXXX]             |
-| Pro email        | [TO FILL]                                       |
-| Website          | [TO FILL — with https://]                       |
-| Hours            | [TO FILL — per day, 24h format: 09:00-18:00]    |
-| Primary category | [TO FILL — e.g., "Italian restaurant"]          |
+| Field             | Official value to use everywhere                |
+|-------------------|--------------------------------------------------|
+| Business name     | [TO FILL — exactly as registered]               |
+| Address           | [TO FILL — street, city, ZIP, country]          |
+| Phone             | [TO FILL — format: +1 XXX XXX XXXX]             |
+| Pro email         | [TO FILL]                                       |
+| Website           | [TO FILL — with https://]                       |
+| Primary category  | [TO FILL — e.g., "Italian restaurant"]          |
+| Short description | [TO FILL — 1-2 sentences, lift from site hero / meta description, paste identically everywhere (Google Business, Bing, Apple, directories)] |
+| Hours             | [TO FILL — per day, 24h format: 09:00-18:00]    |
 
 
 Save these in a file you can reach in two clicks. You will copy them 10
 Save these in a file you can reach in two clicks. You will copy them 10
 times.
 times.
@@ -422,8 +429,13 @@ results. More reviews (positive AND recent) = higher Google ranking.
   https://search.google.com/search-console
   https://search.google.com/search-console
 - **Google Business Insights** — inside your Google Business Profile,
 - **Google Business Insights** — inside your Google Business Profile,
   shows what searches lead to you.
   shows what searches lead to you.
-- **BrightLocal Free Tools** — verify NAP consistency across directories:
-  https://www.brightlocal.com/free-local-tools/
+- **Moz Local — Citation Checker (free)** — 60-second audit checking
+  NAP consistency across 50+ directories (Google Business, Apple
+  Maps, Yelp, etc.) and flagging duplicates and inconsistencies:
+  https://moz.com/local (click "Check My Listing" or "Get Free
+  Audit" on the homepage — no credit card required). Replaces the
+  former BrightLocal Free Tools (page removed by BrightLocal in
+  2026, service now paid-only).
 - **PageSpeed Insights** — confirm site stays fast:
 - **PageSpeed Insights** — confirm site stays fast:
   https://pagespeed.web.dev/
   https://pagespeed.web.dev/
 
 

+ 20 - 6
skills/client-handover/resources/branding/zenquality.css

@@ -372,7 +372,6 @@ ul.task-list li {
 
 
 ul.checklist li::before,
 ul.checklist li::before,
 ul.task-list li::before,
 ul.task-list li::before,
-li input[type="checkbox"] + *,
 li.task-list-item::before {
 li.task-list-item::before {
   content: "☐";
   content: "☐";
   position: absolute;
   position: absolute;
@@ -382,13 +381,28 @@ li.task-list-item::before {
   line-height: 1;
   line-height: 1;
 }
 }
 
 
-input[type="checkbox"] {
-  display: none;
+/* Pandoc GFM emits <li><input disabled type="checkbox"> text...</li> with
+   no wrapper class. Render the native checkbox inline (small, green) and
+   leave inline elements (<a>, <code>, <strong>) that follow it untouched.
+   Earlier rule `li input[type="checkbox"] + *` mistakenly absolutely-
+   positioned the first element sibling after the checkbox, yanking links
+   and code spans out of flow and overlapping adjacent content. */
+li > input[type="checkbox"] {
+  appearance: none;
+  -webkit-appearance: none;
+  display: inline-block;
+  width: 3mm;
+  height: 3mm;
+  margin: 0 1.5mm 0 0;
+  border: 0.4mm solid var(--green-moss);
+  border-radius: 0.5mm;
+  vertical-align: middle;
+  background: transparent;
 }
 }
 
 
-input[type="checkbox"]:checked + label::before {
-  content: "☑";
-  color: var(--green-forest);
+li > input[type="checkbox"]:checked {
+  background: var(--green-forest);
+  border-color: var(--green-forest);
 }
 }
 
 
 /* ============ CALLOUTS ============ */
 /* ============ CALLOUTS ============ */

+ 1 - 1
skills/client-handover/scripts/handover-to-pdf.sh

@@ -121,7 +121,7 @@ fi
 md_to_html_body() {
 md_to_html_body() {
   local src="$1"
   local src="$1"
   if command -v pandoc >/dev/null 2>&1; then
   if command -v pandoc >/dev/null 2>&1; then
-    pandoc --from=gfm --to=html5 --no-highlight "$src"
+    pandoc --from=gfm+gfm_auto_identifiers --to=html5 --no-highlight "$src"
     return
     return
   fi
   fi
   if command -v python3 >/dev/null 2>&1 && python3 -c "import markdown" >/dev/null 2>&1; then
   if command -v python3 >/dev/null 2>&1 && python3 -c "import markdown" >/dev/null 2>&1; then

+ 8 - 16
skills/doc/SKILL.md

@@ -1,22 +1,14 @@
 ---
 ---
 name: doc
 name: doc
 description: |
 description: |
-  Full documentation audit and sync. Auto-detects what doc files the project
-  actually has — root docs (README, CLAUDE.md, INSTALL.md, CONFIGURE.md,
-  USAGE.md, DEPLOY.md, CONTRIBUTING.md, CHANGELOG.md), docs/**/*.md, project-state
-  files in .claude/{tasks,audits,memory}/, and inline comments (JSDoc, docstrings,
-  rustdoc, godoc). Stack-aware: detects framework + deploy complexity, proposes
-  DEPLOY.md only when non-trivial (Docker, fly.toml, k8s, multi-stage CI), skips
-  for trivial deploys (FTP push, single scp, plain static). Enforces README
-  presence with typical GitHub layout (title, quick start, links to existing
-  sub-docs). Cross-references git history for drift; detects added features
-  missing from docs and removed features still documented (feature delta
-  detection). Reports drift with commit refs, proposes fixes, patches approved
-  items.
-  Trigger: "doc", "sync docs", "audit docs", "update readme", "check documentation",
-  "are docs up to date", "documentation drift", "stale docs", "new feature not documented",
-  "removed feature still in docs", "create README", "should I have a DEPLOY doc".
-  Replaces the old /readme skill with broader scope.
+  Use when documentation may be out of sync with code — added features
+  missing from docs, removed features still documented, or README / INSTALL
+  / DEPLOY / CHANGELOG drift detected. Stack-aware audit, cross-references
+  git history, patches approved items.
+  Triggers: "doc", "sync docs", "audit docs", "update readme", "check
+  documentation", "are docs up to date", "documentation drift", "stale docs",
+  "new feature not documented", "removed feature still in docs",
+  "create README", "should I have a DEPLOY doc".
 argument-hint: [leave empty for full audit, or list specific files/docs to check]
 argument-hint: [leave empty for full audit, or list specific files/docs to check]
 disable-model-invocation: false
 disable-model-invocation: false
 allowed-tools:
 allowed-tools:

+ 9 - 14
skills/geo/SKILL.md

@@ -1,20 +1,15 @@
 ---
 ---
 name: geo
 name: geo
 description: |
 description: |
-  Standalone GEO (Generative Engine Optimization) audit for AI search
-  engines: ChatGPT, Perplexity, Claude, Gemini, Google AI Overviews,
-  Microsoft Copilot, Brave AI, DuckAssist, You.com, Apple Intelligence.
-  Audits AI crawler directives, llms.txt / llms-full.txt, Schema.org
-  types optimised for AI extraction (QAPage, Speakable, Person+Article,
-  HowTo, Organization graph), entity SEO (Wikidata, sameAs, @id,
-  Knowledge Panel), content shape for LLM extraction (Definition Lead,
-  TL;DR, Q→A structure, citable stats, freshness), and live AI
-  visibility monitoring.
-  For full SEO + GEO combined audit → use /seo (runs seo + geo in parallel).
-  For classical SEO only → use /seo and skip the GEO section.
-  Trigger: "geo", "AI search", "ChatGPT visibility", "Perplexity optimisation",
-  "llms.txt", "AI crawlers", "Google AI Overview", "entity SEO", "Wikidata",
-  "generative engine optimization", "référencement IA", "optimisation IA".
+  Use when a web project needs AI-search visibility audit — ChatGPT,
+  Perplexity, Claude, Gemini, AI Overviews, Copilot, Brave AI, DuckAssist,
+  You.com, Apple Intelligence. Standalone GEO; dispatches the geo-analyzer
+  agent.
+  Triggers: "geo", "AI search", "ChatGPT visibility", "Perplexity
+  optimisation", "llms.txt", "AI crawlers", "Google AI Overview",
+  "entity SEO", "Wikidata", "generative engine optimization",
+  "référencement IA", "optimisation IA".
+  For combined SEO+GEO → /seo.
 argument-hint: optional keywords/scope, e.g. "SaaS B2B content GEO" or "audit llms.txt et entity SEO"
 argument-hint: optional keywords/scope, e.g. "SaaS B2B content GEO" or "audit llms.txt et entity SEO"
 allowed-tools:
 allowed-tools:
   - Read
   - Read

+ 1 - 1
skills/init-project/SKILL.md

@@ -1,6 +1,6 @@
 ---
 ---
 name: init-project
 name: init-project
-description: Full project init: interview → design → scaffold → implement (TDD). Two validation gates.
+description: Use when initializing a brand-new project from scratch — needs interview, design, scaffold, and TDD implementation. Multi-agent orchestrator: plugin-advisor + interviewer + analyzer + scaffolder with two validation gates. Triggers: "init project", "new project", "start project from scratch", "scaffold project", "init-project".
 argument-hint: <project idea or description>
 argument-hint: <project idea or description>
 disable-model-invocation: true
 disable-model-invocation: true
 allowed-tools: Read, Write, Edit, Bash, Grep, Glob
 allowed-tools: Read, Write, Edit, Bash, Grep, Glob

+ 1 - 1
skills/onboard/SKILL.md

@@ -1,6 +1,6 @@
 ---
 ---
 name: onboard
 name: onboard
-description: Onboard an existing repo — detect archetype, install claude-config, run full audit (debt/SEO/GEO/UI-UX/perf/security/a11y/docs), output prioritized improvement plan in .claude/audits/ + .claude/tasks/. Use on repos not created via /init-project.
+description: Use when bringing an existing repo into the claude-config framework — needs archetype detection, config install, full multi-axis audit (debt/SEO/GEO/UI-UX/perf/security/a11y/docs), and prioritized backlog. Multi-agent orchestrator. Do NOT use for repos created via /init-project. Triggers: "onboard", "onboard project", "audit existing repo", "setup existing project".
 argument-hint: [optional hints: "Python FastAPI" | "add gsd" | "Next.js monorepo" | "force-archetype:wordpress"]
 argument-hint: [optional hints: "Python FastAPI" | "add gsd" | "Next.js monorepo" | "force-archetype:wordpress"]
 disable-model-invocation: true
 disable-model-invocation: true
 allowed-tools: Read, Write, Edit, Bash, Glob, Grep
 allowed-tools: Read, Write, Edit, Bash, Glob, Grep

+ 10 - 19
skills/seo/SKILL.md

@@ -1,25 +1,16 @@
 ---
 ---
 name: seo
 name: seo
 description: |
 description: |
-  Full SEO + GEO audit and optimization for any web project.
-  Runs the seo-analyzer (classical search — Google, Bing, DuckDuckGo)
-  and geo-analyzer (AI search — ChatGPT, Perplexity, Claude, Gemini,
-  Google AI Overviews, Copilot) IN PARALLEL, then consolidates their
-  output into a unified .claude/audits/SEO.md report.
-  Covers: meta, OG, JSON-LD (classical + GEO-optimised schemas),
-  sitemap, robots.txt (including AI crawlers), llms.txt, headings,
-  alt attrs, canonicals, hreflang, Core Web Vitals, entity SEO
-  (Wikidata, sameAs, Knowledge Panel), content shape for AI extraction,
-  AI visibility monitoring.
-  Trigger: "seo", "referencement", "optimize for search", "audit SEO",
-  "meta tags", "structured data", "JSON-LD", "sitemap", "robots.txt",
-  "Google ranking", "local SEO", "referencement local", "fiche Google",
-  "AI search", "GEO", "llms.txt", "ChatGPT visibility", "Perplexity",
-  "Google AI Overview".
-  For GEO-only audit → use /geo.
-  For W3C HTML/CSS validity + WCAG a11y → use /validate (syntactic conformance,
-  not ranking signals).
-  For code-only bugs → use /bugfix. For feature work → use /feat.
+  Use when a web project needs SEO + GEO audit or optimization — classical
+  search (Google, Bing, DuckDuckGo) AND AI search (ChatGPT, Perplexity,
+  Claude, Gemini, AI Overviews, Copilot). Parallel multi-agent orchestrator:
+  dispatches seo-analyzer + geo-analyzer concurrently, merges envelopes into
+  .claude/audits/SEO.md.
+  Triggers: "seo", "referencement", "audit SEO", "meta tags",
+  "structured data", "JSON-LD", "sitemap", "robots.txt", "Google ranking",
+  "local SEO", "AI search", "GEO", "llms.txt", "ChatGPT visibility",
+  "Perplexity", "Google AI Overview".
+  For GEO only → /geo. For W3C/a11y → /validate. For bugs → /bugfix.
 argument-hint: optional keywords/scope, e.g. "local SEO plombier 91 94 77" or "SaaS B2B content strategy"
 argument-hint: optional keywords/scope, e.g. "local SEO plombier 91 94 77" or "SaaS B2B content strategy"
 allowed-tools:
 allowed-tools:
   - Read
   - Read

+ 1 - 1
skills/ship-feature/SKILL.md

@@ -1,6 +1,6 @@
 ---
 ---
 name: ship-feature
 name: ship-feature
-description: Ship feature end-to-end: design → plan → implement (TDD) → review → finish
+description: Use when shipping a new feature end-to-end — needs design brainstorm, planning, TDD implementation with subagents, error recovery, code review, and finish. Multi-agent orchestrator (9-step pipeline). Triggers: "ship feature", "ship-feature", "build and merge", "feature end-to-end", "implement and ship".
 argument-hint: <feature description>
 argument-hint: <feature description>
 disable-model-invocation: true
 disable-model-invocation: true
 allowed-tools: Read, Write, Edit, Bash, Grep, Glob
 allowed-tools: Read, Write, Edit, Bash, Grep, Glob

+ 8 - 14
skills/validate/SKILL.md

@@ -1,20 +1,14 @@
 ---
 ---
 name: validate
 name: validate
 description: |
 description: |
-  Web standards audit — W3C HTML validity (validator.nu), W3C CSS
-  validity (jigsaw.w3.org/css-validator), WCAG 2.1 accessibility
-  (axe-core, pa11y, WAVE API). Dedicated to syntactic and
-  accessibility conformance. Produces .claude/audits/VALIDATE.md.
-  Dispatches the validator-analyzer agent with a STRICT scope
-  filter — no meta/OG/JSON-LD/CWV/security-header noise.
-  Trigger: "validate", "validation", "w3c", "html validity",
-  "css validity", "wcag", "accessibility", "a11y audit", "axe",
-  "pa11y", "wave", "validator.w3.org", "nu validator",
-  "validation html", "accessibilité", "audit a11y", "audit wcag",
-  "normes w3c", "conformité web", "validité html css".
-  For security hardening (CSP, HSTS, 404) → use /harden.
-  For SEO/indexability (meta, sitemap, JSON-LD) → use /seo.
-  For AI engines (llms.txt, QAPage, entity SEO) → use /geo.
+  Use when a web project needs W3C HTML/CSS validity check or WCAG 2.1
+  accessibility audit. Dispatches the validator-analyzer agent with a
+  STRICT scope filter (no meta/OG/JSON-LD/CWV/security-header noise).
+  Triggers: "validate", "validation", "w3c", "html validity",
+  "css validity", "wcag", "accessibility", "a11y audit", "axe", "pa11y",
+  "wave", "validator.w3.org", "nu validator", "accessibilité",
+  "audit a11y", "audit wcag", "normes w3c", "conformité web".
+  For CSP/HSTS/404 → /harden. For meta/sitemap → /seo. For AI engines → /geo.
 argument-hint: [URL] [--fix] [--local|--full] [--no-external]
 argument-hint: [URL] [--fix] [--local|--full] [--no-external]
 allowed-tools:
 allowed-tools:
   - Read
   - Read