11 次代碼提交 cff445651f ... a8c0bde367

作者 SHA1 備註 提交日期
  bastien a8c0bde367 memory: capitalize 2026-05-15 — BDR-016 + LRN-019 (doc-syncer rework) 1 天之前
  bastien f57a7f2524 chore(settings): enable ui-ux-pro-max skill 1 天之前
  bastien 7ee9b42203 feat(doc-syncer): README mandatory + 14-section prod-only DEPLOY.md 1 天之前
  bastien 1bf02eaa61 memory: capitalize darwin 2026-05-12 — LRN-017/018 + BLK-003 + BDR-015 4 天之前
  bastien fa768cb2ef merge darwin: bottom-5 skill optimization round 1 4 天之前
  bastien e53c4062e1 darwin: Phase 3 report — bottom-5 round 1, avg 58.0 → 78.2 4 天之前
  bastien 134561dec9 optimize skills-perso + commit-change: round 1 — D3 edge cases 4 天之前
  bastien d3dd31c3c7 optimize plugin-check: round 1 — D3 fallback + D1 triggers + advisory clarification 4 天之前
  bastien 079074d393 optimize refactor: round 1 — D3 fallback + D1 triggers 4 天之前
  bastien 512df486d7 optimize status: round 1 — D3 fallback + triggers 4 天之前
  bastien b6f1acfa17 darwin: add test prompts for 5 skills (baseline pass) 4 天之前

+ 139 - 0
.claude/audits/DARWIN-SKILL-2026-05-12.md

@@ -0,0 +1,139 @@
+# Darwin Skill Optimization — 2026-05-12
+
+**Branch:** `auto-optimize/20260512-1319`
+**Scope:** 28 dirs in `~/Documents/claude/skills/` (cwd = source of truth, ~/.claude/skills is runtime mirror)
+**Eval mode:** structural dim 1-7 full / dim 8 `dry_run`
+**Phase reached:** 2 (round 1 per skill — rounds 2-3 skipped for diminishing returns)
+**Runtime:** ~30 min
+
+---
+
+## Baseline scorecard (23 scoreable + 5 excluded)
+
+23 personal skills scored. 5 broken gstack symlinks excluded (not user-owned).
+
+| Rank | Skill            | Baseline | Weakest |
+|------|------------------|---------:|---------|
+| 1    | status           | 45.3 | D3 |
+| 2    | refactor         | 48.4 | D4 |
+| 3    | plugin-check     | 59.2 | D4 |
+| 4    | skills-perso     | 66.4 | D3 |
+| 5    | commit-change    | 69.6 | D3 |
+| 6    | hotfix           | 74.1 | D4 |
+| 7    | code-clean       | 74.7 | D3 |
+| 8    | feat             | 74.7 | D4 |
+| 9    | doc              | 76.2 | D3 |
+| 10   | analyze          | 76.4 | D4 |
+| 11   | validate         | 76.4 | D4 |
+| 12   | geo              | 76.5 | D4 |
+| 13   | profile          | 78.3 | D3 |
+| 14   | close            | 79.2 | D3 |
+| 15   | bugfix           | 79.3 | D4 |
+| 16   | seo              | 82.5 | D4 |
+| 17   | onboard          | 83.5 | D8 |
+| 18   | client-handover  | 83.9 | D8 |
+| 19   | init-project     | 84.1 | D8 |
+| 20   | ship-feature     | 84.3 | D8 |
+| 21   | prune-memory     | 84.6 | D8 |
+| 22   | harden           | 85.5 | D8 |
+| *    | graphify         | 29.0 | D4 |
+
+graphify scored on partial read (62KB SKILL.md exceeded token limit). Real fix likely a Phase 2.5 exploratory rewrite, not hill-climb — deferred.
+
+**Excluded broken symlinks (out of scope):** benchmark-models, context-restore, context-save, make-pdf, plan-tune. All point to `skills-external/gstack/<name>/SKILL.md` which doesn't exist.
+
+**Average across 23: 75.6 / 100.**
+
+---
+
+## Phase 2 — optimized skills (bottom 5)
+
+User-confirmed queue: bottom 5 by baseline (graphify deferred).
+
+| Skill          | Before | After | Δ      | Round | Status | Change                                       |
+|----------------|-------:|------:|-------:|:-----:|:------:|----------------------------------------------|
+| status         | 45.3   | 76.2  | +30.9  | 1     | keep   | D3 fallback + frontmatter triggers           |
+| refactor       | 48.4   | 74.3  | +25.9  | 1     | keep   | D3 fallback + frontmatter triggers           |
+| plugin-check   | 59.2   | 76.8  | +17.6  | 1     | keep   | D3 fallback + triggers + advisory note       |
+| skills-perso   | 66.4   | 80.1  | +13.7  | 1     | keep   | D3 "Known limits of heuristic" section       |
+| commit-change  | 69.6   | 83.5  | +13.9  | 1     | keep   | D3 fallback + pre-flight git checks (HEAD/identity) |
+
+**Average:** 58.0 → 78.2 (+20.2 per skill).
+**Kept:** 5/5. **Reverted:** 0.
+
+### Per-skill commit
+
+- `512df48` optimize status: round 1 — D3 fallback + triggers
+- `079074d` optimize refactor: round 1 — D3 fallback + D1 triggers
+- `d3dd31c` optimize plugin-check: round 1 — D3 fallback + D1 triggers + advisory clarification
+- `134561d` optimize skills-perso + commit-change: round 1 — D3 edge cases
+
+### Same pattern across the bottom 4 dispatchers
+
+status, refactor, plugin-check, commit-change are all thin dispatchers (15-30 lines, body = "load and follow agents/<x>.md + $ARGUMENTS"). Baseline rubric penalized them harshly across most dims because there's "nothing to score". Round 1 fix is invariant:
+
+1. Add fallback clause: "If agent file unreachable, emit `<X> agent missing.` and STOP."
+2. Add explicit triggers in frontmatter description.
+3. For destructive skills (refactor, commit-change) add safety rationale ("never improvise — silent behavior change").
+
+skills-perso is the outlier — full implementation, not a dispatcher. Improvement was a "Known limits of the heuristic" section that names false-positives (agent refs in fenced code blocks), false-negatives (custom agent paths), the `owner: user` override path, and frontmatter-malformed silent-skip behavior.
+
+---
+
+## Methodology notes & caveats
+
+1. **Eval math drift.** Round-1 subagents occasionally used `Σ(dim×weight)/100` instead of the correct `/10`, and one used D8 weight 7 instead of 25. Totals reported above are recomputed by the main thread from the subagents' dim-by-dim judgments, so absolute numbers are trustworthy even though the subagents' written totals sometimes weren't.
+
+2. **Score recalibration at round 1.** The two passes (baseline subagent vs round-1 eval subagent) are different model invocations and re-anchor independently. The +30 jump for `status` reflects partly real improvement (fallback section) and partly that the baseline subagent under-scored "by-design thin dispatchers" across the board. Δ direction is reliable; absolute magnitudes are noisy.
+
+3. **150% size cap is tight for thin dispatchers.** `status` (15 lines, 776B) and `refactor` (15 lines, 379B) had ~22-line / ~570B caps. Multiple trim cycles per skill to fit. Recommend the spec consider an absolute-byte floor (e.g., min cap = max(150%, 1000B)) for cases where the original was minimal.
+
+4. **D8 (effect) untested.** Spec allows `dry_run`; all 5 logged as such. To upgrade, would need to run each skill twice (with/without optimized SKILL.md) and compare outputs. Saved for a follow-up pass.
+
+5. **Rounds 2-3 skipped.** Round 1 Δ for all 5 was big (+13.7 to +30.9). Round 2 expected Δ is small (returns flatten near 80). Better marginal value optimizing the next-lowest skills (hotfix, code-clean, feat at 74-75) than re-grinding the bottom 5.
+
+6. **Screenshot.mjs is macOS-only.** Script hardcodes `/Users/alchain/.npm-global/...`. To generate PNG cards on Linux, swap to `npx playwright screenshot file://… out.png --viewport-size=960,1280` or fix the script's `require()` path.
+
+---
+
+## Suggested next passes
+
+| Priority | Action |
+|----------|--------|
+| P1 | Hill-climb rank 6-12 (hotfix, code-clean, feat, doc, analyze, validate, geo) — same dispatcher fallback pattern; expected +5 to +15 per skill |
+| P1 | Phase 2.5 exploratory rewrite of `graphify` (62KB SKILL.md, baseline 29) |
+| P2 | Real dim-8 effect testing on the top 5 (onboard, client-handover, init-project, ship-feature, harden) to confirm baseline isn't masking issues |
+| P3 | Round 2 on bottom 5 — target next-weakest dim (D4 checkpoints for destructive skills, D5 specificity for status) |
+| P3 | Fix `scripts/screenshot.mjs` for Linux + generate PNG cards |
+
+---
+
+## Files touched (committed on `auto-optimize/20260512-1319`)
+
+```
+skills/status/SKILL.md          (+9 -2)
+skills/refactor/SKILL.md        (+3 -4)
+skills/plugin-check/SKILL.md    (+5 -5)
+skills/skills-perso/SKILL.md    (+18 -0)
+skills/commit-change/SKILL.md   (+5 -3)
+skills/close/test-prompts.json       (new)
+skills/graphify/test-prompts.json    (new)
+skills/harden/test-prompts.json      (new)
+skills/profile/test-prompts.json     (new)
+skills/prune-memory/test-prompts.json (new)
+```
+
+5 commits on branch. To merge:
+
+```bash
+git checkout master
+git merge --no-ff auto-optimize/20260512-1319
+```
+
+Or review per-commit and cherry-pick. No master commits yet — branch is purely additive.
+
+---
+
+## results.tsv
+
+Persisted to `~/.agents/skills/darwin-skill/results.tsv` (28 baseline rows + 5 round-1 rows = 33 total).

+ 13 - 1
.claude/memory/blockers.md

@@ -22,6 +22,7 @@ rules:
 |----|------|---------|--------|
 | BLK-001 | 2026-04-22 | `rtk curl` breaks JSON pipelines | upstream |
 | BLK-002 | 2026-04-23 | `rmdir` denied in sandbox on empty directory | resolved |
+| BLK-003 | 2026-05-12 | `scripts/screenshot.mjs` hardcoded macOS path blocks PNG cards on Linux | upstream |
 
 ---
 
@@ -44,4 +45,15 @@ rules:
 - **Solution**:
   - This session: `git rm tasks/*.md` handled files individually (via `git rm`, cleared gate). Git auto-detected renames to `.claude/tasks/`, so `tasks/` directory removed implicitly at commit time.
   - If dir persists empty after `git rm`: ask user to run `rmdir tasks` manually.
-- **Status**: resolved (fixed via `git rm` + rename auto-detection; no `rmdir` needed in practice).
+- **Status**: resolved (fixed via `git rm` + rename auto-detection; no `rmdir` needed in practice).
+## BLK-003 — `scripts/screenshot.mjs` hardcoded macOS path blocks PNG cards on Linux
+
+- **Date**: 2026-05-12
+- **Friction**: `/darwin-skill` Phase 3 generates result cards via `node ~/.agents/skills/darwin-skill/scripts/screenshot.mjs <html> <png>`. On Linux: script fails immediately — `require('/Users/alchain/.npm-global/lib/node_modules/playwright/node_modules/playwright-core')` resolves to a non-existent macOS user path. No PNG cards produced; Phase 3 falls back to markdown report only.
+- **Real cause**: upstream `alchaincyf/darwin-skill` author dev'd on macOS, shipped absolute path to their own homedir's global npm install of playwright. Zero portability layer (no PATH lookup, no `playwright` bare require, no fallback to `npx`).
+- **Solution**:
+  - Workaround (used 2026-05-12): skip PNG generation, deliver markdown + HTML cards (HTML viewable in browser without playwright).
+  - Local patch: `npm i -g playwright` then replace `require('/Users/alchain/...')` with `require('playwright')`. Two lines edit.
+  - Spec-documented fallback: `npx playwright screenshot "file:///path/to/card.html#<theme>" out.png --viewport-size=960,1280 --wait-for-timeout=2000` — works without modifying the file, costs ~150MB chromium download.
+  - PR upstream to `github.com/alchaincyf/darwin-skill` once tested.
+- **Status**: upstream (third-party skill at `~/.agents/skills/darwin-skill/scripts/screenshot.mjs`, not in any of our repos).

+ 40 - 0
.claude/memory/decisions.md

@@ -36,6 +36,8 @@ rules:
 | 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 |
+| BDR-015 | 2026-05-12 | Exclude broken gstack symlinks from /darwin-skill scope (external ownership) | accepted |
+| BDR-016 | 2026-05-15 | doc-syncer: README AUTO+unconditional, DEPLOY.md prod-only + 14-section VPS template | accepted |
 
 ---
 
@@ -264,3 +266,41 @@ rules:
   - 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.
+
+---
+
+## BDR-015 — Exclude broken gstack symlinks from /darwin-skill scope (external ownership)
+
+- **Date**: 2026-05-12
+- **Status**: accepted
+- **Decision**: 5 dirs in `~/Documents/claude/skills/` whose `SKILL.md` symlinks point to non-existent gstack paths (`skills-external/gstack/<name>/SKILL.md` missing) — `benchmark-models`, `context-restore`, `context-save`, `make-pdf`, `plan-tune` — are excluded from `/darwin-skill` baseline + optimization. Marked `status=error` in `results.tsv` with note `broken gstack symlink — out of scope`. NOT scored, NOT optimized, NOT deleted.
+- **Why**: darwin-skill constraint #1 forbids changing a skill's core function — implies external/gstack-owned skills are out of scope. Symlinks resolve to `skills-external/gstack` which is third-party submodule. Plus the targets are broken — gstack's actual layout (`benchmark/`, `health/`, `qa/`, etc.) doesn't include these 5 names, suggesting upstream rename or removal. Repairing them is a separate triage task, not darwin's concern.
+- **Alternatives rejected**:
+  - Fix symlinks first then darwin-optimize → out of scope, blocks the optimization queue on gstack archaeology.
+  - Score them with `FILE_NOT_FOUND` and include in averages → biases stats, mixes signal with infrastructure issue.
+  - Optimize the gstack source files directly → external ownership, never modify.
+  - Delete the broken symlinks → would obscure that the user once expected these to exist; leave for triage.
+- **Caveats**:
+  - If/when symlinks are repaired (real gstack target exists), re-run baseline to bring them in scope.
+  - Bigger picture: `benchmark-models` looks like a deliberate rename of gstack's `benchmark` to disambiguate from the gstack-skill called `/benchmark`. Could be a planned migration that stalled. Worth a one-line ticket separate from darwin.
+
+---
+
+## BDR-016 — doc-syncer: README AUTO+unconditional, DEPLOY.md prod-only + 14-section VPS template
+
+- **Date**: 2026-05-15
+- **Status**: accepted
+- **Decision**: `agents/doc-syncer.md` STEP 5/6/8/A4 rewritten. README creation now AUTO + unconditional in both interactive and AUTO modes. Validation gate offers only `yes` or `edit` for README — no `skip`/`no`. Any project-level "no README" opt-out (e.g. `CLAUDE.md` "Exceptions: No README at scaffold") gets struck through during same patch. README template expanded: features, Stack, Quick start (dev), Verifying a change, Build & deploy, Documentation, License — all rendered from real manifest/`.env.example`/scripts data, no placeholders. DEPLOY.md becomes prod-only, expanded into 14-section VPS-deploy structure (topology table, env vars, VPS provisioning, two-layer firewall, Docker tuning, first-time setup, routine deploys, persistence, backups, TLS, observability, hardening, rollback, runbook). Dev quick-start lives ONLY in README "Quick start (dev)" section; mixed dev/prod DEPLOY.md flagged as drift, dev content proposed for move to README during same patch round.
+- **Why**: README opt-out makes repo look abandoned to anyone landing on it — universal "always render" beats opt-in. Mixed dev/prod DEPLOY.md was drift source: devs read DEPLOY for local setup, ops read DEPLOY for prod, both edit independently, conflicts pile up. Clean audience split — README = dev + features audience, DEPLOY = ops + SRE audience — gives each doc one owner mental model. 14-section VPS template mirrors real Scaleway/Hetzner/OVH/DO/Vultr deploy shape (reference: Scaleway DEV1-S walkthrough) so the doc maps 1:1 to the runbook ops actually execute.
+- **Alternatives rejected**:
+  - Keep README gated on HUMAN approval (status quo) — rejected: opt-outs proliferated, repos shipped with no README. Friction wins.
+  - Single ARCHITECTURE+DEPLOY doc — rejected: mixed-audience doc is the drift source we're fixing. Don't recombine.
+  - Trim DEPLOY.md to single "Production" section — rejected: real VPS deploys need topology + firewall + Docker tuning + backups + TLS + observability. Single section becomes wall-of-text nobody reads.
+  - Optional README in AUTO mode (default skip) — rejected: AUTO mode purpose is friction removal. README is most-missed doc; auto-render it.
+  - Auto-write the README without surfacing draft — rejected: rendered draft still shown at validation gate so user can `edit` before write. "No skip" ≠ "no review".
+- **Caveats**:
+  - Real-project-data rule still binds — license = "Not specified — set one before public release" (explicit gap, not fabricated SPDX).
+  - 14-section DEPLOY template drops sections that don't apply (e.g. "Managed DB" if no DB). Template = ceiling not floor.
+  - If `DEPLOY_COMPLEXITY == TRIVIAL`, no DEPLOY.md created — deploy stays in README. Threshold = no Docker + no compose + no fly.toml + no k8s + no scripts/deploy.* → trivial.
+  - Existing DEPLOY.md with `Local development` / `Dev setup` section → surfaced as drift, content moved to README, section removed from DEPLOY. Not a silent rewrite.
+- **Reference**: commit `7ee9b42`, `agents/doc-syncer.md` STEP 5 (README mandatory clause + template lines 223–335), STEP 6 (14-section DEPLOY.md template lines 338–541), STEP 8 (validation gate `yes/edit` for README, `yes/no/edit` for HUMAN), STEP A4 (AUTO MODE README-missing → SIGNIFICANT). Linked to [[doc-syncer-two-doc-split]] (LRN-019).

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

@@ -87,3 +87,22 @@ rules:
 - 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).
+
+## 2026-05-12
+
+- Ran `/darwin-skill` full pipeline on cwd repo (real skill source, not `~/.claude/skills/` runtime mirror). Baseline scored 23 personal skills + 5 broken gstack symlinks excluded. Avg baseline 75.6.
+- Phase 2 round 1 on bottom 5: status 45.3→76.2 (+30.9), refactor 48.4→74.3 (+25.9), plugin-check 59.2→76.8 (+17.6), skills-perso 66.4→80.1 (+13.7), commit-change 69.6→83.5 (+13.9). All KEEP. Avg 58.0→78.2 (+20.2/skill).
+- Rounds 2-3 skipped — diminishing returns past round 1 on dispatcher pattern. graphify (29.0, 62KB SKILL.md) deferred to Phase 2.5 exploratory rewrite per user.
+- Pattern observed: thin-dispatcher round-1 invariant = fallback + frontmatter triggers. Replicable across the 4 dispatchers tested. Captured as LRN-017.
+- Methodology gotcha: darwin eval subagents drift on total math (factor-10 errors, D8 weight 7 vs 25). Direction reliable, magnitude noisy. Captured as LRN-018. Recompute totals in main thread going forward.
+- BDR-015: broken gstack symlinks (5 dirs) excluded from darwin scope — external ownership + missing targets.
+- BLK-003: `scripts/screenshot.mjs` hardcoded macOS path → PNG cards skipped on Linux. Markdown report + 5 new test-prompts.json + 5 optimized SKILL.md only. Upstream issue, workaround in place.
+- Branch `auto-optimize/20260512-1319` merged via `--no-ff` to master. 6 commits land. Report at `.claude/audits/DARWIN-SKILL-2026-05-12.md`. results.tsv at `~/.agents/skills/darwin-skill/results.tsv` (33 rows).
+- Pre-existing uncommitted `agents/doc-syncer.md` (mtime 15:33, before session) NOT touched — left for the work session that owns it.
+
+## 2026-05-15
+
+- `/commit-change` over working tree: 2 commits land. `7ee9b42 feat(doc-syncer): README mandatory + 14-section prod-only DEPLOY.md` reworks STEP 5/6/8/A4 — README AUTO+unconditional, DEPLOY.md prod-only, 14-section VPS template. `f57a7f2 chore(settings): enable ui-ux-pro-max skill` toggles `ui-ux-pro-max@ui-ux-pro-max-skill` false → true.
+- BDR-016 capitalized — README AUTO+unconditional + DEPLOY prod-only is design decision: opt-out makes repo look abandoned, mixed dev/prod DEPLOY = drift source. README has only `yes`/`edit` at validation gate, no `skip`.
+- LRN-019 capitalized — doc split by audience (README=dev, DEPLOY=ops) generalizes across deployable projects. 14-section VPS template = ceiling not floor, drop sections that don't apply. Audience test: junior dev → README, on-call SRE → DEPLOY.
+- Skipped: `skills-external/gstack` (submodule pointer unchanged, only `.gbrain/`+`.hermes/` untracked inside), `Screenshot from 2026-05-09 02-40-42.png` (binary, default-exclude).

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

@@ -36,6 +36,9 @@ rules:
 | 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 |
+| LRN-017 | 2026-05-12 | Thin-dispatcher SKILL.md round-1 win = fallback + frontmatter triggers (+15 to +30) | any `/darwin-skill` round-1 on a dispatcher SKILL.md |
+| LRN-018 | 2026-05-12 | Darwin eval subagents drift on total math — recompute in main thread | any subagent-driven SKILL.md rescore |
+| LRN-019 | 2026-05-15 | Deployable-project doc split: README dev-quickstart + DEPLOY 14-section prod-VPS topology | any onboard/doc-syncer/scaffold producing docs for a deployable project |
 
 ---
 
@@ -232,3 +235,49 @@ rules:
   - 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`.
+
+---
+
+## LRN-017 — Thin-dispatcher SKILL.md round-1 win = fallback + frontmatter triggers (+15 to +30)
+
+- **Date**: 2026-05-12
+- **Pattern**: thin-dispatcher SKILL.md (delegates to `agents/<x>.md`, body 15-30 lines, no inline workflow) scores low on darwin rubric (45-70) because dims D2/D3/D4/D5 punish empty body. Round-1 universal fix:
+  1. Add fallback clause — `If $HOME/.claude/agents/<x>.md unreachable, emit "<X> agent missing." and STOP. Never improvise — silent behavior change is unsafe.`
+  2. Add triggers to frontmatter `description` — explicit `Triggers: "<keyword>", "<synonym>", "<i18n variant>".`
+  3. For destructive skills (refactor, commit-change): add safety rationale + pre-flight check stub.
+  Δ +13 to +31 observed: status 45.3→76.2 (+30.9), refactor 48.4→74.3 (+25.9), plugin-check 59.2→76.8 (+17.6), commit-change 69.6→83.5 (+13.9). 150% byte cap tight — trim aggressively.
+- **Context**: `/darwin-skill` run 2026-05-12, branch `auto-optimize/20260512-1319` merged to master, 5 commits. skills-perso (66.4→80.1, +13.7) NOT a dispatcher — different patch (Known-limits subsection on the heuristic).
+- **Future application**:
+  - Any darwin round-1 on a dispatcher SKILL.md → skip diagnosis, apply this template directly. Saves one eval cycle.
+  - After round 1, gains flatten near 75-80 → pivot to next-lowest skill, do not grind rounds 2-3 on same target.
+  - For thin originals (<500B), 150% cap is the binding constraint — pre-trim drafts before committing.
+- **Reference**: `.claude/audits/DARWIN-SKILL-2026-05-12.md`. Commits `512df48`..`134561d`. results.tsv at `~/.agents/skills/darwin-skill/results.tsv`.
+
+---
+
+## LRN-018 — Darwin eval subagents drift on total math — recompute in main thread
+
+- **Date**: 2026-05-12
+- **Pattern**: analyzer subagents asked to score SKILL.md and compute weighted total drift on the formula. Two recurring errors: (a) divide `Σ(dim×weight)` by `100` instead of `10` (off by factor 10 — produces 6.17 instead of 61.7, then sometimes the subagent silently re-multiplies); (b) use D8 weight 7 instead of the spec value 25 (status: spec says D8 weight = 25, easy to confuse with D4 weight = 7). Per-dim judgments themselves stable across runs; computed totals unreliable.
+- **Context**: 5 round-1 evals during darwin 2026-05-12. Refactor subagent computed 743÷10 correctly in scratch but wrote `617/100 = 61.7` — actual correct total 74.3. Subsequent prompts explicitly stating "D8 weight is 25" cleared the second error.
+- **Future application**:
+  - Prompt subagent for dim scores only, not weighted total. Main thread computes `Σ(dim_i × weight_i) / 10` deterministically.
+  - If subagent must compute, include weight table in prompt AND show example computation for one row.
+  - When comparing baseline vs round-N, use main-thread recomputed totals on BOTH sides, not the two subagents' self-reported numbers.
+  - Score recalibration between baseline subagent and round-1 subagent is real (independent re-anchoring) — first-round Δ tends to overstate improvement. Direction reliable, magnitude noisy.
+- **Reference**: see "Methodology notes" section of `.claude/audits/DARWIN-SKILL-2026-05-12.md`.
+
+---
+
+## LRN-019 — Deployable-project doc split: README dev, DEPLOY prod-VPS 14 sections
+
+- **Date**: 2026-05-15
+- **Pattern**: deployable project → split docs by audience, not by topic. README = dev + features audience (one-line pitch, Features, Stack, Quick start (dev), Verifying a change, Build & deploy summary, Documentation cross-links, License). DEPLOY.md = ops/SRE audience, prod-only, 14 sections mirroring real VPS-deploy shape (topology table, env vars, VPS provisioning, two-layer firewall = cloud security group + UFW, Docker tuning = log caps + `live-restore`, first-time setup, routine deploys, persistence/volumes, backups + cron + retention, TLS = Caddy/nginx + ACME, observability = logs + healthchecks, hardening = SSH keys-only + fail2ban + unattended-upgrades, rollback, runbook). Dev quick-start NEVER in DEPLOY.md — mixed dev/prod = drift source. Trivial deploy (no Docker, no compose, no fly.toml, no k8s, no scripts/deploy.*) → fold into README, skip DEPLOY.md.
+- **Context**: applied 2026-05-15 in `agents/doc-syncer.md` STEP 5/6 rewrite. Generalizes README-vs-DEPLOY ownership drift seen across multi-maintainer repos (devs read one doc, ops read another, both edit independently, conflicts pile up). 14-section template comes from real Scaleway DEV1-S walkthrough — shape works on any provider (Scaleway, Hetzner, OVH, DO, Vultr, plain bare-metal).
+- **Future application**:
+  - Any `/onboard` / `/doc` / `/init-project` producing docs for a deployable project → apply the split directly. Don't ask user "where should dev setup go" — README, always.
+  - Existing repo has DEPLOY.md with "Local development" / "Dev setup" section → flag as drift, propose moving content to README, removing section from DEPLOY in same patch round.
+  - Existing repo has README.md mixing prod topology details (firewall, TLS, backups) → flag as drift, propose moving to DEPLOY.md.
+  - 14-section template = ceiling not floor. Drop sections that don't apply (no DB → drop "Managed DB" section, no domain → drop TLS section). Don't pad to hit 14.
+  - Audience test before merging a doc section: "would a junior dev clone-and-run with this?" → README. "Would an on-call SRE provisioning a new VPS use this?" → DEPLOY. If both → split it.
+- **Reference**: commit `7ee9b42`, `agents/doc-syncer.md` STEP 5 (README template lines 223–335), STEP 6 (DEPLOY.md 14-section template lines 338–541). Linked to [[doc-syncer-readme-auto-deploy-prod]] (BDR-016).

+ 331 - 35
agents/doc-syncer.md

@@ -223,41 +223,113 @@ by STEP 5/6 if creation needed).
 
 If `README.md ∉ DOC_FILES`:
 
-README is mandatory. Propose creation using typical GitHub layout —
-include only sections relevant to detected `STACK` and
-`DEPLOY_COMPLEXITY`. Use real project data (manifest name,
-description, install/run commands). No placeholders.
-
-Proposed template (HUMAN approval required):
+**README is MANDATORY. Always create it — never gate on user approval.**
+A repo without a README is an immediate "this looks abandoned" signal
+to anyone landing on it. If the previous maintainer opted out (e.g.
+`CLAUDE.md` carries an "Exceptions: No README at scaffold" line),
+override that opt-out and strike through the exception in `CLAUDE.md`
+during patching.
+
+Render the template below using real project data only:
+- `<project-name>` ← manifest `name` (humanise: `nuit-folle` → `Nuit Folle`)
+- one-line description ← manifest `description`, else first paragraph
+  of CLAUDE.md project overview, else "Mobile-first / web / CLI / …
+  project. Replace this line with a concrete pitch." (clearly flagged
+  as a placeholder so the user replaces it)
+- feature bullets ← top-level entry points / routes / skills / CLI
+  commands discovered in the codebase (names + 1-line description each)
+- stack list ← `STACK` detected in STEP 2 with versions from manifest
+- install + run commands ← exact `npm scripts` / `pyproject.toml` /
+  `Cargo.toml` / `Makefile` targets (no invented commands)
+- documentation cross-links ← only existing or freshly-proposed files
+- license ← `LICENSE` file SPDX header if present, manifest `license`
+  field if present, else "Not specified — set one before public release"
+  (explicit gap, not a placeholder)
+
+The template includes a **"Quick start (dev)"** section that is the
+sole user-facing entry-point for local development. Production deploy
+guidance lives in `DEPLOY.md`; the README only links to it.
 
 ```markdown
-# <project-name>
+# <Project Name>
+
+<one-line description from manifest or CLAUDE.md project overview>
 
-<one-line description from manifest or git remote>
+---
 
 ## Features
-- <bullet from detected entry points / commands>
-- <bullet>
 
-## Quick Start
+- **<feature>** — <one-line>
+- **<feature>** — <one-line>
+(infer from entry points, routes, commands, top-level modules)
+
+## Stack
+
+- <Language> <version> (manifest)
+- <Framework> <version>
+- <Notable libs>
+- <Build tool / test runner / linter>
+
+## Quick start (dev)
+
+Single-process, no Docker — fastest path to a running app:
+
 \`\`\`bash
-<install command from detected stack>
-<run command from detected stack>
+<install command from manifest>
+<run command(s) from manifest>
 \`\`\`
 
+<If a docker-compose dev override exists:>
+Docker-compose dev — matches the production topology with hot reload:
+
+\`\`\`bash
+<dev compose command>
+\`\`\`
+
+<1-2 lines about local→backend wiring, defaults, common gotchas>
+
+For **production deployment** — provisioning, firewall, TLS, backups,
+hardening — see [DEPLOY.md](DEPLOY.md).
+
+## Verifying a change
+
+\`\`\`bash
+<typecheck command>     # only list those that actually exist in the manifest
+<lint command>
+<test command>
+\`\`\`
+
+<one-line baseline expectation, e.g. "X tests pass today">
+
+## Build & deploy
+
+<For each top-level build/deploy script in the manifest, one line.>
+<If DEPLOY_COMPLEXITY == NON_TRIVIAL: link to DEPLOY.md.>
+
 ## Documentation
-- [Install](INSTALL.md)            <!-- only if exists or proposed -->
-- [Configure](CONFIGURE.md)        <!-- only if exists or proposed -->
-- [Usage](USAGE.md)                <!-- only if exists or proposed -->
-- [Deploy](DEPLOY.md)              <!-- only if DEPLOY_COMPLEXITY == NON_TRIVIAL -->
-- [Contributing](CONTRIBUTING.md)  <!-- only if exists -->
-- [Changelog](CHANGELOG.md)        <!-- only if exists -->
-
-## License
-<from LICENSE file or manifest, else HUMAN>
+
+- [<root doc>](<root doc>)            (only if exists or proposed)
+- [CLAUDE.md](CLAUDE.md)               (only if exists)
+- [DEPLOY.md](DEPLOY.md)               (only if DEPLOY_COMPLEXITY == NON_TRIVIAL)
+- [Contributing](CONTRIBUTING.md)      (only if exists)
+- [Changelog](CHANGELOG.md)            (only if exists)
+
+## Project layout (top-level)
+
+\`\`\`
+<top-level directory tree, 1 line per dir, generated from `ls -d */`>
+\`\`\`
+
+## Status
+
+<Pre-1.0 / Beta / Stable — pulled from manifest `version` and a 1-line
+state line. Note the license situation explicitly if absent.>
 ```
 
-Tag overall as HUMAN — user validates before write.
+Tag as **AUTO** — create on first audit. Surface the rendered README in
+the validation gate before writing so the user can `edit` if needed,
+but do NOT skip creation; "skip" should not be an offered option on
+README bootstrap.
 
 ### STEP 6 — DEPLOY.md GATE
 
@@ -266,8 +338,204 @@ Tag overall as HUMAN — user validates before write.
 | `DEPLOY_COMPLEXITY == NONE` | Skip. Don't propose DEPLOY.md. |
 | `DEPLOY_COMPLEXITY == TRIVIAL` AND no DEPLOY.md | Skip. Suggest one-paragraph "Deploy" section in README. HUMAN. |
 | `DEPLOY_COMPLEXITY == TRIVIAL` AND DEPLOY.md exists | Suggest deletion or inlining into README. HUMAN. |
-| `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND no DEPLOY.md | Propose creation. HUMAN. Template based on detected artifacts (Docker → image build + run + env; fly.toml → `fly deploy` + secrets; workflows → branch trigger + manual approval; k8s → kubectl apply + namespace + rollout). |
-| `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND DEPLOY.md exists | Apply standard drift detection (STEP 3-4). |
+| `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND no DEPLOY.md | Propose creation using the full prod-only template below. HUMAN approval. |
+| `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND DEPLOY.md exists | Apply standard drift detection (STEP 3-4). Verify the existing file covers the 14 sections below; surface missing sections as drift items. |
+
+**DEPLOY.md is PROD-ONLY.** Dev quick-start lives in README.md
+("Quick start (dev)" section); DEPLOY.md never duplicates it. If the
+existing DEPLOY.md contains a "Local development" / "Dev setup" /
+similar section, flag it as drift and propose moving its content into
+README.md while removing the section from DEPLOY.md.
+
+#### DEPLOY.md template — 14 sections (NON_TRIVIAL)
+
+Mirror the conventional VPS-deploy structure (reference: a Scaleway
+DEV1-S walkthrough; the same shape works on any provider). Drop
+sections that don't apply (e.g. "Managed DB" if the app has no DB).
+Each section uses real project data (env vars from `.env.example` or
+`.env`, container names from `docker-compose.yml`, scripts from
+`scripts/`, ports from `Dockerfile EXPOSE` / `compose ports`).
+
+```markdown
+# Deploy
+
+<1-paragraph topology summary: containers, host TLS terminator,
+public ingress, internal hops.>
+
+---
+
+## What gets deployed
+
+| Service | Image source | Port (host) | Role |
+| ... | ... | ... | ... |
+
+<Add a note on which ports are publicly bound vs loopback-only.>
+
+---
+
+## Required environment
+
+<Table of env vars expected on the VPS in `.env` — secrets, rate limits,
+provider keys, CORS origin, web-port override, build-time frontend URL.
+Pull names from the actual code (server.js, lib/api.ts, etc.).>
+
+---
+
+## Provision the VPS
+
+<Specs table (CPU/RAM/disk/OS recommended minimums). DNS A record.
+SSH key. Baseline apt-get / pkg packages (git, curl, ufw, fail2ban,
+ca-certificates). Optional cloud-provider CLI shortcut.>
+
+---
+
+## Firewall (two layers)
+
+### Layer 1 — cloud provider security group
+<Allow-list table: SSH from your IP, 80, 443 from anywhere; deny rest.
+Cheats per provider (Scaleway / Hetzner / OVH / DO / Vultr).>
+
+### Layer 2 — UFW on the VM
+<`ufw default deny incoming` + allow 22/80/443 + enable.>
+
+---
+
+## Install Docker (production-tuned)
+
+<`curl get.docker.com | sh`. `/etc/docker/daemon.json` with
+`json-file` log driver capped (max-size + max-file) and
+`live-restore: true`. Enable + restart.>
+
+---
+
+## First-time VPS setup
+
+<Clone, .env, `compose up --build -d`, loopback sanity curl. Assumes
+the prep chapters above are done; keep this short.>
+
+---
+
+## Routine deploys
+
+<`npm run deploy` / `bash scripts/deploy.sh` flow + manual VPS-side
+fallback (git fetch + reset + compose up).>
+
+---
+
+## Data persistence
+
+<Which volumes are mounted (named or bind), what files live there,
+backup recipe pointer to next section.>
+
+---
+
+## Backups (cron + retention)
+
+### One-shot script
+<`/opt/backup-<project>.sh` — `docker cp` volume contents, tar+gzip,
+rotation by mtime, log file.>
+
+### Cron
+<crontab line, daily 03:00–04:00, log path.>
+
+### Off-VPS storage (optional but recommended)
+<rsync + S3-compatible push.>
+
+### Restore
+<compose stop + docker cp + compose start, with verification curl.>
+
+---
+
+## Behind a domain + TLS reverse proxy
+
+### Option A — host nginx + Certbot
+<DNS + UFW + nginx server block + `certbot --nginx` + timer status.>
+
+#### Security headers (Option A only)
+<HSTS w/ preload, X-Content-Type-Options nosniff, X-Frame-Options DENY,
+Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy
+locked-down, CSP minimal-but-framework-compatible. Verify via curl +
+securityheaders.com / ssllabs.com.>
+
+### Option B — Caddy (auto-TLS, single file)
+<apt + Caddyfile snippet.>
+
+### Backend CORS
+<env var name + restart procedure + cross-origin curl to verify lockdown.>
+
+### Frontend API base URL
+<Only if the frontend has a build-time API URL var. Document the value
+to set (empty string for same-origin or full URL for split-host) and
+the seam (Dockerfile ARG + compose build-args).>
+
+### Sanity checks
+<TLS redirect curl, healthcheck curls, `nc -zv <vps-ip> <port>` to
+confirm internal ports are NOT publicly bound.>
+
+---
+
+## Post-deploy hardening
+
+### 1. Non-root deploy user
+<adduser + usermod -aG docker + ssh key copy + sudo NOPASSWD.>
+
+### 2. Disable root + password SSH
+<`sshd_config`: PermitRootLogin prohibit-password, PasswordAuthentication no.>
+
+### 3. (Optional) Move SSH off port 22
+<port change order: open new in UFW + cloud SG BEFORE removing 22.>
+
+### 4. Unattended security upgrades
+<apt-get install unattended-upgrades + dpkg-reconfigure.>
+
+### 5. fail2ban
+<systemctl enable + status verification.>
+
+### 6. Final lockdown check
+<nmap from outside, password-SSH attempt expected rejected.>
+
+---
+
+## Rollback
+
+<git reset to known-good SHA + compose up --build + restore data if
+the bad deploy corrupted state.>
+
+---
+
+## Health checks
+
+<URL → expected response table, hit on the public hostname behind TLS
+or on `127.0.0.1:<WEB_PORT>` if no reverse proxy yet.>
+
+---
+
+## Troubleshooting
+
+<9–10 common failures, each as a sub-section with a diagnosis recipe:
+- container won't start
+- 5xx from the API
+- CORS rejected in browser
+- 502 bad gateway from host nginx
+- SSL renewal failed
+- volume / data unexpectedly empty
+- disk full
+- restart loop
+- container log explosion>
+
+---
+
+## Operational notes
+
+<Log destinations, log volume cap reminder, manual prune commands,
+key-rotation procedure, anything provider-specific.>
+```
+
+If `DEPLOY_COMPLEXITY == NON_TRIVIAL` AND a DEPLOY.md already exists
+but is missing 3+ of these 14 sections, surface each missing section
+as a separate `[HUMAN]` drift item in STEP 7 with a 1-line description
+of what the section should cover for this project. Do not patch them
+automatically — production deploy guidance is judgement-heavy.
 
 ### STEP 7 — REPORT
 
@@ -320,8 +588,11 @@ Last updated: <date> (<N commits since>)
 - `[REMOVED]` — feature in docs, not in code. AUTO for list entry
   to delete, HUMAN if needs deprecation note.
 
-CHANGELOG entries always HUMAN. README/DEPLOY creation always
-HUMAN.
+CHANGELOG entries always HUMAN. DEPLOY.md creation always HUMAN.
+**README.md creation is AUTO** — always render and write, never gate
+on user input. The validation gate (STEP 8) still surfaces the
+rendered file so the user can edit before write, but "skip" is not an
+option for README bootstrap; it is mandatory.
 
 If no drift in any doc and no missing required doc:
 `DOC SYNC: all docs current` and stop.
@@ -332,13 +603,22 @@ If no drift in any doc and no missing required doc:
 DOC SYNC — VALIDATION GATE
 AUTO items   : <count> (Claude will patch these)
 HUMAN items  : <count> (listed above for review)
-CREATE items : <count> (README/DEPLOY proposals)
+CREATE items : <count>
+  - README.md     (AUTO — will be written; `edit` to refine the rendered draft)
+  - DEPLOY.md     (HUMAN — approve before write)
+  - …
 REMOVE items : <count>
 
-Apply AUTO patches?      (yes / select items / cancel)
-Apply HUMAN/CREATE items? (per-item: yes / no / edit)
+Apply AUTO patches?              (yes / select items / cancel)
+Apply HUMAN items?               (per-item: yes / no / edit)
+Apply CREATE items?              (per-item: yes / edit / no — README has no `no`)
 ```
 
+README.md CREATE is unconditional: the only valid responses are `yes`
+(write the rendered draft as-is) or `edit` (revise the draft, then
+write). Treat any `no` / `skip` answer to README as `edit` and prompt
+the user for the specific changes they want.
+
 Wait for explicit approval. Do not proceed without it.
 
 ### STEP 9 — PATCH
@@ -391,6 +671,13 @@ Map modified files to relevant docs:
 
 If no relevant docs exist for changed files → exit silently.
 
+**Exception — README absence**: in AUTO MODE, if README.md is missing
+AND any code/config file was modified this session, treat it as a
+SIGNIFICANT item in STEP A4 and surface a "README missing — propose
+creation" line with the rendered draft (per STEP 5 template). Auto
+mode does NOT auto-write CREATE items; the rendered draft is shown so
+the user can approve in one step at end-of-session.
+
 ### STEP A3 — QUICK DRIFT CHECK
 
 For each relevant doc, read it and check only sections affected
@@ -429,12 +716,21 @@ Categorize:
 ## RULES
 - Never invent content. Only sync what changed in code.
 - Never fabricate examples, feature descriptions, explanations.
-- Doc creation (README, DEPLOY) requires HUMAN approval and uses
-  real project data only.
+- README.md creation is **AUTO and unconditional** — always created
+  when missing, using real project data only (no placeholders, no
+  fabricated content). The validation gate surfaces the rendered file
+  for editing but never offers a "skip" option for README bootstrap.
+  Strike through any project-level "no README" opt-out (e.g. in
+  CLAUDE.md "Exceptions to global rules") during the same patch.
+- DEPLOY.md creation requires HUMAN approval and uses real project
+  data only. Produced only when `DEPLOY_COMPLEXITY == NON_TRIVIAL`,
+  following the 14-section template in STEP 6. Trivial deploy belongs
+  in README.
+- DEPLOY.md is **PROD-ONLY**. Dev quick-start lives in README under a
+  "Quick start (dev)" section. If an existing DEPLOY.md mixes dev and
+  prod, surface the dev section as drift and propose moving it to
+  README during the same patch round.
 - Doc list is dynamic — auto-detect, never assume fixed set.
-- DEPLOY.md only when `DEPLOY_COMPLEXITY == NON_TRIVIAL`. Trivial
-  deploy belongs in README.
-- README always required. Bootstrap if missing.
 - CHANGELOG entries: always propose, never auto-write.
 - Inline comment updates: only for files in scope, only when
   signature actually changed.

+ 1 - 1
settings.json

@@ -237,7 +237,7 @@
   },
   "enabledPlugins": {
     "example-skills@anthropic-agent-skills": false,
-    "ui-ux-pro-max@ui-ux-pro-max-skill": false,
+    "ui-ux-pro-max@ui-ux-pro-max-skill": true,
     "caveman@caveman": true,
     "security-guidance@claude-code-plugins": true,
     "superpowers@superpowers-marketplace": true,

+ 5 - 0
skills/close/test-prompts.json

@@ -0,0 +1,5 @@
+[
+  {"id": 1, "prompt": "ferme la session", "expected": "Skill runs PRECHECK on .claude/memory/, gathers git log + diff + status, presents the 3-question ritual (decided/learned/blocked) with pre-filled drafts from conversation context, waits for approval, then appends approved entries (English, caveman) to decisions.md/learnings.md/blockers.md plus one journal line."},
+  {"id": 2, "prompt": "close — retro rapide avant que je parte", "expected": "Same 3-question ritual; if a registry has nothing notable to log, skill emits '(rien à logger cette session)' for that question and still writes the journal timeline line under today's date heading."},
+  {"id": 3, "prompt": "checkpoint memory — but .claude/memory/ doesn't exist in this repo", "expected": "PRECHECK detects missing .claude/memory/, STOPS with the warning telling user to run /onboard or /init-project first — does NOT create the directory itself."}
+]

+ 6 - 3
skills/commit-change/SKILL.md

@@ -18,9 +18,12 @@ allowed-tools:
   - AskUserQuestion
 ---
 
-Load and follow strictly:
-- $HOME/.claude/agents/commit-changer.md
+Load and follow strictly: `$HOME/.claude/agents/commit-changer.md`.
 
-Execute the COMMIT-CHANGER agent on the current working directory.
+If unreachable, emit `Commit-changer agent missing.` and STOP. Never auto-commit blind — a wrong group is harder to undo than not committing.
+
+Pre-flight checks (the agent should also perform, but flag here):
+- Detached HEAD or unmerged conflicts → STOP, report state.
+- Identity unconfigured (`git config user.email` empty) → STOP, ask user.
 
 $ARGUMENTS

+ 5 - 0
skills/graphify/test-prompts.json

@@ -0,0 +1,5 @@
+[
+  {"id": 1, "prompt": "/graphify .", "expected": "Skill runs full pipeline on CWD: ensures graphify python installed, detects files into categories (code/docs/papers/images/video), shows clean corpus summary, dispatches AST + parallel semantic subagents (general-purpose, NOT Explore), merges chunks, builds graph + communities, writes graph.json + GRAPH_REPORT.md + interactive HTML in graphify-out/."},
+  {"id": 2, "prompt": "how does AuthModule relate to the Database layer in this codebase?", "expected": "Skill recognizes a cross-module architecture question on a graphified project — runs `graphify path 'AuthModule' 'Database'` (or `graphify query` if path is too literal) to traverse EXTRACTED + INFERRED edges instead of grepping files, then narrates the connection."},
+  {"id": 3, "prompt": "/graphify https://github.com/anthropics/anthropic-sdk-python https://github.com/openai/openai-python", "expected": "Skill executes Step 0 multi-repo flow: `graphify clone` each URL into ~/.graphify/repos/<owner>/<repo>, runs the pipeline on each, then `graphify merge-graphs` into a single cross-repo-graph.json with `repo` attribute on each node."}
+]

+ 5 - 0
skills/harden/test-prompts.json

@@ -0,0 +1,5 @@
+[
+  {"id": 1, "prompt": "/harden https://example.com --full", "expected": "Skill runs FULL-mode hardening audit: parses URL+domain, detects framework configs (.htaccess/nginx.conf/next.config.js/etc.), launches external validators in parallel (Mozilla Observatory + SecurityHeaders.com + SSL Labs async), dispatches seo-analyzer with STRICT narrow scope (transport/HSTS/CSP/headers/canonical/404/server-config ONLY), polls SSL Labs, writes .claude/audits/HARDEN.md with score + external grades + top-3 actions."},
+  {"id": 2, "prompt": "audit sécurité web sur ce repo, mais en local — pas d'appels externes", "expected": "Skill defaults DEPTH=LOCAL (no URL), auto-skips Step 0b external validators (EXTERNAL forced off in LOCAL), dispatches seo-analyzer with narrow scope on detected config files only, produces .claude/audits/HARDEN.md without the External validators section."},
+  {"id": 3, "prompt": "/harden https://example.com — and check my meta tags + sitemap too", "expected": "Skill respects scope boundary: silently DROPS the meta-tags/sitemap request (those are /seo's territory), runs ONLY the 6 in-scope hardening areas, and ideally points the user to /seo for the dropped concerns — does NOT mix scopes."}
+]

+ 5 - 5
skills/plugin-check/SKILL.md

@@ -1,15 +1,15 @@
 ---
 name: plugin-check
-description: Audit active plugins vs project needs. Recommends enable/disable actions.
+description: Audit active plugins vs project needs. Read-only advisory recommending enable/disable. Triggers: "plugin-check", "quels plugins".
 argument-hint: [ex: "React + FastAPI" or "Rust CLI, no frontend"]
 disable-model-invocation: true
 allowed-tools: Read, Bash, Glob, Grep
 ---
 
-Load and follow strictly:
-- $HOME/.claude/agents/plugin-advisor.md
+Load and follow strictly: `$HOME/.claude/agents/plugin-advisor.md`.
 
-Analyze active plugins and the following context,
-then produce the full PLUGIN ADVISOR REPORT:
+Analyze active plugins + context below, produce PLUGIN ADVISOR REPORT.
+
+If `$HOME/.claude/agents/plugin-advisor.md` unreachable: emit `Plugin advisor agent missing.` and STOP. Never write — user toggles via `claude plugin enable/disable`.
 
 $ARGUMENTS

+ 5 - 0
skills/profile/test-prompts.json

@@ -0,0 +1,5 @@
+[
+  {"id": 1, "prompt": "profile list", "expected": "Skill runs `bash $HOME/.claude/lib/profile.sh list` and prints the table of available profiles (web, seo, web-full, backend, design, dev, qa, audit, minimal) without extra commentary."},
+  {"id": 2, "prompt": "active les skills design — désactive le bruit gstack", "expected": "Skill interprets this as `set design` (destructive — disables non-listed gstack skills), confirms first since `set` is destructive, then runs `bash $HOME/.claude/lib/profile.sh set design` and reports the count of skills moved plus the reminder to start a new Claude session to pick up changes."},
+  {"id": 3, "prompt": "quel profil est actif?", "expected": "Skill runs `bash $HOME/.claude/lib/profile.sh current` and reports the detected active profile with its match percentage; does NOT toggle any symlinks."}
+]

+ 5 - 0
skills/prune-memory/test-prompts.json

@@ -0,0 +1,5 @@
+[
+  {"id": 1, "prompt": "prune memory — registres trop longs", "expected": "Skill runs PRECHECK (refuses if working tree dirty on .claude/memory/), audits all 5 registries for A) obsolete/superseded entries B) similar merge candidates C) bloated prose D) Index drift, presents the per-registry PRUNE PLAN with category-level approval gate, applies only approved changes (mark-superseded never hard-delete), then runs Index sanity verify at STEP 4."},
+  {"id": 2, "prompt": "/prune-memory decisions", "expected": "Skill filters audit to decisions.md only — leaves learnings/blockers/journal/evals untouched, presents plan for that single registry, and exits cleanly after applying approved changes with the same append-only + caveman rules."},
+  {"id": 3, "prompt": "compresse les memoires — mais j'ai des changements pas commités dans .claude/memory/", "expected": "STEP 0 PRECHECK detects dirty working tree on registry files and STOPS immediately: 'Commit or stash pending changes in .claude/memory/ first. Skill writes in-place. Git is the only backup.' — no writes, no plan."}
+]

+ 3 - 4
skills/refactor/SKILL.md

@@ -1,14 +1,13 @@
 ---
 name: refactor
-description: Improve code quality without changing behavior — strict norm enforcement
+description: Improve code quality without changing behavior — strict norm enforcement. Triggers: "refactor", "clean up code", "normaliser".
 argument-hint: <file, function, or module to refactor>
 disable-model-invocation: true
 allowed-tools: Read, Write, Edit, Grep, Glob, Bash
 ---
 
-Load and follow strictly:
-- $HOME/.claude/agents/refactorer.md
+Load and follow strictly: `$HOME/.claude/agents/refactorer.md`.
 
-Execute the REFACTORER agent on the following target:
+If unreachable, emit `Refactorer agent missing.` and STOP. Never improvise — silent behavior change is unsafe.
 
 $ARGUMENTS

+ 17 - 0
skills/skills-perso/SKILL.md

@@ -99,3 +99,20 @@ fi
 ```
 
 Keep descriptions to one line (~80 chars max, truncate with "..." if needed).
+
+## Known limits of the detection heuristic
+
+- **False positive (rare):** agent references buried in fenced code blocks
+  (` ``` ... ``` `) match Signal 2 even though they are not active delegations.
+  Mitigation: skill author adds `owner: user` (Signal 1) — explicit always wins.
+- **False negative:** personal skills that delegate to agents under non-standard
+  paths (e.g. `~/.config/myagents/`, `agents-shared/`) won't match Signal 2.
+  Mitigation: same — add `owner: user` to frontmatter.
+- **Frontmatter malformed / missing:** `is_personal()` returns false (skill
+  silently excluded). The "0 personal skills detected" diagnostic catches the
+  zero case but not partial misses.
+- **Description extract edge cases:** plain multi-line YAML (no `|`/`>`) is
+  read as first line only. For users of `description: |` block scalars this is
+  intended; otherwise inspect raw `SKILL.md` if a description looks truncated.
+- **Override:** to force-include a framework skill, fork it into `~/.claude/skills/`
+  and add `owner: user`. The fork is then yours to maintain.

+ 9 - 2
skills/status/SKILL.md

@@ -1,14 +1,21 @@
 ---
 name: status
-description: Consolidated project snapshot — plugins active, token cost, git state, recent commits, GSD v2 milestone progress. Read-only. Run at session start or after a break.
+description: Consolidated project snapshot — plugins, token cost, git state, recent commits, GSD v2 milestone progress. Read-only. Run at session start or after a break. Triggers: "status", "sitrep", "where are we", "project state", "after break".
 argument-hint: (no arguments needed)
 disable-model-invocation: true
 allowed-tools: Read, Bash, Glob, Grep
 ---
 
 Load and follow strictly:
-- $HOME/.claude/agents/status-reporter.md
+- `$HOME/.claude/agents/status-reporter.md`
 
 Produce the full PROJECT STATUS report for the current working directory.
 
+## Fallback when agent file missing
+
+If `$HOME/.claude/agents/status-reporter.md` is unreachable (deleted, permission denied, broken symlink):
+
+1. Emit: `Status agent missing — restore ~/.claude/agents/status-reporter.md.`
+2. STOP. Do not improvise a manual report — partial snapshots mislead.
+
 $ARGUMENTS