Compare commits

...

27 Commits

Author SHA1 Message Date
Bastien Chanot
c816b11bc4 Merge chore/ecc-audit-bdr into develop 2026-07-01 22:55:08 +02:00
Bastien Chanot
d2df514126 chore(memory): BDR-047 — ECC audit → zero import, config ahead of reference 2026-07-01 22:52:06 +02:00
Bastien Chanot
d0ec54ee61 Merge chore/reconcile-todo-drift into develop 2026-07-01 21:18:23 +02:00
Bastien Chanot
caf3d01487 Merge bugfix/install-plugins-npm-guard into develop 2026-07-01 21:18:22 +02:00
Bastien Chanot
90dc7d854d chore(memory): capitalize reconcile session + (a) npm-guard fix
Session capture for the /reconcile pass + the BLK-013 fix-forward build:

- journal 2026-07-01: reconcile real-state (1 actionable / 3 upstream /
  3 deferred / release live), (c) TODO drift, (a) npm guard built.
- BLK-013: append Update — fix-forward now BUILT (1f2c1cc); was
  "script hardening NOT built". Now fully resolved (env + script).
- BLK-014 + BDR-046: append Update — MERGED 2393ca5, supersedes the
  stale "pending merge". Records that BDR-046 already settled the
  "canal d'install" question (native installer, no `elif npm` branch).

Append-only (Update blocks, last-block-wins) — no past entry rewritten;
verified reconcile_blk_open now returns only the true upstream trio.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBXkDr74N9whdiJyjzyVN
2026-07-01 21:18:16 +02:00
Bastien Chanot
1f2c1cc6e7 fix(install-plugins): guarantee npm present, not just node>=22
BLK-013 fix-forward. Step 1 checked `node >=22` but never verified npm.
On a host where node was already recent, NODE_OK short-circuited the
installer and npm was never touched — yet GSD (gsd-pi) and ctx7 install
via `npm install -g`, so a missing npm made `make plugin` die Error 127
mid-run (distro `apt install nodejs` can ship npm as a separate package).

Add an unconditional npm guard right after the Node block:
corepack enable npm → distro package-manager install fallback → fatal
exit 1 with an actionable message if still absent. Happy path (npm
present) skips the whole block: zero behavior change on healthy machines.

shellcheck clean (only pre-existing SC1091 infos), bash -n OK. Fresh
npm-less apt host validation still pending. Closes TODO (a) 2026-06-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBXkDr74N9whdiJyjzyVN
2026-07-01 21:07:38 +02:00
Bastien Chanot
9c024064bb chore(todo): reconcile --help chantier drift — 7 subtasks [ ]→[-]
/reconcile show-only surfaced 7 open [ ] boxes under the
`## Helper --help` section headed [WON'T-BUILD 2026-06-30]. The chantier
was killed (BDR-001 won't-build, measured non-rentable) but the build
subtasks stayed unchecked → naive `grep '[ ]'` counted them as open work.

Mark them [-] (cancelled) so declared state matches reality. The 
WON'T-BUILD prose already frames them as "historique, non actionnables".
Naive open-count 10→3; survivors are genuine deferred-open (context-file
2e passage, zenquality cross-repo, install-plugins npm harden).

Registries left untouched (reconcile is read-only there; BLK-014/BDR-046
"pending merge" staleness is a /prune-memory concern, not this).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeBXkDr74N9whdiJyjzyVN
2026-07-01 20:51:15 +02:00
Bastien Chanot
2393ca536c Merge bugfix/install-claude-idempotent into develop 2026-07-01 20:20:00 +02:00
Bastien Chanot
020737de57 chore(memory): BDR-046 — Claude Code via official native installer, drop npm
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 20:14:56 +02:00
Bastien Chanot
6be627e246 fix(install): install Claude Code via official native installer, not npm
Uniformizes point 1: install.sh fresh-machine branch used npm, but npm
is no longer a documented Claude Code channel (official quickstart lists
Native/Homebrew/WinGet/apt only) and collides with the native symlink.
Switch the fresh-install path to the recommended native installer,
matching install-plugins.sh which already points to the native channel.

- install.sh: fresh install via `curl -fsSL https://claude.ai/install.sh
  | bash`; ensure ~/.local/bin on PATH for the auth/verify steps.
- skip-if-present guard unchanged.
- fix stale node/npm prerequisite comment (npm now serves the plugins
  step, not the Claude Code install).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 16:33:02 +02:00
Bastien Chanot
01f9ebb57b chore(memory): BLK-014 + LRN-085 — install.sh idempotent claude install/update
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 16:10:59 +02:00
Bastien Chanot
8dc4027c4b fix(install): make Claude Code install/update idempotent across channels
install.sh aborted with npm EEXIST when claude was already present:
the binary is a native-installer symlink (~/.local/bin/claude ->
~/.local/share/claude/versions/*) that npm does not own, and the
npm prefix (~/.local, set for BLK-013) targets the same path. The
`else err` branch turned EEXIST into a fatal exit. No presence guard
existed, unlike the RTK/GSD steps.

- install.sh: skip-if-present guard (command -v claude), mirroring
  the RTK/GSD pattern; npm only runs on a truly fresh machine.
- update-all.sh: pick updater by channel — npm for npm-managed
  installs, `claude update` for native installs (npm would EEXIST).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 16:07:13 +02:00
Bastien Chanot
2d76233b02 Merge feature/doc-sync into develop 2026-07-01 14:31:38 +02:00
Bastien Chanot
8ca1bb7bab docs: +/gitflow /release-candidate /deploy /reconcile /pdf-translate
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNaYKPEkjH1jbgoX1TwKMX
2026-07-01 14:31:38 +02:00
Bastien Chanot
0a2e832a66 Merge feature/gitflow-aiguillage-standalone into develop 2026-07-01 14:28:10 +02:00
Bastien Chanot
8f001ec868 chore(memory): BDR-045 + LRN-084 + LRN-034 corrob — capitalize gitflow aiguillage-standalone
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNaYKPEkjH1jbgoX1TwKMX
2026-07-01 14:04:15 +02:00
Bastien Chanot
e8807a7333 feat(gitflow): chore branch type + aiguillage for standalone memory/doc skills
Standalone /capitalize /close /prune-memory /reconcile no longer lean on the .claude/** hook exemption when run on main/develop: the aiguillage branches them to chore/* off develop before writing. New chore type (base develop, finish->develop) added to the lib; hook unchanged (chore/* non-protected). Closes the leak where standalone memory work (memory IS the work, no code branch to follow) landed direct on a protected base. 64/64 gitflow-test green, shellcheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNaYKPEkjH1jbgoX1TwKMX
2026-07-01 13:25:36 +02:00
Bastien Chanot
53bd7beee8 chore(memory): BDR-044 + LRN-083 + auto-skill-dispatch won't-build — capitalize
BDR-044: auto-skill-dispatch chantier retired won't-build — 3rd measured moot
of the session (after --help, darwin re-baseline). Cartography showed L1
(superpowers "1%->MUST invoke") already over-determines routing -> reframed
from "does it route" (yes) to DISCERNMENT; risk inverted under->over. Measured
in real fresh sessions (8 prompts/3 classes): clear->route, ambiguous->ask,
trivial->abstain — model discriminates, no over-routing. Adding L2 prose =
phantom value + degradation risk. LRN-083: subagents are an invalid instrument
for measuring main-loop spontaneous routing (SUBAGENT-STOP + delegated framing
pin to the no-route floor) — retired the 0/6 subagent RED. LRN-080 corroborated
(3-in-a-row). TODO -> won't-build. Claude composed all -> trailers (4th
application of LRN-081).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KWG7sXg94LXX1gddCGBvM
2026-06-30 20:04:30 +02:00
Bastien Chanot
efe33b76c5 chore(memory): LRN-081 correction — helper is trailer-agnostic
Append-only correction bullet to LRN-081: memory-commit.sh does NOT append
trailers (git commit -m verbatim, memory-commit.sh:86, no hook/template);
trailers are model-composed message content; control point = the MESSAGE, not
the helper. Proven by 532ae69 (bare msg → no trailers) → c09f2b2 (amended).
Phrasing cleanup of the false wording (body + Index cell) deferred to
/prune-memory. Claude-composed → trailers (LRN-081 rule, 3rd application).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KWG7sXg94LXX1gddCGBvM
2026-06-30 18:43:54 +02:00
Bastien Chanot
c09f2b2630 chore(memory): LRN-082 + TODO(b) moot — capitalize
LRN-082: a trigger-cleared on a multi-motif exclusion lifts only the named
motif. BDR-043 cleared BDR-015's broken-symlink ground (a) but not its
external-ownership ground (b) → the darwin re-baseline is phantom value
(would edit the gstack submodule, LRN-070; results.tsv gone anyway). TODO (b)
resolved-MOOT (not done, not open). Trailers present: Claude composed LRN-082
+ the moot note — LRN-081's own rule, 2nd application.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KWG7sXg94LXX1gddCGBvM
2026-06-30 18:38:50 +02:00
Bastien Chanot
5d348a711f chore(memory): LRN-081 + TODO reconcile — close ritual
LRN-081: Claude commit trailers only on Claude-COMPOSED content; a commit merely staging user-authored text gets none (staging != authorship). TODO reconcile: checked L26 'Cleanup machine courante' DONE (make plugin EXIT=0 this session ran Step 8.5, fs-verified strays absent); added (a) harden install-plugins.sh Step 1 npm-via-corepack (BLK-013 fix-forward) + (b) darwin re-baseline of the 5 ex-broken skills (BDR-043). Trailers present here because Claude composed the LRN + TODO formulations (LRN-081's own rule) — unlike e591510 which staged raw user text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6bUdvHnajCNzgVQefZowj
2026-06-30 18:08:12 +02:00
Bastien Chanot
437697e961 chore(memory): EVAL-013 — /reconcile real-usage value proven (usage vs build)
Capitalize the /reconcile dogfood on fresh live drift. Distinct from EVAL-011
(BUILD: fixture RED/GREEN + self-dogfood) — EVAL-013 = USAGE on real repo,
proving 2 things the build eval did not: (a) finds UNANTICIPATED gaps (3 stale
[branch …] headers = header-marker drift class beyond checkbox drift), (b) rejects
a FALSE POSITIVE off-fixture (--help candidate, both WON'T-BUILD → aligned).
'this run' wording kept — value proven, not zero-false-positive guaranteed
(consistent with the skill's engraved honest-limits). action keep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KWG7sXg94LXX1gddCGBvM
2026-06-30 17:49:01 +02:00
Bastien Chanot
09200c5274 chore(memory): reconcile TODO — /release-candidate QUEUED→SHIPPED + 3 [branch] headers→DONE
/reconcile dogfood on a fresh declared↔real gap. Oracle-proven requalifications:
- /release-candidate: QUEUED→SHIPPED (SKILL.md d3d6ced, merged 0c0b748, released
  v4.0.0/tag v4.0.0); 4 subtasks [ ]→[x] (tag/SKILL.md/routing/test=real 4.0.0 fan-out).
- 3 stale [branch …] headers (minor-gate, blk-011-gsd, prune-memory-hardening)
  →[DONE]: all merged to develop + branches deleted (merge_done=YES).
Bodies left intact (historical 'why'). Registries untouched (read-only per skill).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KWG7sXg94LXX1gddCGBvM
2026-06-30 17:43:22 +02:00
Bastien Chanot
e591510160 chore(todo): queue auto-skill-dispatch chantier (NEXT, measure-first)
Append the "Auto-déclenchement des skills par intention" chantier to TODO.md as NEXT — measure-first (twin of BDR-001 --help): behavioral RED before any design, scope bounded to clear/unambiguous intent signals. Design opens only if the RED proves value.
2026-06-30 17:20:26 +02:00
Bastien Chanot
5b03ac28a2 chore(memory): BLK-013 + BDR-043 — capitalize (make-plugin npm blocker + BDR-015 darwin re-baseline requalif)
Capitalized from 2 code vérifs (subagents, no-memory) + the make plugin fix:
- BLK-013: make plugin Error 127 — apt `nodejs` ships node WITHOUT npm; Step 1
  checks node>=22 but never npm. Fixed via corepack (npm 11.18.0 → ~/.local/bin,
  prefix ~/.local), EXIT=0, Step 4 ✓, Step 8.5 stray-dir residual cleanup
  (BDR-030/LRN-042) finally ran. Fix-forward: Step 1 should guarantee npm via
  corepack on apt-nodejs hosts.
- BDR-043: BDR-015 trigger cleared — its 5 broken gstack symlinks repaired
  (0 broken / 83 today, gstack now ships those skills); darwin re-baseline
  UNBLOCKED, NOT run. Kept distinct from BLK-007/f928a53 (iOS episode).
- ③ doc-commit branch-guard requalif DROPPED (already graved BDR-040/TODO:292);
  only the new whitelist-replication nuance logged in journal.

TODO.md planning note left uncommitted (user's WIP, separate scope).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6bUdvHnajCNzgVQefZowj
2026-06-30 17:08:06 +02:00
Bastien Chanot
c3ba540372 chore(memory): BDR-001 won't-build + LRN-080 + TODO requalify (--help measured non-rentable)
--help chantier ABANDONED after measurement (not built — nothing to build):
- BDR-001 append (won't-build 2026-06-30): behavioral RED, 6 reps (/web-validate
  + /harden, no instruction) → 6/6 already render help AND stop without dispatch;
  residual value = format consistency only → ROI insufficient on a solo repo.
  Original Decision/Why/Rejected intact (append-only); Index status cell updated.
- LRN-080: measure if the model already does X before adding an instruction to
  make it do X — the behavioral RED kills phantom-value additions. Links LRN-075.
- TODO: chantier requalified WON'T-BUILD (3rd state — not done, not open).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6bUdvHnajCNzgVQefZowj
2026-06-30 16:27:04 +02:00
Bastien Chanot
4a00a60494 Merge release/4.0.0 into develop 2026-06-30 15:33:23 +02:00
20 changed files with 435 additions and 53 deletions

View File

@ -32,6 +32,8 @@ rules:
| BLK-010 | 2026-06-27 | init-project: scaffold (STEP 5) + bootstrap README (5b) have no deterministic commit owner; worktree `add -b` on unborn HEAD | resolved (uncommitted) |
| BLK-011 | 2026-06-27 | init-project STEP 13 GSD post-FINISH creates ROADMAP.md → stranded doc (3rd post-FINISH artifact) | resolved (STEP 12 removed) |
| BLK-012 | 2026-06-29 | gitflow_init half-applied: socle-commit failure swallowed → hook activated on partial run → re-run self-blocks | resolved |
| BLK-013 | 2026-06-30 | `make plugin` Error 127 — npm absent on apt-`nodejs` host (Step 4 gsd-pi aborts, Steps 5-10 + residual cleanup never run) | resolved (env) |
| BLK-014 | 2026-07-01 | `make install` aborts npm EEXIST on `~/.local/bin/claude` when claude already installed via native installer — no presence guard | resolved |
---
@ -154,3 +156,26 @@ rules:
- **Solution**: (1) socle commit FATAL in `_gitflow_init_existing``if ! git diff --cached --quiet; then git commit … || { echo …; return 1; }; fi` → aborts BEFORE develop/hook-activation; (2) identity precheck at top of `gitflow_init` (fail loud, no half-apply); (3) identity guard in `gitflow-migrate.sh:migrate_local`. Recovery: set faunosteo local identity → deactivate hook → delete premature develop → reinit (socle commits with hook inactive, as designed) → main==develop @ socle, tree clean, master renamed. Verified: shellcheck clean, 57/57 tests pass, hardened init on an identity-less repo aborts rc1 with ZERO mutation.
- **Status**: resolved (`lib/gitflow.sh` + `lib/gitflow-migrate.sh`, uncommitted working tree as of the gitflow chantier).
- **Reference**: [[LRN-068]] (transactional-bootstrap principle). Discovered mid gitflow-migration 2026-06-29. Sibling chantier learning [[LRN-067]].
## BLK-013 — `make plugin` Error 127: npm absent on apt-`nodejs` host
- **Date**: 2026-06-30
- **Friction**: `make plugin` (→ `install-plugins.sh`) aborts at Step 4 (gsd-pi): `install-plugins.sh: line 425: npm: command not found``make: *** [Makefile:10: plugin] Error 127`. Steps 5-10 never run, AND the post-Step-4 stray-dir cleanup (Step 8.5) never reached → the [[BDR-030]]/[[LRN-042]] residual (stray `$REPO/.agents/skills` + `$REPO/.claude/skills`, promised "auto-cleaned next `make plugin`") silently persists run after run. SessionStart banner already showed `gsd v2 ✗`.
- **Real cause**: Debian/apt `nodejs` package ships `node` WITHOUT `npm` (npm = separate apt pkg). `/usr/bin/node` present (v22.22.1); its bindir has acorn/corepack/semver but NO npm/npx — npm genuinely uninstalled, not a PATH miss. install-plugins.sh Step 1 checks `node >=22` but NEVER verifies npm — assumes npm ships with node (true for nodesource/brew/dnf paths, FALSE for plain apt).
- **Solution**: corepack (ships with node) over apt npm (apt npm could pull a divergent 2nd node). `corepack enable --install-directory "$HOME/.local/bin" npm` → npm 11.18.0 shim, no sudo, `~/.local/bin` already on PATH. Then `npm config set prefix "$HOME/.local"` — default prefix `/usr` is root-owned → `npm install -g` would EACCES; `~/.local` writable + bins land on PATH. Persisted in `~/.npmrc`. Re-run → EXIT=0, Step 4 ✓ (`gsd-pi@2.64.0`), Step 8.5 ran (`Removed stray repo-local skills dir: .agents/skills` + `.claude/skills`). Caveat: gsd-pi DEPRECATED + postinstall scripts SKIPPED (npm 11 `allow-scripts`) — `gsd --version/--help` ok, full provisioning would need `npm install -g --allow-scripts=gsd-pi,… gsd-pi`.
- **Fix-forward**: install-plugins.sh Step 1 should GUARANTEE npm on apt-`nodejs` hosts — detect missing npm + `corepack enable npm` (not just check node) → stops Error 127 recurring on any fresh apt machine.
- **Status**: resolved (env-level: corepack shim + npm prefix; zero repo change). Fix-forward (script hardening) NOT built.
- **Reference**: discovered fixing `make plugin` 2026-06-30. Distinct from [[BLK-003]] (macOS playwright hardcoded path) + the Playwright-chromium `make plugin` failure. Blocked residual = [[BDR-030]]/[[LRN-042]].
- **Update 2026-07-01**: fix-forward BUILT. install-plugins.sh Step 1 gained unconditional npm guard (`corepack enable npm` → distro `install npm` fallback → fatal `exit 1`), placed AFTER the `NODE_OK` short-circuit so a node>=22-present-but-npm-absent host no longer skips it. Now fully resolved (env-level + script). shellcheck/`bash -n` clean; fresh-apt live validation still pending. Commit `1f2c1cc`, branch `bugfix/install-plugins-npm-guard`.
---
## BLK-014 — `make install` aborts npm EEXIST when claude already present
- **Date**: 2026-07-01
- **Friction**: `make install` → install.sh Step 2 `npm install -g @anthropic-ai/claude-code@latest` fails EEXIST on `~/.local/bin/claude` when claude already installed → `else err``exit 1`. Bootstrap not idempotent on Claude Code step; rest (auth, symlinks, plugins) never runs.
- **Real cause**: claude installed via NATIVE installer, not npm — `~/.local/bin/claude` = symlink → `~/.local/share/claude/versions/<v>` (`npm ls -g @anthropic-ai/claude-code` = empty; `claude --version` = 2.1.197). npm prefix `~/.local` (set by [[BLK-013]]) targets same `~/.local/bin/claude` → npm won't clobber a bin it doesn't own → EEXIST. Channel conflict, not double-install. Step had NO presence guard, unlike RTK (install-plugins.sh:388) / GSD (:419) / claude check (:252).
- **Solution**: install.sh — skip-if-present guard `command -v claude` (mirror RTK/GSD), npm only fresh machine (`elif`). update-all.sh — channel-aware updater: `npm ls -g` → npm-managed uses npm, else native uses `claude update` (self-update). Never `npm --force` (would clobber native, break self-update).
- **Status**: resolved. Fix `8dc4027`, branch `bugfix/install-claude-idempotent`, pending merge validation.
- **Reference**: [[BLK-013]] npm prefix `~/.local` = contributing factor (npm bin over native bin). install-plugins.sh already pointed to code.claude.com (native) — install.sh was the npm outlier. Fresh-machine `elif npm` branch channel-consistency = open design question (potential BDR). Pattern → [[LRN-085]].
- **Update 2026-07-01**: MERGED `2393ca5` (bugfix/install-claude-idempotent → develop), pushed — supersedes "pending merge validation". The open channel-consistency question is RESOLVED by [[BDR-046]] (fresh install → native installer, npm dropped for claude); install.sh has no `elif npm` branch → nothing left to trancher.

View File

@ -22,7 +22,7 @@ rules:
| ID | Date | Title | Status |
|----|------|-------|--------|
| BDR-001 | 2026-04-22 | Uniform --help helper via session-start hook (option C) | accepted |
| BDR-001 | 2026-04-22 | Uniform --help helper via session-start hook (option C) | accepted · won't-build 2026-06-30 |
| BDR-002 | 2026-04-23 | Move tasks/ + introduce memory + audits under .claude/ | accepted |
| BDR-003 | 2026-04-23 | Gitignore wildcard + negations pattern for .claude/ | accepted |
| BDR-004 | 2026-04-27 | Adopt auto permission mode as default | accepted |
@ -64,6 +64,11 @@ rules:
| BDR-040 | 2026-06-29 | doc-syncer MINOR-shape oracle: deterministic floor under LLM's MINOR call | accepted |
| BDR-041 | 2026-06-30 | /reconcile = deterministic declared-vs-real engine + thin gated skill (reconciler, not lister) | accepted |
| BDR-042 | 2026-06-30 | /release-candidate = thin orchestrator over gitflow release; the tag lives in the skill, not the lib | accepted |
| BDR-043 | 2026-06-30 | BDR-015 trigger cleared — 5 ex-broken gstack symlinks repaired → darwin re-baseline back in scope (unblocked, NOT run) | accepted |
| BDR-044 | 2026-06-30 | auto-skill-dispatch won't-build — under-routing fear inverted to over-routing by cartography, then measured: model discriminates (clear→route, ambiguous→ask, trivial→abstain) | accepted · won't-build |
| BDR-045 | 2026-07-01 | Standalone memory/doc skills branch to chore/* via aiguillage (hook exemption kept) | accepted |
| BDR-046 | 2026-07-01 | Claude Code installs via official native installer (curl claude.ai/install.sh), drop npm from install.sh | accepted |
| BDR-047 | 2026-07-01 | ECC audit → zero import; local config ahead of reference | accepted |
---
@ -77,6 +82,7 @@ rules:
- Option A (copy helper into each SKILL.md) — rejected: maintenance entropy.
- Option B (external wrapper `/help <skill>`) — rejected: breaks "one command = one skill" experience.
- **Reference**: commit 3968a29.
- **Won't-build (2026-06-30)**: accepted but never built. MEASURED before building — behavioral RED, 6 reps (`/web-validate` + `/harden`, no instruction): **6/6 already render rich help AND stop without dispatching** (even `/harden` didn't start its audit). The intended behavior is already spontaneous (universal `--help` convention); the ONLY residual value of the global instruction = format CONSISTENCY across 6 divergent shapes — judged not worth ~5 lines in a [[BDR-031]]-compressed CLAUDE.md on a solo repo. Not "abandoned" — measured non-rentable. Per-skill option stays rejected (original Decision above). See [[LRN-080]], [[LRN-075]].
## BDR-002 — Move tasks/ + introduce memory + audits under .claude/
@ -655,3 +661,117 @@ rules:
- **Consequence (accepted)**: a release cut by calling `gitflow finish` directly, bypassing the skill, fans out but is NOT tagged → `/release-candidate` is the CANONICAL sole release path. Acceptable for a solo repo; revisit (tag in lib) only if direct-lib releases become a need.
- **Alternatives rejected**: tag inside `gitflow_finish` (atomic but modifies the tested generic mechanic for a release-specific concern — lib=mechanic/skill=judgment); restart tags at v1.0.0 (desyncs tag↔CHANGELOG lineage).
- **Reference**: `skills/release-candidate/SKILL.md`, `lib/tests/run-release-candidate.sh` (RED no-tag → GREEN 5/5), CLAUDE.md routing. Built via writing-skills TDD. Consumes the gitflow model [[BDR-039]]. See [[LRN-078]], [[LRN-079]], [[EVAL-012]].
## BDR-043 — BDR-015 trigger cleared: 5 ex-broken gstack symlinks repaired → darwin re-baseline back in scope
- **Date**: 2026-06-30
- **Status**: accepted (requalifies [[BDR-015]] — append-only, BDR-015 left intact)
- **Decision**: the 5 dirs [[BDR-015]] excluded from `/darwin-skill` (`benchmark-models`, `context-restore`, `context-save`, `make-pdf`, `plan-tune`) are no longer broken. gstack now ships those skills — all GENERATED by `gen-skill-docs` in the `make plugin` run → real submodule targets exist, symlinks resolve. VÉRIF audit 2026-06-30 = 0 broken among 83 symlinks (skills/ 41 + skills-disabled/ 33 + nested 5 + top-level 4). Per BDR-015's own caveat ("if/when symlinks repaired → re-run baseline to bring them in scope"), the 5 RETURN to darwin scope → re-baseline UNBLOCKED.
- **Why**: BDR-015's exclusion was CONDITIONAL on the targets being broken (external-ownership + missing-target). Precondition gone → exclusion no longer applies to these 5.
- **Action (NOT done)**: verify `~/.agents/skills/darwin-skill/results.tsv` still marks these 5 `status=error` ("broken gstack symlink — out of scope"); if so, re-run darwin baseline to bring them in. Status = UNBLOCKED, execution PENDING — do NOT read as "re-baselined".
- **Distinct from [[BLK-007]]**: BLK-007/`f928a53` (2026-06-02) = a DIFFERENT symlink episode (`spec` + 5 iOS device-farm skills, source-only after a submodule bump; fixed by linking `spec`, skipping iOS). NOT the 5 of BDR-015 — kept separate to avoid a false causal link.
- **Reference**: VÉRIF audit (subagent, filesystem-only, 2026-06-30). [[BDR-015]] caveat. darwin eval log `results.tsv`.
---
## BDR-044 — auto-skill-dispatch won't-build: under→over reframe, measured — model already discriminates
- **Date**: 2026-06-30
- **Status**: accepted · won't-build
- **Decision**: do NOT add L2 routing prose to CLAUDE.md for "auto-trigger skills on intent". Chantier retired won't-build — 3rd measured moot of the session (after [[BDR-001]] --help + [[BDR-043]]/[[LRN-082]] darwin re-baseline).
- **Why — the dependent variable inverted**: the initial fear was UNDER-routing (model ignores skills, does the task by hand). Cartography refuted it — routing is a STACK and L1 (superpowers "1% chance → you MUST invoke") already SUR-determines invocation → "does it route?" = "already yes". The real open question became DISCERNMENT (clear→route, ambiguous→ASK, trivial→abstain), and the real hazard inverted to OVER-routing. Measured in REAL fresh main-loop sessions (8 prompts, 3 classes): CLEAR→routes ✓, AMBIGUOUS→asks (refuses to guess, investigates to ask a USEFUL question) ✓, TRIVIAL→abstains ✓. The L1-vs-Workflow-rules textual tension ("1% → MUST invoke" vs "ask one question if needed / pragmatic on trivial") is resolved well in behavior — the model balances. Adding L2 bounding prose = phantom value AND risks DEGRADING an already-good discernment.
- **Alternatives rejected**:
- Add a routing-reinforcement instruction (original intent) → phantom value: L1 already over-determines routing; more mandate worsens the only real risk (over-routing).
- Add an over-routing bound (clear→route / ambiguous→ask / trivial→abstain) at L2 → measurement shows the model ALREADY does this; codifying it risks perturbing it, zero upside.
- Keyword hook on intent verbs → too noisy — the design-hook mis-fired on "design" in "auto-skill-dispatch" 3× this session; intent verbs (corrige/crée) are everywhere.
- **Reference**: cartography L0L4 + discernment-RED (user-run, fresh sessions). Subagent under-routing RED RETIRED as non-discriminating ([[LRN-083]]). [[LRN-080]] (measure-first), [[LRN-049]] (bound noise). TODO "auto-skill-dispatch" → won't-build.
## BDR-045 — Standalone memory/doc skills branch to `chore/*` via the aiguillage (hook exemption kept)
- **Date**: 2026-07-01
- **Status**: accepted
- **Decision**: Standalone memory/doc skills (`/capitalize` `/close` `/prune-memory` `/reconcile`) run the gitflow aiguillage BEFORE writing: on a protected base they `gitflow start chore <name>` off develop → commit lands on `chore/*`, not direct on main/develop. New `chore` type in `lib/gitflow.sh` (`base_for`→develop, `branch_type`, `finish`→develop like feature/bugfix); hook UNCHANGED (`chore/*` non-protected; the `.claude/**`-on-main exemption KEPT — T3 still green). `gitflow-aiguillage.md` broadened (caller→type map); 3 skills wired (`capitalize` covers `/close` via alias, `prune-memory`, `reconcile`); tests +T1 chore predicates +T6b finish chore→develop +T10 coherence chore/m → 64/64. Reused the EXISTING aiguillage include, not a new mechanism. Commit `e8807a7`.
- **Why**: the `.claude/**` exemption is scoped to the SIDE-CAR ([[BDR-034]]: memory following a code branch). When memory IS the work (standalone reconcile/prune/capitalize) there is no branch to follow → it fell back to `main`. A multi-repo raccord committed 5 `chore(memory)` direct on `main` and nothing flagged it — the exemption worked as designed, masking the divergence with the "all via branch" rule ([[LRN-084]]). The aiguillage closes the SKILL path without taxing the side-car. The hook can NEVER enforce "from develop" (only "not on a protected base") → that half lives ONLY in `gitflow_start`.
- **Alternatives rejected**:
- (A) remove the `.claude/**` exemption — breaks standalone `/capitalize`+`/close` on main/develop (commit in place, no branch of their own — `memory-commit.sh` has no protected-base guard) AND every side-car commit; over-reaches the leak.
- (C) codify exemption + human habit — enforces NOTHING mechanically; goal was automatic.
- (D) narrow the exemption by size/scope in the hook — fuzzy, false positives.
- **Honest residual**: a MANUAL `git commit` of `.claude/**` on `main` still passes — B covers the skill path only. Non-blocking hook WARN on manual `.claude/**`-on-main = DEFERRED. See [[BDR-034]], [[BDR-039]], [[LRN-084]].
---
## BDR-046 — Claude Code installs via the official native installer, not npm
- **Date**: 2026-07-01
- **Decision**: install.sh fresh-machine branch installs Claude Code via `curl -fsSL https://claude.ai/install.sh | bash` (official native installer), not `npm install -g @anthropic-ai/claude-code`. Skip-if-present guard unchanged. update-all.sh stays channel-aware (native → `claude update`, legacy npm → npm).
- **Why**: official quickstart (code.claude.com/docs) lists Native (recommended) / Homebrew / WinGet / apt only — npm is NO longer a documented channel. npm collided with the native symlink `~/.local/bin/claude` → EEXIST ([[BLK-014]]), and npm bypasses native background auto-update. install-plugins.sh already pointed to code.claude.com (native) — install.sh was the npm outlier; this aligns them.
- **Alternatives rejected**:
- (A) keep npm on fresh install — deprecated channel, re-introduces the EEXIST class on any machine with a prior native install, no auto-update.
- (B) `claude install` subcommand — needs claude already present (chicken-and-egg on fresh machine); curl bootstrap is the documented first-time path.
- (C) Homebrew/apt — platform-specific; curl covers macOS/Linux/WSL uniformly and matches the doc's "recommended".
- **Honest residual**: `curl | bash` = pipe-to-remote-bash (accepted: official Anthropic domain, same pattern already used for nvm at install.sh:29). node/npm still installed as prereqs — needed by the plugins step (gsd-pi), not by claude. PATH export added so the auth step finds the freshly-installed binary. See [[BLK-014]], [[LRN-085]].
- **Status**: accepted. Commits 8dc4027 + 6be627e, branch bugfix/install-claude-idempotent, pending merge.
- **Update 2026-07-01**: MERGED `2393ca5` → develop, pushed — supersedes "pending merge".
---
## BDR-047 — ECC audit → zero import; local config ahead of reference
- **Date**: 2026-07-01
- **Status**: accepted
- **Decision**: audited affaan-m/ECC (legit original, NOT the arabicapp malware
clone) read-only for value vs this config. Result: ZERO import. Nothing taken.
Clean measure-first outcome — analysis closed.
- **Safety** (durable, avoids re-audit): ECC = genuine original — 2232 commits,
~1480 by Affaan Mustafa, real contributor long-tail, sequential PRs. No payload:
postinstall = echo, install.sh runs only its 3 reputable deps (@iarna/toml, ajv,
sql.js), ships own supply-chain IOC scanner. Zero injection flags across ALL
categories. NOTE: ECC install.sh auto-runs `npm install` → never run their
installer casually; this analysis stayed read-only.
- **Why zero import** (each intuition CHALLENGED, not confirmed):
- RULES (122 files, by-language): ~80% redundant w/ CLAUDE.md, rest dormant
reference. INERT at ECC — nothing reads rules/, their README admits "plugins
cannot distribute rules automatically", `paths:` frontmatter aspirational (no
auto-routing exists). "take all" refuted.
- CONTEXTS (dev/research/review, 3 tiny files): least load-bearing. Delivery via
`claude --system-prompt "$(cat)"` would OVERWRITE global CLAUDE.md. Harmful
as-shipped. "important" refuted.
- GUIDELINES: ECC itself demoted to docs/example. Per-project CLAUDE.md
(git-tracked) superior.
- INSTRUCTION FILES (AGENTS/RULES/SOUL/WORKING-CONTEXT): redundant or
ECC-specific. AGENTS.md "proactive delegation" already mandated here.
- MEMORY/learning: auto hook-capture → confidence-scored instincts. CONFLICTS
measure-first (observe-first vs approve-first). Instinct schema parked (gated
only).
- eval-harness (the spike): DOCS-ONLY — 271-line SKILL.md, no runner,
`/eval define|check|report` exist NOWHERE. Same "belle méthodo / câblage
vaporware" pattern as rules. Executable-eval ALREADY covered locally:
lib/tests/run-*.sh (code graders) + darwin dim8 (with/without-baseline
sub-agent effect testing + git ratchet) + RED-before-GREEN discipline. evals.md
= ledger of REAL runs (EVAL-011 ran 20/20, dogfooded) — spike premise
"descriptif pas exécuté" was FALSE, corrected.
- **Lesson**: external repo — even prestigious / "d'un boss" — judged on REAL added
value to THIS config's axes (typed memory, real harness, gitflow), NOT author
reputation. Measuring it revealed local config AHEAD on those axes. Taking a thing
"since we analyzed" = sunk-cost. Zero is the honest conclusion. Don't re-propose
auditing ECC expecting treasure.
- **2 real gaps FOUND (not rejected — the only concrete fruit of the audit)**:
1. pass@k / reliability-under-repetition — local harness proves PRESENCE (guard
fires, often N=1), not RELIABILITY (right output 9/10 under repetition). Blind
spot for non-deterministic skill/agent behavior (EVAL-006 flagged "N=6 fleet
NOT exhausted").
2. re-runnable regression battery indexed on model upgrades — bespoke
per-chantier tests, no one-command "re-run behavioral evals for load-bearing
skills" when model changes. darwin optimizes on-demand, not a standing gate.
- **Both = home-grown ~10-line bash over darwin's test-prompts.json if ever
wanted — NOT ECC imports.** eval-harness delivers neither (no runner). Separate
later decision.
- **Alternatives rejected**:
- Import eval-harness anyway (sunk-cost "we analyzed it") — rejected: docs-only,
capability already covered, adds vocabulary not machinery.
- Import rules by-language + build wiring hook — parked: low ROI (bash/md, not
polyglot); hookify-rules would be the mechanism, someday-if-polyglotte.
- Adopt instinct auto-capture — rejected: conflicts measure-first.
- **Optional zero-cost nicety** (not now): tag evals.md entries w/ grader-type + k
(e.g. `method: code-grader, pass^3`) — writing convention, not an import.
- **Reference**: read-only clone (scratchpad), 4 parallel analyzer agents +
eval-harness spike, this session. No branch on ECC, no import. See [[BDR-045]]
(chore/ aiguillage), [[BDR-009]] (caveman registries).

View File

@ -33,6 +33,7 @@ rules:
| EVAL-010 | 2026-06-29 | prune-memory hardening: RED-7 deterministic fix + RED-8 accept + 34-row index backfill | keep |
| EVAL-011 | 2026-06-30 | /reconcile build: RED contaminated→corrected (unguided control), GREEN behavioral confirmed, dogfooded on itself | keep |
| EVAL-012 | 2026-06-30 | /release-candidate build: RED (gitflow fans out, no tag) → GREEN 5/5 (tag), throwaway-repo flow replay | keep |
| EVAL-013 | 2026-06-30 | /reconcile real-usage on live repo: known gap + 2 unanticipated (header-marker drift class) + false-positive rejected off-fixture, 0 false assertion | keep |
---
@ -136,3 +137,10 @@ rules:
- **method**: read-first cartography (gitflow release wired: start L49 base=develop, finish L108-111 fan-out; grep-confirmed NO `git tag` → the gap). TDD on a throwaway repo: RED (`RC_TAG=0`) = start→prep→finish → 4 GREEN (fan-out / merge-back / branch-deleted / CHANGELOG) + 1 RED (tag v4.0.0 absent — gitflow never tags); GREEN (`RC_TAG=1`) = + `git tag -a` → 5/5, tag on main's merge commit. shellcheck clean (caught + fixed an SC2164 mid-build).
- **anomalies**: (1) versioning reasoning corrected by the user — number derives from change nature, not justification ([[LRN-078]]); caveman verified `Removed` not breaking from refs, not memory. (2) tag-in-skill consequence (direct-lib release wouldn't tag) made explicit + accepted, not left implicit. (3) layers kept distinct — this built+tested the skill; cutting the real v4.0.0 is a separate later act.
- **action**: keep. RED red for the right reason (gap = tag), GREEN closes it, teeth proven.
## EVAL-013 — /reconcile in REAL USAGE: unanticipated drift found + false-positive rejected off-fixture
- **Date**: 2026-06-30
- **output**: reconcile run on live claude-config repo (develop) → write-back `.claude/tasks/TODO.md` (commit `09200c5`, pushed): `/release-candidate` QUEUED→SHIPPED + 4 subtasks [ ]→[x]; 3 stale `[branch …]` headers→[DONE]. Engine `lib/reconcile.sh` orchestrated by hand (enumerate_ids + oracle_* probes + verdict + A/B/C gate). Distinct from [[EVAL-011]] (BUILD: fixture RED/GREEN + self-dogfood) — this = USAGE on fresh real drift.
- **method**: real run, no fixture. Per declared item, oracle vs git/fs: `oracle_path_present` (SKILL.md d3d6ced), `oracle_msg_committed`, `oracle_merge_done` (3 branches merged+deleted), tag v4.0.0 + version.txt. `blk_open` → 3 external (BLK-001/003/009, no drift). `deferrals` (marked) + `contradiction_candidates`. Measurable: 1 primary gap (/release-candidate QUEUED-but-done, oracle-proven) + 3 secondary (header-marker drift) found · 1 false positive rejected · 0 false gap asserted.
- **anomalies**: none wrong. 2 capabilities PROVEN that [[EVAL-011]] did NOT: (a) finds UNANTICIPATED gaps — the 3 `[branch X]` headers = a header-marker drift CLASS beyond checkbox drift, not designed-for, caught anyway (merge_done=YES + no local branch). Coverage wider than spec. (b) rejects FALSE POSITIVE on REAL data — `--help` candidate (BDR-001 title ⇄ TODO L134) surfaced as CANDIDATE not verdict; review → both WON'T-BUILD, aligned, not contradiction. Recursive coherence holds OFF-fixture. Design note: NO merge-time header-update hook — merge does merge, /reconcile = periodic catch (separation kept, finding 1).
- **action**: keep. Real-world value proven — known gap + 2 unknown + false-positive rejected, zero false assertion.

View File

@ -261,3 +261,37 @@ rules:
- Learnings: semver derives from change nature, caveman = Removed not breaking ([[LRN-078]]); orchestrator-skill TDD = throwaway-repo flow replay ([[LRN-079]]).
- CHANGELOG [Unreleased]: added /reconcile + /release-candidate under ### Added (so the eventual v4.0.0 captures them — /reconcile shipped without its entry, rectified here).
- Ship: feature/release-candidate-skill → develop (gitflow finish). Push gated (ASK). Real v4.0.0 cut = separate later act (layer 2).
## 2026-06-30 (cont.) — make plugin fixed (npm) + deferred-items requalif (③ doc-commit, BDR-015 darwin)
- 2 code vérifs (subagents, no-memory) + `make plugin` action. VÉRIF③: gitflow hook (`lib/gitflow.sh:199-225`, exempts `.claude/**` + merges + root) installed by init-project STEP 5f + onboard STEP 2.6 → branch guard covered everywhere EXCEPT repos outside `gitflow init` (doc-commit.sh has NO branch guard — `_unsafe_state` skips main/develop). ③ = confirmed REAL but NARROW hole, already graved [[BDR-040]]/TODO:292 → NOT re-graved.
- ③ nuance (only new bit, logged here): a future doc-commit guard must REPLICATE the hook's `.claude/` whitelist (hook EXEMPTS 100%-`.claude/` commits on main/develop — memory follows the work), NOT blanket-block main/develop → 3rd copy of the whitelist predicate, not "4 lines". Low priority, stays deferred.
- VÉRIF symlinks: 0 broken / 83 today → BDR-015 trigger cleared, darwin re-baseline UNBLOCKED (NOT run). [[BDR-043]].
- `make plugin` Error 127 (npm absent, apt-`nodejs` host) → fixed via corepack (npm 11.18.0 → `~/.local/bin`, prefix `~/.local`), EXIT=0, Step 4 ✓, stray-dir residual cleanup ([[BDR-030]]/[[LRN-042]]) finally ran. [[BLK-013]].
- BLK-013 + BDR-043 capitalized; ③ requalif dropped (already captured), whitelist nuance logged here. Surgical memory commit (blockers+decisions+journal only, NOT TODO — user's uncommitted planning note left untouched).
## 2026-06-30 (cont.) — close ritual (LRN-081 + TODO reconcile) + gate-suspense gap caught
- Ran /close (capitalize --ritual). After a fresh capitalize → registries propose near-nothing (BLK-013/BDR-043 already this session); live work = TODO reconcile + 1 LRN.
- GAP caught: the prior STEP-3 gate (LRN-081 + TODO check L26 + 2 adds) had stayed UNRESOLVED — conversation diverted to an out-of-band /reconcile + EVAL-013 (`437697e`, author user, NOT Claude) which never touched the gate items. Verified absent, then completed. Exactly the declared-vs-real drift /reconcile exists to catch.
- LRN-081: Claude commit trailers only on Claude-COMPOSED content; staging user-authored text gets none (staging ≠ authorship). Born of `e591510` (clean) vs `5b03ac2` (trailers).
- TODO: checked L26 "Cleanup machine courante" DONE (`make plugin` EXIT=0 this session ran Step 8.5; fs-verified both strays absent — closes the session's opening "cleanup ligne 26"); added (a) harden install-plugins.sh Step 1 npm-via-corepack ([[BLK-013]] fix-forward); added (b) darwin re-baseline of the 5 ex-broken skills ([[BDR-043]], promoted from its action-field).
- LRN-081 capitalized; checked 1 done, added 2.
## 2026-06-30 (cont.) — BLOC1 darwin re-baseline → resolved-MOOT (measure-first)
- Searched for results.tsv instead of assuming its state → GONE (wiped by 23/06 make-plugin reinstall; was a local May-2026 artifact, not shipped upstream). No darwin baseline survives at all → not even a re-baseline, a fresh-from-zero one.
- BDR-043 cleared only motif (a) of BDR-015's TWO exclusion grounds (symlinks repaired ✅, 0 broken); motif (b) external-ownership INTACT — 5 resolve to skills-external/gstack/ (submodule), darwin edits SKILL.md → would dirty submodule ([[LRN-070]]). Re-baseline = unactionable score = phantom value. Twin of --help ([[LRN-080]]), distinct mechanism (residual motif vs absent value).
- Decision A (won't-run): TODO (b) → resolved-MOOT (not done, not open). LRN-082 capitalized (multi-motif trigger lesson). The "montre la table avant de décider" gate paid off — looking found the table gone instead of assuming status=error.
## 2026-06-30 (cont.) — BLOC2 auto-skill-dispatch → WON'T-BUILD (discernment measured)
- Cartography: routing = STACK L0(design-hook)→L1(superpowers "1%→MUST invoke", dominant)→L2(CLAUDE.md prose)→L3(frontmatter)→L4([[BDR-019]]). L1 over-determines invocation → "auto-call?" = already yes.
- Reframe C (user): real question = DISCERNMENT not "does it route"; risk inverts under→OVER-routing (L1 mandate vs Workflow "ask if needed / pragmatic on trivial").
- Subagent RED (6 reps, toy tasks) → 0/6 routed → RETIRED as non-discriminating (SUBAGENT-STOP + delegated framing = floor artifact, not signal); did NOT report as a number → [[LRN-083]].
- Discernment-RED in REAL fresh sessions (user-run, 8 prompts / 3 classes): CLEAR→route ✓, AMBIGUOUS→ask (refuses to guess, investigates for a useful Q) ✓, TRIVIAL→abstain ✓. Over-routing risk does NOT materialize — model balances L1 vs Workflow rules.
- Verdict: WON'T-BUILD ([[BDR-044]]) — 3rd measured moot of the session (--help, darwin re-baseline, auto-skill-dispatch). LRN-083 capitalized; [[LRN-080]] corroborated (3-in-a-row → measure-first sweep heuristic). TODO auto-skill-dispatch → won't-build. ALL actionables soldés.
## 2026-07-01
- gitflow aiguillage-standalone (BDR-045): chore type + 4 standalone memory/doc skills branch off develop before writing; hook exemption kept. 64/64 green (e8807a7). Then repaired 5 direct-on-main `chore(memory)` → chore/reconcile-memory branches (LRN-084, LRN-034 corrob).
- BLK-014 fixed: install.sh npm EEXIST on `~/.local/bin/claude` (native symlink, npm prefix `~/.local` from BLK-013) → skip-if-present guard + channel-aware update-all.sh (`claude update` for native). LRN-085. Commit 8dc4027, branch bugfix/install-claude-idempotent pending merge.
- BDR-046: install.sh switched fresh-install from npm → official native installer (`curl claude.ai/install.sh | bash`); npm no longer a documented channel (verified quickstart). Aligns with install-plugins.sh. Commit 6be627e, same branch.
- /reconcile show-only (claude repo, engine-verified): confronted TODO+registries vs git/fs. Real state = 1 actionable (install-plugins npm harden), 3 blocked-upstream (BLK-001 rtk / BLK-003 darwin / BLK-009 CC #21858, re-test on CC MAJ), 3 deferred-on-trigger, release-decision live (develop 20 ahead of v4.0.0). Engine false-flagged BLK-014 (last-status-wins caught Reference "open" vs Status resolved) — verified merged. "canal d'install" = already decided by BDR-046, NOT open; faunosteo/WARN-manuel = not in this repo.
- (c) TODO drift fixed: 7 `--help` WON'T-BUILD subtasks `[ ]`→`[-]` (chore/reconcile-todo-drift, 9c02406) → naive open-count 10→3, survivors all genuine deferred-open. Registries left read-only during reconcile (staleness deferred to this capitalize).
- (a) BLK-013 fix-forward BUILT: install-plugins.sh unconditional npm guard (corepack→distro→fatal), placed after `NODE_OK` short-circuit so node>=22-but-no-npm hosts don't skip it. shellcheck/`bash -n` clean, 1f2c1cc. Capitalize refreshed BLK-013 (NOT built→built), BLK-014 + BDR-046 (pending→merged) via append-only Update blocks. Both branches finished into develop.

View File

@ -99,6 +99,12 @@ rules:
| LRN-077 | 2026-06-30 | test fixtures must carry NEUTRAL names — a name that telegraphs the answer lets the subject pass by reading the name, not doing the work | designing any test fixture/path; same symptom as [[LRN-074]] (passes for WRONG reason), distinct cause (leaky fixture vs assumed command) |
| LRN-078 | 2026-06-30 | semver number DERIVES from the change nature, not "justify a target"; solo-repo "breaking" = requires a migration of own usage; a removal nothing invokes = Removed not breaking | choosing a release version; classifying MAJOR/MINOR/PATCH; deciding if a removal is breaking |
| LRN-079 | 2026-06-30 | orchestrator-skill TDD = replay the prescribed flow on a throwaway repo (gitflow-test style): RED runs the flow minus the new step → the outcome assertion reds on the gap | testing a skill that orchestrates an existing mechanic + one new step |
| LRN-080 | 2026-06-30 | before adding an instruction "to make the model do X", measure if it ALREADY does X — universal conventions (--help…) it often does; the behavioral RED can KILL the chantier (phantom value) | proposing any global instruction to elicit a behavior; CLAUDE.md additions |
| LRN-081 | 2026-06-30 | Claude commit trailers (Co-Authored-By + Claude-Session) only on Claude-COMPOSED content; a commit merely STAGING user-authored text gets none — staging ≠ authorship | committing on the user's behalf; memory-commit.sh appends trailers by default |
| LRN-082 | 2026-06-30 | Trigger-cleared on a multi-motif exclusion lifts only the named motif — re-check the others before acting | any "exclusion lifted / precondition cleared" — verify ALL grounds, not just the named one |
| LRN-083 | 2026-06-30 | subagents are an INVALID instrument for measuring main-loop spontaneous routing — SUBAGENT-STOP + delegated framing pin them to the no-route floor | any RED of whether the MAIN loop self-invokes; use fresh main-loop sessions, observe via the human |
| LRN-084 | 2026-07-01 | protection hook enforces PROD not the full branch-flow; exemption masked the rule-vs-guard divergence | a guard exempts a class / checks one predicate — verify it encodes full intent |
| LRN-085 | 2026-07-01 | Idempotent CLI install/update: `command -v` skip-if-present guard + detect channel (`npm ls -g` vs native symlink) before choosing updater; never `npm --force` over a bin npm doesn't own | any installer/updater for a CLI with >1 install channel |
---
@ -540,6 +546,7 @@ rules:
- **Pattern**: narrated/remembered state from ANY source (user OR assistant) is not ground truth. Approval of a diff ≠ its application.
- **Future application**: anyone asserts "X is done" → verify (git log, file content, grep) before building on it; ESPECIALLY when it contradicts your own earlier statement, or after a context/window break. Internal contradiction → stop, re-check git, never reconcile by accepting the newer claim silently.
- **Reference**: P3 reprise, commit 493b6b9. Linked to [[LRN-032]] (verify before applying a rule), [[LRN-035]] (check the artifact, not the claim/count).
- **corroboration 2026-07-01**: multi-repo raccord (6 repos) — mapped each repo's REAL git/fs state (read-only cartography) before EVERY write/destructive op, gated per-gap, re-verified each subagent oracle in the main loop. Declared TODO/registry/checkbox drift confirmed repeatedly; the discipline KILLED false simplifications: a blind `master→main` CHANGELOG swap (reflog showed master renamed AWAY, not a live branch), "just remove the `.claude/**` exemption" (would have broken standalone `/capitalize`, [[LRN-084]]), a config supersession grep that failed on a line-wrap (supersession was real). Narrated/declared state ≠ ground truth, at multi-repo scale.
---
@ -873,3 +880,49 @@ rules:
- **Date**: 2026-06-30
- **pattern**: a thin orchestrator skill (composes an existing tested mechanic + ONE new step) is not unit-testable as a function, but its FLOW is testable by replay on a throwaway repo (gitflow-test style). RED = run the prescribed sequence WITHOUT the new step (the existing mechanic alone) and assert the desired outcome → it reds on exactly the gap. GREEN = add the step. For `/release-candidate`: `gitflow start release`→prep→`finish` (no tag) → assert `vX.Y.Z` on main → REDS (gitflow fans out but never tags); add `git tag` → 5/5. Teeth: the single toggled line (`RC_TAG`) flips red↔green so GREEN can't pass by accident.
- **future application**: for any orchestrator over a lib mechanic, test the END-TO-END flow on a disposable repo; isolate the NEW step so the RED reds precisely on it (don't re-test the lib's generic part — it has its own tests).
## LRN-080 — measure whether the model already does X before adding an instruction to make it do X
- **Date**: 2026-06-30
- **pattern**: the --help chantier (implement [[BDR-001]] as a global CLAUDE.md instruction "on --help → render help + stop") was KILLED by its behavioral RED. Before writing a line, measured the control (6 reps, `/web-validate` + `/harden`, no instruction): **6/6 already rendered rich help AND stopped without dispatching** — the supposedly-absent behavior was fully present. Residual value = format consistency across 6 divergent shapes → not worth ~5 lines in a compressed CLAUDE.md on a solo repo. A phantom-value addition avoided.
- **why it matters**: [[LRN-075]] (test the UNGUIDED control) paying off one chantier later — measuring the RED before building is what caught it. For UNIVERSAL conventions the model already honors (--help, common flags, standard shapes), a "teach it to do X" instruction buys nothing but tokens; the only thing left to buy is consistency, which must clear its own ROI bar.
- **future application**: before adding any global instruction to ELICIT a behavior, run the behavioral control first — does the model already do it unaided? If yes, the only remaining value is standardization; price it honestly vs the cost (esp. a compressed CLAUDE.md). Often: don't add it.
- **corroboration 2026-06-30**: 3 consecutive "make the model do X" chantiers — --help ([[BDR-001]]), darwin re-baseline ([[BDR-043]]/[[LRN-082]]), auto-skill-dispatch ([[BDR-044]]) — ALL measured won't-build/moot. A backlog of "add instruction to elicit behavior Y" has a high phantom-value rate (universal conventions + aggressive existing mandates like superpowers L1 already elicit Y) → sweep such backlogs measure-first, expect kills.
## LRN-081 — Commit trailers: Claude-COMPOSED content only, never on staging of user-authored text
- **Date**: 2026-06-30
- **pattern**: the Claude commit trailers (`Co-Authored-By: Claude …` + `Claude-Session: …`) mark Claude's ACTUAL contribution. They belong on commits whose CONTENT Claude composed — memory entries, code, docs, TODO lines drafted from intent/BDRs. A commit that merely STAGES content the USER wrote (queuing the user's own raw note) gets NEITHER trailer — author = the user, clean. Staging ≠ authorship.
- **why it matters**: memory-commit.sh + the dev flows append the trailers BY DEFAULT → committing user-authored text through them mis-credits Claude on every note/spec the user writes. A `Claude-Session:` on a 100%-user addition is traceability noise pointing at no Claude contribution.
- **context**: 2026-06-30 — user's `auto-skill-dispatch` planning note committed `chore(todo)` CLEAN, no trailer (`e591510`, author Bastien Chanot); vs `chore(memory)` BLK-013/BDR-043 (`5b03ac2`) WITH trailers (Claude composed those entries). The split IS the rule.
- **future application**: before committing on the user's behalf ask "did Claude COMPOSE this content?" Composed (entry/code/doc/TODO-from-intent) → trailers. Merely staging user-written text → no trailers, user-authored. Self-referential proof: this entry + the promoted TODO follow-ups = Claude-composed → trailers OK on their commit.
- **correction 2026-06-30**: the mechanism claim above ("memory-commit.sh appends trailers by default", body + Index cell) is WRONG. `memory-commit.sh` does NOT append trailers — it commits `git commit -m "$msg"` verbatim (`memory-commit.sh:86`; trailer-agnostic; no `commit.template`, no `prepare-commit-msg` hook). Trailers are MODEL-composed message content (harness git-commit convention). Control point = the composed MESSAGE, not the helper. Proven live: a bare one-liner through the helper (`532ae69`) landed with ZERO trailers → had to amend (`c09f2b2`). Teeth = consciously ADD trailers on Claude-composed commits + OMIT on user-staging; the helper enforces NEITHER. The PRACTICAL guidance above (composed→trailers, staged→none) stays correct — only the mechanism was wrong; the false entry already mis-led one commit (the bare-msg miss). DEFERRED to /prune-memory: rewrite the false "helper appends" wording in this body + the Index cell (curation = not append-only → wrong tool here); this bullet marks WHAT to clean.
## LRN-082 — Trigger-cleared on a MULTI-MOTIF exclusion lifts only the NAMED motif — re-check the others before acting
- **Date**: 2026-06-30
- **pattern**: an exclusion justified by ≥2 independent grounds lifts only for the ground that actually changed. A "trigger cleared / precondition gone" note naming ground A leaves ground B in full force. Geometric trigger lifted ≠ value trigger lifted; acting on cleared-A without re-checking B = false unblock.
- **why it matters**: [[BDR-015]] excluded 5 gstack skills from /darwin-skill on TWO grounds — (a) broken symlinks AND (b) external ownership (never modify a third-party submodule). [[BDR-043]] cleared (a) only (symlinks repaired, 0 broken) → marked re-baseline "unblocked". (b) intact: darwin optimizes by EDITING SKILL.md → would edit the gstack submodule = forbidden ([[LRN-070]]). Re-baseline = a score we can't act on → phantom value.
- **context**: 2026-06-30 — measure-first: searched for results.tsv instead of assuming → GONE (wiped by 23/06 make-plugin reinstall) → no baseline survives + (b) never lifted → action resolved-MOOT, not run. Twin of [[LRN-080]] (--help): trigger fired, measurement showed phantom value (distinct mechanism: there value-absent, here residual-motif).
- **future application**: before acting on any "exclusion lifted / precondition cleared", enumerate ALL original grounds and verify EACH is gone — not just the one the trigger names. Cleared-A says nothing about B.
## LRN-083 — Subagents are an INVALID instrument for measuring MAIN-LOOP spontaneous routing
- **Date**: 2026-06-30
- **pattern**: to measure whether the MAIN loop self-invokes a skill on implicit intent, dispatched subagents are non-discriminating — SUBAGENT-STOP tells them to SKIP the L1 routing mandate, and a delegated-execute framing suppresses meta-routing → they hand-do the task regardless of how strong/weak the main-loop prose is. Result pins to the no-route FLOOR (artifact, not signal). Complement of [[LRN-028]] (there subagents OVER-saw installed skills, invalidating a no-skill baseline; here they UNDER-route, invalidating a routing-measurement) — both = subagent ≠ main-loop condition.
- **why it matters**: a 0/N subagent RED reads as "under-triggers → build the chantier" but is the [[LRN-028]] trap — the instrument can't tell strong prose from weak. Concluding from it = a pass/fail for the WRONG reason ([[LRN-074]]/[[LRN-077]]).
- **context**: 2026-06-30 auto-skill-dispatch RED. 6 subagents on toy implicit-intent tasks → 0/6 routed → RETIRED as non-discriminating, NOT reported as a number. Reframed; measured instead in REAL fresh main-loop sessions.
- **future application**: measure main-loop spontaneous routing/discernment in FRESH main-loop sessions (full L0L4, no SUBAGENT-STOP, real user-turn). Observable instrument = the HUMAN typing the prompts + watching live — cron/schedule-spawned fresh sessions are the right CONDITION but UNOBSERVABLE to the orchestrator (they notify the owner, not the dispatcher), so they can't be the measurement vehicle. Never substitute a subagent for a fresh session in a routing RED. See [[LRN-028]], [[LRN-075]], [[LRN-080]].
## LRN-084 — A protection hook enforces PROD safety, not the full branch-flow — the exemption masked the rule-vs-guard divergence
- **Date**: 2026-07-01
- **pattern**: the gitflow pre-commit hook is a PROTECTION guard (block code on main/develop), NOT a flow enforcer. It exempts `.claude/**` and can only test "on a protected base" — it can NEVER verify "branched FROM develop" (no base knowledge). So "every change via a branch from develop" is only HALF-encoded by the hook; the base half lives solely upstream in `gitflow_start`. The exemption is scoped to the SIDE-CAR ([[BDR-034]]); it has no branch to follow when memory IS the work → standalone memory fell back to `main`.
- **why it matters**: a multi-repo raccord committed 5 `chore(memory)` direct on `main` and NOTHING flagged it — nothing was violated, the exemption worked as designed. The divergence was guard (declares PROD protection) vs intended rule (all via branch); the exemption MASKED it, the raccord revealed it by violating the unencoded half. A guard encoding only PART of the intent reads as full enforcement — a false-green.
- **future application**: when a guard exempts a class or checks one predicate, ask what it does NOT encode and whether a human leans on it for MORE than it enforces. Enforce the unencoded half where it actually lives (the aiguillage at skill start, [[BDR-045]]), do not push it into a guard that structurally can't hold it. Verify the guard's real scope against the rule's full scope before trusting "it would have caught it." See [[BDR-034]], [[BDR-045]], [[LRN-034]].
---
## LRN-085 — Idempotent CLI install/update: presence guard + channel detection, never `--force`
- **Date**: 2026-07-01
- **Context**: install.sh npm-installed claude blindly → EEXIST abort when claude present via native installer (symlink npm doesn't own). Sibling steps (RTK/GSD) already had `command -v` skip guards; install.sh didn't. See [[BLK-014]].
- **Pattern**: (a) idempotent install step = `command -v <bin>` guard → skip-if-present with version echo, install only in `else`/`elif`. For a BINARY this IS a deterministic oracle (contrast [[LRN-054]]: conversation-state presence has none → don't skip-branch). (b) a CLI can ship via >1 channel (npm vs native). npm can't clobber a bin symlink it doesn't own → EEXIST; `npm --force` = wrong (npm itself says "recklessly", breaks native self-update). Detect channel first: `npm ls -g <pkg>` succeeds → npm-managed → npm; else native → `claude update` self-updater. (c) install ≠ update: first-time installer skips-if-present; the update script does the channel-aware upgrade.
- **Future application**: any installer/updater for a CLI reachable via multiple channels — guard with `command -v`, branch the updater on detected channel, never blind `--force` over a foreign-owned bin. Caveat [[LRN-036]]: `command -v` needs the bin dir on PATH in shelled-out/hook contexts.
- **Reference**: [[BLK-014]], mirrors RTK/GSD guard in install-plugins.sh. Related [[LRN-005]] (plugin enable idempotency), [[LRN-039]] (installer config drift).

View File

@ -23,9 +23,10 @@ Root causes trouvées (logs install-20260623-181416.log) :
- [x] Verif — shellcheck/bash -n propres ; migré darwin → $HOME/.agents/skills + `bash link.sh`
(skills/darwin-skill OK) ; `profile.sh set full` → 0 "missing", 35 gstack on-demand ;
cycle minimal↔full OK ; git propre (symlinks gstack gitignorés) ; profil full restauré
- [~] Cleanup machine courante : $REPO/.claude/skills/darwin-skill + .agents/skills VIDE
- [x] Cleanup machine courante : $REPO/.claude/skills/darwin-skill + .agents/skills VIDE
restent (rm bloqué par garde permission .claude/) → auto-nettoyés au prochain `make plugin`
[reconcile 2026-06-29 : TOUJOURS présents (fs-vérifié, darwin-skill 116K daté 23/06) — `make plugin` pas rejoué depuis. Reste différé, déclencheur = prochain install.]
[done 2026-06-30 : `make plugin` rejoué EXIT=0 (npm réparé via corepack, [[BLK-013]]) → Step 8.5 a retiré les deux ; fs-vérifié ABSENTS, vrai skills/ intact (36 entrées). Boucle fermée.]
- [x] Capitalize — LRN-042 (Bug B CWD-relatif) + BDR-030 (gstack on-demand par profil) + journal 2026-06-23
- [x] Commit (via /commit-change) — DONE (reconcile 2026-06-29 : working tree clean, travaux shippés)
@ -131,8 +132,8 @@ Subtasks :
- [x] Patcher `lib/design-gate.md` — ajouter motion/motion-v/framer-motion + autres anim-libs dans filesystem signals
- [x] Tester : shellcheck OK ; matrix React/Vue/RN/backend/with-motion/no-package/pnpm tous corrects
## Helper `--help` / `help` sur tous les skills (option C)
> ⚠️ BLOQUÉ (reconcile 2026-06-29) : contredit BDR-001 (accepted) qui a REJETÉ "copier le helper dans chaque SKILL.md" (maintenance entropy) au profit d'un hook session-start. Or ce chantier planifie STEP 0.5 par SKILL.md. Le TODO note lui-même "aucun skill ne gère --help aujourd'hui" → la voie hook de BDR-001 n'a jamais produit de --help fonctionnel. TRANCHER d'abord : BDR-001 périmé → marquer superseded, OU repasser par le hook. Ne pas lancer avant résolution.
## Helper `--help` / `help` sur tous les skills (option C) [WON'T-BUILD 2026-06-30 — mesuré non-rentable]
> ⛔ WON'T-BUILD (2026-06-30) : ABANDON tranché après mesure. RED comportemental (6 reps, /web-validate + /harden, SANS instruction) → **6/6 rendent déjà une aide riche ET s'arrêtent sans dispatcher** (même /harden n'a pas lancé l'audit). Le comportement supposé absent est déjà spontané (convention universelle --help). Seule valeur résiduelle = cohérence de format (6 formats divergents) → ROI insuffisant pour ~5 lignes dans un CLAUDE.md compressé ([[BDR-031]]) sur repo mono-user. 3e état : NON "fait" (rien construit), NON "ouvert" (on ne le fera pas). L'option globale réalisait l'intention BDR-001 ; per-skill toujours rejeté. Voir [[BDR-001]] (won't-build), [[LRN-080]], [[LRN-075]]. Design + subtasks ci-dessous = historique, non actionnables.
Problème : aucun skill ne gère `--help` aujourd'hui. `argument-hint` affiche juste la syntaxe en autocomplétion, pas de description/exemples. L'utilisateur doit lire le SKILL.md ou deviner.
Objectif : `/<skill> --help` (ou `/<skill> help`) affiche un bloc standardisé (description, args, exemples, cross-refs) et exit SANS dispatcher l'agent ni modifier quoi que ce soit.
@ -163,13 +164,13 @@ Design :
- **Skills à patcher** : `~/Documents/claude/skills/` = ~20 skills persos + skills-perso list pour référence. Ne PAS toucher skills-external/gstack (ownership externe) ni example-skills.
Subtasks :
- [ ] Créer `skills/lib/help-handler.md` — snippet réutilisable (détection + extraction + affichage)
- [ ] Définir format d'aide standard + section "ARGUMENTS" vs reuse de argument-hint
- [ ] Décider : sections ARGUMENTS/EXAMPLES doivent-elles être dans la frontmatter (nouveau champ YAML) ou dans le corps du SKILL.md (nouvelle section `## Help`) ?
- [ ] Patcher un skill pilote (`/validate`) — valider UX _(désormais `/web-validate` — renommé e5e673a)_
- [ ] Patcher les skills perso restants : analyze, bugfix, code-clean, commit-change, doc, feat, geo, graphify, harden, hotfix, init-project, make-pdf, onboard, plan-tune, plugin-check, refactor, seo, ship-feature, skills-perso, status, benchmark-models, context-save, context-restore
- [ ] Mettre à jour `~/.claude/CLAUDE.md` — mentionner convention --help disponible sur tous les skills perso
- [ ] Note : skills-external/gstack ont leur propre convention, ne pas toucher
- [-] Créer `skills/lib/help-handler.md` — snippet réutilisable (détection + extraction + affichage)
- [-] Définir format d'aide standard + section "ARGUMENTS" vs reuse de argument-hint
- [-] Décider : sections ARGUMENTS/EXAMPLES doivent-elles être dans la frontmatter (nouveau champ YAML) ou dans le corps du SKILL.md (nouvelle section `## Help`) ?
- [-] Patcher un skill pilote (`/validate`) — valider UX _(désormais `/web-validate` — renommé e5e673a)_
- [-] Patcher les skills perso restants : analyze, bugfix, code-clean, commit-change, doc, feat, geo, graphify, harden, hotfix, init-project, make-pdf, onboard, plan-tune, plugin-check, refactor, seo, ship-feature, skills-perso, status, benchmark-models, context-save, context-restore
- [-] Mettre à jour `~/.claude/CLAUDE.md` — mentionner convention --help disponible sur tous les skills perso
- [-] Note : skills-external/gstack ont leur propre convention, ne pas toucher
## Skill profiles (partition gstack par usage)
- [x] Plan
@ -280,7 +281,7 @@ Goal: universal gitflow across all `bchanot/*` Gitea repos. Lib built across pri
- [x] follow-up (a) — `submodule.gstack.ignore=dirty` committé dans `.gitmodules` — DONE (reconcile 2026-06-29 : commit `be1dcef` sur main, mergé via hotfix/gstack-ignore-gitmodules)
- [ ] follow-up (b) — zenquality `cleanup/post-smtp-fix` rename `<type>/<name>` ou finish+delete (AUTRE repo, optionnel)
## 2026-06-29 — MINOR-gate strengthening (doc-syncer) [branch feature/minor-gate-strengthening]
## 2026-06-29 — MINOR-gate strengthening (doc-syncer) [DONE — merged develop, branch deleted]
Read-first cartography refuted the literal premise: "strengthen MINOR gate" = 3 problems;
the literal one (blocking gate on MINOR) contradicts engraved [[BDR-036]]. Scope: ①+②, not B,
③ deferred. Built test-first (Iron Law).
@ -291,7 +292,7 @@ the literal one (blocking gate on MINOR) contradicts engraved [[BDR-036]]. Scope
- [x] FINISH — merged feature/minor-gate-strengthening → develop (`0f0bd7f`) on explicit signal
- [~] ③ branch-guard in doc-commit DEFERRED — duplicates protected-base predicate 3rd time (lib + hook + here); all migrated repos have the hook. Reconsider only for repos outside `gitflow init`
## 2026-06-29 — BLK-011 GSD ROADMAP post-FINISH [branch bugfix/blk-011-gsd-roadmap]
## 2026-06-29 — BLK-011 GSD ROADMAP post-FINISH [DONE — merged develop ce4391a, branch deleted]
User reframed: don't plumb a commit for the stranded ROADMAP — ask if gsd belongs at init at all.
Read refuted both option-premises (gsd ≫ roadmap; TODO ≠ gsd ROADMAP) but conclusion A held for a
stronger reason: speculative auto-bootstrap of an unused engine at creation is bad per se ([[LRN-072]]).
@ -301,7 +302,7 @@ stronger reason: speculative auto-bootstrap of an unused engine at creation is b
- [x] Capitalize — [[BLK-011]] resolved (true reason + premise trace) + [[LRN-072]] + CHANGELOG Removed + journal 2026-06-29 (cont. 2)
- [x] FINISH — merged bugfix/blk-011-gsd-roadmap → develop (`ce4391a`); develop pushed to origin (6 commits, SSH)
## 2026-06-29 — prune-memory hardening (RED-7/8 + index backfill) [branch bugfix/prune-memory-hardening]
## 2026-06-29 — prune-memory hardening (RED-7/8 + index backfill) [DONE — merged develop 73e12be, branch deleted]
LAST of 3 chantiers. Read-first cartography confirmed RED-7/8 + measured 34-row index drift.
- [x] RED-7 (example-priming) — fictionalized STEP-2 example to 9xx ids (live ids primed a wrong merge of complementary LRN-014/016); DETERMINISTIC test (run-deterministic.sh) per [[LRN-046]]. Caught its own ugrep false-green → /usr/bin/grep ([[LRN-074]]). [[LRN-073]]
- [x] RED-8 (added-negation inversion) — consciously ACCEPTED as documented limit in BACKLOG ([[LRN-047]]); no fragile guard built
@ -346,7 +347,7 @@ Subtasks (à détailler au lancement) :
- [x] Test final = reproduire l'inventaire 2026-06-29 (cat. 1-4 + contradiction BDR-001) comme oracle — DONE (run-reconcile.sh 20/20, fixtures neutres, RED prouvé rouge avant le vert)
- SHIPPED 2026-06-30 : feat `82e6322` + mémoire `6b512be` → merge `aede7af` (feature/reconcile-skill supprimée) → poussé origin/develop. main intact. BDR-041 + LRN-075/076/077 + EVAL-011 capitalisés.
## [QUEUED] skill /release-candidate — orchestrateur gitflow release (lib vérifiée, le tag est le gap)
## [SHIPPED 2026-06-30 — develop 0c0b748, released v4.0.0 (tag v4.0.0)] skill /release-candidate — orchestrateur gitflow release
Pertinent maintenant : develop ahead de main, prochaine étape gitflow = release.
VÉRIFIÉ dans lib/gitflow.sh (2026-06-30) — release CÂBLÉE, pas que hotfix :
- start base=develop (`gitflow_base_for` L49) ; `gitflow start release <ver>` positionne sur la branche (L71).
@ -361,7 +362,34 @@ Design (à la conception) : ORCHESTRATEUR au-dessus du gitflow existant — NE P
- push gaté (ASK, [[LRN-069]]) : main + develop + tag.
Subtasks (à détailler au lancement) :
- [ ] Décider : tag dans le skill VS étendre `gitflow finish` avec un arg tag optionnel (orchestrateur préféré — ne pas réécrire la mécanique)
- [ ] `skills/release-candidate/SKILL.md` — orchestration start→prep→finish→tag→push(gaté) + gate humain "WHEN to release"
- [ ] routage CLAUDE.md
- [ ] test (worktree jetable : prouver fan-out main+develop + tag présent sur main + branche supprimée)
- [x] Décider : tag fourni par le skill au-dessus de gitflow (mécanique non réécrite) — d3d6ced, [[BDR-042]]
- [x] `skills/release-candidate/SKILL.md` — orchestration start→prep→finish→tag→push(gaté) + gate humain "WHEN to release" — présent (d3d6ced)
- [x] routage CLAUDE.md — présent (~/.claude/CLAUDE.md "Cut a release → release-candidate")
- [x] test — prouvé par la release réelle 4.0.0 : fan-out main (709facf) + develop (4a00a60) + tag v4.0.0
## Auto-déclenchement des skills par intention [WON'T-BUILD 2026-06-30 — mesuré : Claude discrimine déjà (3 classes)]
> ⛔ WON'T-BUILD (2026-06-30) : 3e moot de la série (après [[BDR-001]] --help + [[BDR-043]]/[[LRN-082]] darwin re-baseline). Cartographie : routing = STACK L0(design-hook)→L1(superpowers « 1%→MUST invoke », dominant)→L2(prose CLAUDE.md)→L3(frontmatter)→L4(BDR-019). L1 SUR-détermine déjà l'invocation → « auto-call ? » = déjà oui. Reframe C : la vraie question = DISCERNEMENT, risque inversé under→**OVER**-routing. Mesure en VRAIES sessions fraîches (8 prompts / 3 classes) : CLEAR→route ✓, AMBIGUË→demande (refuse de deviner, investigue pour une question utile) ✓, TRIVIALE→s'abstient ✓. Le sur-routing soupçonné (L1 vs règles Workflow) NE se matérialise PAS — le modèle équilibre. Prose de bornage L2 = valeur fantôme + risque de DÉGRADER un discernement déjà bon. Voir [[BDR-044]] (reframe + verdict), [[LRN-083]] (RED sous-agent invalide), [[LRN-080]] (mesure-first, corroboré 3-in-a-row). RED sous-agent initial (0/6) RETIRÉ comme non-discriminant (plancher artefact). Design + subtasks ci-dessous = historique, non actionnables.
> ⏭️ (historique) NEXT, mais CADRÉ : **pas de design avant la mesure**. Jumeau méthodologique de [[BDR-001]] `--help` (won't-build après RED) — même piège architectural, même garde-fou [[LRN-080]] (mesurer avant d'instruire) + [[LRN-049]] (borner le bruit avant le marqueur). Les subtasks ci-dessous s'arrêtent à la mesure ; le design ne s'ouvre QUE si le RED valide la valeur.
**Contrainte architecturale (établie pour `--help`, non négociable) :**
Aucun mécanisme n'intercepte le message utilisateur pour *lancer* un skill. La harness ne route pas avant que le modèle réponde — un skill n'est invoqué QUE par le modèle (outil Skill). Donc « auto-call déterministe » = IMPOSSIBLE. Le seul levier sur l'invocation elle-même = instruire le MODÈLE à reconnaître l'intention et appeler le bon skill → **conformité-modèle, PAS déterminisme**. C'est une instruction de routage CLAUDE.md, pas un mécanisme.
- Nuance (raffinement) : une couche déterministe existe *en amont* du call, pas *sur* le call — un hook `UserPromptSubmit` peut détecter un signal et INJECTER un rappel de routage (le `design-toolchain` hook fait déjà exactement ça pour l'UI ; le banner session-start aussi). Détection déterministe + injection advisory ; le modèle reste celui qui tire. MAIS sur des verbes d'intention (« corrige », « crée », « bug »), un hook keyword serait BRUYANT (ces mots sont partout) — le design-hook s'en sort car « design/UI » est un signal rare. Donc le levier hook est probablement non-viable pour le cas large → ce qui **renforce** le besoin de borner aux signaux rares/non-ambigus.
**Substrat déjà en place :** [[BDR-019]] a retiré `disable-model-invocation` repo-wide → le modèle PEUT déjà self-router vers les skills (défaut = activé ; user l'avait vécu live : intention feature détectée, `ship-feature` voulu, jadis bloqué). Et la section « Skill routing » de CLAUDE.md existe déjà. Donc la **baseline du RED = le routage CLAUDE.md ACTUEL tel quel** ; le chantier n'a de valeur que si le RED prouve que cette prose SOUS-déclenche sur intention claire (exactement la logique --help : baseline = convention déjà là, question = est-ce qu'instruire en plus change quoi que ce soit).
**Le chantier COMMENCE par (rien d'autre avant) :**
- [x] (a) **Cartographier** le routage CLAUDE.md actuel — quels signaux → quels skills sont déjà censés router (« Skill routing » + « Design work » + descriptions de skills). État des lieux factuel, pas de jugement.
- [x] (b) **RED comportemental** ([[LRN-080]]) — prompts d'intention IMPLICITE, naturalistes, SANS instruction renforcée : « il y a un bug, debug », « on va créer X », « corrige ceci », « refactor ce module », « cut a release »… → le modèle invoque-t-il le bon skill, ou fait-il la tâche à la main en ignorant le skill ? N reps, plusieurs intents distincts.
- Garde-fou RED : **ne PAS amorcer**. Sessions fraîches / sous-agents, prompts naturels, zéro mention de « skill » / « routage » / « test » dans le prompt mesuré (sinon le modèle route parce qu'il SAIT qu'on le teste — contamination). Le RED `--help` était mécanique donc peu sensible à l'amorçage ; l'intent-routing l'est beaucoup plus → rigueur supérieure requise.
- [x] (c) **Décider selon le RED** :
- déjà bon (comme --help) → chantier MINCE, voire won't-build ; capitaliser le constat (3e état : mesuré non-rentable, ni fait ni ouvert).
- sous-déclenche → vraie valeur : renforcer la **prose de routage** (levier modèle) sur signaux CLAIRS uniquement — PAS un hook keyword (trop bruyant, cf. nuance ci-dessus).
**Scope à border au cadrage — NE PAS faire « tout skill jugé pertinent » :**
Tension réelle proactif vs intrusif. Auto-déclencher feat/bugfix sur intention CLAIRE et non-ambiguë = sain. « Déclenche tout skill jugé pertinent » = RISQUÉ (faux déclenchements, skills non sollicités, flux interrompus). Réglage cible ([[LRN-049]] borner le bruit) = déclencher sur signaux d'intention CLAIRS et non-ambigus ; **ambigu → DEMANDER, pas auto-déclencher**. À définir précisément SI (et seulement si) le RED valide : table `signal → skill` + la frontière exacte de l'ambiguïté.
## 2026-06-30 — session-close follow-ups (promoted from BLK-013 / BDR-043)
- [x] (a) Harden install-plugins.sh Step 1 — guarantee `npm` on apt-`nodejs` hosts (detect missing npm + `corepack enable npm`), not just check `node >=22`. Fix-forward for [[BLK-013]] — stops `make plugin` Error 127 recurring on any fresh apt machine.
[done 2026-07-01 : unconditional npm guard after Node block (corepack enable npm → distro `install npm` fallback → fatal exit 1 w/ clear msg). Catches node>=22-present-but-npm-absent (NODE_OK short-circuit). shellcheck clean, bash -n OK. Fresh-apt live validation pending (no npm-less host to hand). branch bugfix/install-plugins-npm-guard.]
- [x] (b) Re-baseline darwin on the 5 ex-broken gstack skills (`benchmark-models`, `context-restore`, `context-save`, `make-pdf`, `plan-tune`) — now repaired and back in scope ([[BDR-043]], trigger cleared). Verify `results.tsv` still marks them `status=error` first. (Promoted from BDR-043's action-field — not an item the user authored.)
[resolved-MOOT 2026-06-30 : won't-run. BDR-043 cleared only motif (a) of BDR-015's TWO exclusion grounds (symlinks repaired ✅); motif (b) external-ownership INTACT — the 5 resolve to skills-external/gstack/ (submodule), darwin optimizes by EDITING SKILL.md → would dirty the submodule (forbidden [[LRN-070]]). Re-baseline = unactionable score. + results.tsv gone (wiped by 23/06 make-plugin reinstall) → not even a re-baseline, a fresh-from-zero one. Geometric trigger lifted, value trigger intact — twin of --help [[LRN-080]]. See [[LRN-082]]. Not "done", not "open": MOOT.]

View File

@ -168,23 +168,27 @@ Every git action follows gitflow — inside a skill AND for ad-hoc commits made
outside one on direct request. The model is universal across all projects.
### Branch model
`main` (prod) · `develop` (integration, off main) · `feature/*` + `bugfix/*`
(off develop → develop) · `release/*` (off develop → main + back-merge develop)
· `hotfix/*` (off main → main + develop [+ any open release/*]). `master`→`main`
everywhere.
`main` (prod) · `develop` (integration, off main) · `feature/*` + `bugfix/*` +
`chore/*` (off develop → develop; `chore/*` = memory/doc maintenance, e.g.
standalone `/capitalize` `/prune-memory` `/reconcile`) · `release/*` (off develop →
main + back-merge develop) · `hotfix/*` (off main → main + develop [+ any open
release/*]). `master`→`main` everywhere.
### Rules for every git action
- **Never commit code directly on `main` or `develop`.** Branch first from the
correct base, named `<type>/<name>`. (`.claude/**` memory/config commits are
exempt — they follow the work, not the code's gitflow.)
hook-exempt — they follow the work; but *standalone* memory/doc skills branch to
`chore/*` via the aiguillage rather than lean on that exemption.)
- **Branch + merge via the lib, never by hand** — the directed-merge + hotfix
fan-out logic lives there once:
`bash ~/.claude/lib/gitflow.sh start <type> <name>` · `… finish`.
- **`gitflow finish` (merge) only on an explicit human signal** ("merge it",
"feature OK") — never because tests pass, a plan step says "merge", or a verb
("ship") implied it.
- **Assistance flows** (`/feat` `/bugfix` `/hotfix`) auto-branch on a protected
base (the aiguillage); on a working branch they commit in place, never finish.
- **Assistance flows** (`/feat` `/bugfix` `/hotfix`) AND **standalone memory/doc
skills** (`/capitalize` `/close` `/prune-memory` `/reconcile`, type `chore`)
auto-branch on a protected base (the aiguillage); on a working branch they commit
in place, never finish.
- **New/onboarded projects** get the model + the versioned pre-commit hook via
`gitflow init` (init-project STEP 5f, onboard STEP 2.6).

View File

@ -101,6 +101,9 @@ Versions are pinned in `plugins.lock.json`. To update: edit the file, then re-ru
| `/doc` | Documentation audit and sync — detect stale docs, patch |
| `/seo` | Full SEO/GEO audit and optimization |
| `/commit-change` | Smart commit grouping from staged/unstaged changes |
| `/gitflow` | Gitflow branch operations — bootstrap main+develop, start a typed branch, directed merge |
| `/release-candidate` | Cut a versioned release — finalize version.txt + CHANGELOG, merge develop→main, tag, push |
| `/deploy` | Run a project's deploy from its committed runbook — instantiate the delta, resume cold |
| `/graphify` | Codebase knowledge graph — navigation for large-scope tasks |
| `/plugin-check` | Check active plugins vs project needs — recommend enable/disable |
| `/health` | Run setup diagnostic |
@ -109,6 +112,7 @@ Versions are pinned in `plugins.lock.json`. To update: edit the file, then re-ru
| `/audit-delta` | Recurring audit of changes since last run (norms, bugs, dead code, security) |
| `/capitalize` | Flush uncapitalized context + reconcile TODO before /clear or /compact (`--ritual` adds the end-of-session reflection) |
| `/prune-memory` | Curate and compress the .claude/memory/ registries |
| `/reconcile` | Confront declared status (TODO, registries) against real git/fs state — surface stale items |
| `/pdf-translate` | Translate a PDF to another language, output as HTML (via Vision) |
| `/close` | End-of-session ritual — alias for `/capitalize --ritual` (dedup + TODO reconcile + 3-question reflection) |
| `/harden` | Web hardening audit — HTTPS/TLS, HSTS, CSP, security headers |

View File

@ -103,17 +103,22 @@ Tu veux...
| Docs périmées | `/doc` |
| SEO/GEO audit | `/seo` (GEO seul → `/geo`) |
| Commit structuré | `/commit-change` |
| Branches gitflow (start/finish) | `/gitflow` |
| Couper une release (develop→main) | `/release-candidate` |
| Déployer via runbook | `/deploy` |
| Navigation codebase large | `/graphify` |
| Lister ses skills | `/skills-perso` |
| Plugins OK ? | `/plugin-check` |
| Audit du delta (depuis dernier run) | `/audit-delta` |
| Flush mémoire + TODO avant /clear | `/capitalize` |
| Curer la mémoire | `/prune-memory` |
| État réel du travail ouvert | `/reconcile` |
| Fin de session (= /capitalize --ritual) | `/close` |
| Audit web (TLS, CSP, headers) | `/harden` |
| Validité HTML/CSS + a11y | `/web-validate` |
| Visibilité IA (GEO seul) | `/geo` |
| Livraison client finale | `/client-handover` |
| Traduire un PDF | `/pdf-translate` |
| Changer profil skills | `/profile` |
| Rien ne marche | `/health` |
@ -138,6 +143,9 @@ Tu veux...
| `/seo` | Audit SEO/GEO complet | Détecte framework, audite meta/OG/sitemap |
| `/geo` | Audit GEO uniquement (IA) | Visibilité ChatGPT, Perplexity, Claude, Gemini… |
| `/commit-change` | Commits bien structurés | Groupe les changements par unité logique |
| `/gitflow` | Opérations de branches gitflow | Bootstrap main+develop, branche typée, merge dirigé |
| `/release-candidate` | Couper une release versionnée (develop en avance sur main) | Finalise version.txt + CHANGELOG, merge develop→main, tag, push |
| `/deploy` | Déployer via le runbook du projet | Instancie le delta depuis le dernier deploy, reprend à froid |
| `/graphify` | Navigation codebase large-scope | Knowledge graph, pour tâches multi-fichiers |
| `/skills-perso` | Lister ses skills personnels | Skills créés dans ~/.claude/skills/ |
| `/health` | Quand quelque chose ne fonctionne pas | Lance doctor.sh |
@ -145,10 +153,12 @@ Tu veux...
| `/audit-delta` | Audit récurrent du delta depuis le dernier run | Axes : conformité / bugs / dead code / sécurité |
| `/capitalize` | Avant /clear ou /compact | Flush contexte non capitalisé + réconcilie .claude/tasks/TODO.md |
| `/prune-memory` | Registres trop longs / bruyants | Curation : merge, superseded, compression |
| `/reconcile` | Connaître l'état réel du travail ouvert (TODO/registres douteux) | Confronte statut déclaré vs git/fs réel |
| `/close` | Fin de session | Alias de /capitalize --ritual — dedup + TODO + réflexion 3 questions |
| `/harden` | Audit sécurité web (SSL, CSP, HSTS) | Projet web avec config HTTP |
| `/web-validate` | Audit W3C + WCAG a11y | Avant livraison projet web |
| `/client-handover` | Livraison client | Audits finaux + livrable brandé |
| `/pdf-translate` | Traduire un PDF vers une autre langue | Sortie HTML fidèle (images, layout, style préservés) |
| `/profile` | Changer le profil de skills | design / dev / qa / audit / minimal |
> Cette table couvre les skills personnels principaux. Les plugins (gstack,

View File

@ -162,6 +162,32 @@ if [ "$NODE_OK" = false ]; then
fi
fi
# --- npm (bundled with Node, but distro `apt install nodejs` can ship it separately) ---
# BLK-013 fix-forward: node>=22 present does NOT imply npm present. GSD (gsd-pi)
# and ctx7 install via `npm install -g`, so a missing npm makes `make plugin`
# die with Error 127 mid-run. The Node block above short-circuits when node is
# already recent (NODE_OK=true) and never checks npm, so guarantee it here.
if ! command -v npm &>/dev/null; then
info "npm missing (Node without npm) — enabling via corepack, else package manager..."
if command -v corepack &>/dev/null; then
sudo corepack enable npm 2>/dev/null || corepack enable npm 2>/dev/null || true
fi
if ! command -v npm &>/dev/null; then
case $OS in
linux-apt) sudo apt-get install -y npm || true ;;
linux-dnf) sudo dnf install -y npm || true ;;
linux-pacman) sudo pacman -S --noconfirm npm || true ;;
macos) brew install node || true ;; # brew's node bundles npm
*) : ;;
esac
fi
if command -v npm &>/dev/null; then
ok "npm $(npm --version)"
else
err "npm still missing — GSD/ctx7 need it; install npm manually then re-run"; exit 1
fi
fi
# --- Rust + Cargo (for RTK) ---
if command -v cargo &>/dev/null; then
ok "Rust/Cargo $(cargo --version | awk '{print $2}')"

View File

@ -22,8 +22,9 @@ echo ""
# ── 1. Check prerequisites ──
echo "── Checking prerequisites..."
# node + npm drive the Claude Code CLI install below. On a fresh machine
# they may be absent — install the current LTS via nvm instead of aborting.
# node + npm are needed by the plugins step (install-plugins.sh: gsd-pi et al.);
# Claude Code itself now installs via its own native installer below. On a fresh
# machine node/npm may be absent — install the current LTS via nvm, not abort.
install_node_via_nvm() {
info "Node.js/npm missing — installing LTS via nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
@ -54,9 +55,20 @@ ok "npm $(npm -v)"
# ── 2. Install Claude Code CLI ──
echo ""
echo "── Installing Claude Code (latest)..."
echo "── Installing Claude Code..."
if npm install -g @anthropic-ai/claude-code@latest; then
# Idempotent + official channel. Skip if already present (mirrors the RTK/GSD
# guard) — the binary is a native-installer symlink at ~/.local/bin/claude that
# self-updates. On a fresh machine install via the official native installer
# (code.claude.com/docs quickstart), NOT npm: npm is no longer a documented
# channel, would collide with the native symlink (EEXIST), and bypasses the
# built-in auto-update. Upgrades are `make update`'s job, not first-time install.
if command -v claude &>/dev/null; then
ok "Claude Code already installed ($(claude --version 2>/dev/null | head -1))"
elif curl -fsSL https://claude.ai/install.sh | bash; then
# Native installer targets ~/.local/bin — put it on PATH for the auth +
# verification steps that follow in this same (non-login) shell.
export PATH="$HOME/.local/bin:$PATH"
ok "Claude Code installed: $(claude --version 2>/dev/null || echo 'unknown')"
else
err "Claude Code installation failed"

View File

@ -1,26 +1,41 @@
# Gitflow aiguillage — assistance flows branch on a protected base
# Gitflow aiguillage — branch on a protected base before writing
Assistance flows (`/feat`, `/bugfix`, `/hotfix`) commit IN PLACE on a working
branch — the frequent case, behavior unchanged. But they must NEVER commit code
on a protected base (`main`/`develop`). Run this check **before editing any
file**. The caller passes its TYPE: feat→`feature`, bugfix→`bugfix`,
hotfix→`hotfix`.
Flows that WRITE — code, OR standalone memory/doc work — must NEVER commit on a
protected base (`main`/`develop`). Run this check **before editing any file**.
```bash
bash "$HOME/.claude/lib/gitflow.sh" protected-base && echo PROTECTED || echo WORKING
```
- **WORKING** (`feature/*`, `bugfix/*`, `hotfix/*`, or any non-protected branch)
→ proceed; you commit in place on this branch. Nothing changes.
- **WORKING** (`feature/*`, `bugfix/*`, `hotfix/*`, `chore/*`, or any non-protected
branch) → proceed; you commit in place on this branch. Nothing changes.
- **PROTECTED** (`main`/`develop`) → branch first, do NOT commit here:
```bash
bash "$HOME/.claude/lib/gitflow.sh" start <YOUR-TYPE> <short-kebab-name>
```
`<short-kebab-name>` derived from the request. Then do the work on the new branch.
**Never run `gitflow finish`** — assistance flows commit, they do not merge.
Integration is a separate, human-gated step (the `gitflow` skill).
The caller passes its TYPE:
Note: `hotfix` branches off **main** (prod) even when invoked from `develop`
that is the gitflow definition of a hotfix. For a dev-scoped small fix, use
`/bugfix` (branches off develop).
| Caller | TYPE | Base |
|--------|------|------|
| `/feat` | `feature` | develop |
| `/bugfix` | `bugfix` | develop |
| `/hotfix` | `hotfix` | main |
| `/capitalize` · `/close` · `/prune-memory` · `/reconcile` | `chore` | develop |
The `chore` row = **standalone memory/doc work**: the registry / TODO / doc
reconciliation & curation skills, run OUTSIDE an assistance flow. Inside `/feat`
`/bugfix` `/hotfix` `/ship-feature` a working branch already exists (this check
returns WORKING) and the memory commit rides it. The aiguillage only fires when
such a skill is invoked directly on `main`/`develop` — i.e. memory IS the work,
with no code branch to follow. That is the leak it closes: the `.claude/**` hook
exemption still lets a *manual* memory commit through on a protected base, but a
skill-driven one now branches to `chore/*` first.
**Never run `gitflow finish`** — these flows commit, they do not merge. Integration
is a separate, human-gated step (the `gitflow` skill).
Note: `hotfix` branches off **main** (prod) even when invoked from `develop` — that
is the gitflow definition of a hotfix. For a dev-scoped small fix, use `/bugfix`
(branches off develop).

View File

@ -32,6 +32,9 @@ chk "protected develop" 'gitflow_protected_base develop'
chk "not protected feat" '! gitflow_protected_base feature/x'
chk "base feature=develop" '[ "$(gitflow_base_for feature)" = develop ]'
chk "base hotfix=main" '[ "$(gitflow_base_for hotfix)" = main ]'
chk "type chore" '[ "$(gitflow_branch_type chore/x)" = chore ]'
chk "base chore=develop" '[ "$(gitflow_base_for chore)" = develop ]'
chk "not protected chore" '! gitflow_protected_base chore/x'
echo "T2 — init fresh (BLK-010 root commit)"
newrepo fresh; echo scaffold > README.md; hookon
@ -92,6 +95,16 @@ chk "merged into develop" 'git log develop --oneline | grep -q "Merge feature/f1
chk "main untouched" "[ \"\$(git rev-parse main)\" = \"$main_before\" ]"
chk "branch deleted" '! git rev-parse --verify -q refs/heads/feature/f1 >/dev/null'
echo "T6b — finish chore → develop only (standalone memory/doc maintenance)"
newrepo finchore; echo a>a; hookon; gitflow_init >/dev/null 2>&1
gitflow_start chore c1 >/dev/null 2>&1
mkdir -p .claude/memory; echo m>.claude/memory/x.md; git add -A; git commit -q -m "chore(memory)"
main_before="$(git rev-parse main)"
gitflow_finish >/dev/null 2>&1
chk "chore merged into develop" 'git log develop --oneline | grep -q "Merge chore/c1 into develop"'
chk "chore main untouched" "[ \"\$(git rev-parse main)\" = \"$main_before\" ]"
chk "chore branch deleted" '! git rev-parse --verify -q refs/heads/chore/c1 >/dev/null'
echo "T7 — finish hotfix → main + develop fan-out"
newrepo finhot; echo a>a; hookon; gitflow_init >/dev/null 2>&1
gitflow_start hotfix h1 >/dev/null 2>&1; echo p>patch.txt; git add patch.txt; git commit -q -m patch
@ -119,7 +132,7 @@ chk "idempotent 2nd run" "[ \"$before\" = \"\$(md5sum .gitignore)\" ]"
echo "T10 — COHERENCE: hook verdict == lib predicate (drift detector, #4)"
newrepo coh; echo a>a; hookon; gitflow_init >/dev/null 2>&1
for br in main develop feature/x bugfix/y release/z hotfix/w master mainline qa; do
for br in main develop feature/x bugfix/y release/z hotfix/w chore/m master mainline qa; do
if gitflow_protected_base "$br"; then lib=protected; else lib=open; fi
git checkout -q -B "$br" 2>/dev/null
printf 'x\n' >> a; git add a

View File

@ -21,7 +21,7 @@ GITFLOW_GITIGNORE_TEMPLATE="${GITFLOW_GITIGNORE_TEMPLATE:-$_GITFLOW_LIB_DIR/../t
# ── predicates / pure helpers ────────────────────────────────────────────────
# echo the gitflow type of a branch: feature|bugfix|release|hotfix|main|develop|other
# echo the gitflow type of a branch: feature|bugfix|release|hotfix|chore|main|develop|other
gitflow_branch_type() {
local br="${1:-$(git symbolic-ref --short -q HEAD 2>/dev/null)}"
case "$br" in
@ -31,6 +31,7 @@ gitflow_branch_type() {
bugfix/*) echo bugfix ;;
release/*) echo release ;;
hotfix/*) echo hotfix ;;
chore/*) echo chore ;;
*) echo other ;;
esac
}
@ -46,7 +47,7 @@ gitflow_protected_base() {
# echo the base a given type must fork from.
gitflow_base_for() {
case "$1" in
feature|bugfix|release) echo "$GITFLOW_DEVELOP" ;;
feature|bugfix|release|chore) echo "$GITFLOW_DEVELOP" ;;
hotfix) echo "$GITFLOW_MAIN" ;;
*) echo "gitflow: unknown type '$1'" >&2; return 2 ;;
esac
@ -103,7 +104,7 @@ gitflow_finish() {
br="$(git symbolic-ref --short -q HEAD)" || { echo "gitflow_finish: detached HEAD" >&2; return 3; }
type="$(gitflow_branch_type "$br")"
case "$type" in
feature|bugfix)
feature|bugfix|chore)
_gitflow_merge_into "$GITFLOW_DEVELOP" "$br" && _gitflow_delete "$br" ;;
release)
_gitflow_merge_into "$GITFLOW_MAIN" "$br" \

View File

@ -50,6 +50,13 @@ Running `/capitalize` right after a ritual should propose (near) nothing.
This skill is NOT `/prune-memory` (registry curation — merge, compress,
mark-superseded). It only appends.
## Gitflow aiguillage (before any write)
Before STEP 4 writes anything, follow `$HOME/.claude/lib/gitflow-aiguillage.md`
— this skill's TYPE = `chore`. On `main`/`develop` it branches to `chore/<name>`
off develop, so the memory commit lands on a branch, never direct on a protected
base; on a working branch it proceeds in place. Never `gitflow finish` (human-gated).
## STEP 0 — PRECHECK
```bash

View File

@ -34,4 +34,7 @@ Ritual answers are deduped like any other candidate — a dup is dropped and its
existing ID shown, not re-logged. This is the upgrade over the legacy `/close`,
which wrote ritual answers fresh with no dedup.
The gitflow aiguillage (branch to `chore/*` on a protected base before writing)
runs inside `capitalize` — not duplicated here.
→ Use the Skill tool to launch `capitalize` with argument `--ritual`.

View File

@ -68,11 +68,13 @@ gives a **real-time, explicit go for THIS merge** — "merge it", "feature OK",
All of these mean: present the merge as a question, then wait for the explicit go.
## Aiguillage (assistance skills)
## Aiguillage (assistance + standalone memory/doc skills)
On a protected base, assistance skills (`feat`/`bugfix`/`hotfix`) call
`start <type>` to branch first; on a working branch they commit in place. Same
`protected-base` predicate the out-of-skill hook uses.
On a protected base, assistance skills (`feat`/`bugfix`/`hotfix`) AND the standalone
memory/doc skills (`capitalize`/`close`/`prune-memory`/`reconcile`, TYPE `chore`)
call `start <type>` to branch first; on a working branch they commit in place. Same
`protected-base` predicate the out-of-skill hook uses. Caller→type map + rationale:
`lib/gitflow-aiguillage.md`.
## Common Mistakes

View File

@ -62,6 +62,13 @@ If working tree is dirty on any registry file → STOP with: "Commit or
stash pending changes in `.claude/memory/` first. Skill writes in-place.
Git is the only backup."
## STEP 0b — Gitflow aiguillage (after PRECHECK, before any write)
PRECHECK first (clean tree = the backup). Then follow
`$HOME/.claude/lib/gitflow-aiguillage.md` — this skill's TYPE = `chore`. On
`main`/`develop` it branches to `chore/<name>` off develop so the curation lands
on a branch; on a working branch it proceeds in place. Never `gitflow finish`.
## STEP 1 — AUDIT (per registry)
For each target registry (filter by `$ARGUMENTS` or all 5):

View File

@ -34,6 +34,8 @@ Not for: curating/compressing registries → `/prune-memory`. The skill never ed
Plus **contradiction candidates**`reconcile_contradiction_candidates`: accepted-BDR ⇄ open-chantier overlap, surfaced for human review.
## The gate (mandatory)
**Before applying (A/B):** follow `$HOME/.claude/lib/gitflow-aiguillage.md` — TYPE `chore`. On `main`/`develop` the write-back branches to `chore/<name>` off develop first, so a reconciled TODO never lands direct on a protected base; on a working branch it applies in place. Never `gitflow finish` (human-gated).
Reconciling the TODO edits a tracked file → never silent. Show the proposed diff, then ask: **A** apply all · **B** select a subset · **C** touch nothing. Registries stay READ-ONLY (append-only; curation is `/prune-memory`).
## Honest limits (do not over-read the guarantee)

View File

@ -27,7 +27,15 @@ echo "── Updating Claude Code CLI..."
if command -v claude &>/dev/null; then
CURRENT_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
info "Current: $CURRENT_VER"
if npm install -g @anthropic-ai/claude-code@latest 2>/dev/null; then
# Use the updater that matches the install channel: npm-managed installs
# update via npm; native-installer installs self-update via `claude update`
# (npm would EEXIST on the ~/.local/bin/claude symlink it does not own).
if npm ls -g @anthropic-ai/claude-code &>/dev/null; then
UPDATE_CMD=(npm install -g @anthropic-ai/claude-code@latest)
else
UPDATE_CMD=(claude update)
fi
if "${UPDATE_CMD[@]}" &>/dev/null; then
NEW_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
if [ "$CURRENT_VER" = "$NEW_VER" ]; then
ok "Claude Code already up to date ($NEW_VER)"
@ -35,7 +43,7 @@ if command -v claude &>/dev/null; then
ok "Claude Code updated: $CURRENT_VER$NEW_VER"
fi
else
warn "Claude Code update failed — try manually: npm install -g @anthropic-ai/claude-code@latest"
warn "Claude Code update failed — try manually: ${UPDATE_CMD[*]}"
fi
else
warn "Claude Code not found — install first with: make install"