Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ec54ee61 | ||
|
|
caf3d01487 | ||
|
|
90dc7d854d | ||
|
|
1f2c1cc6e7 | ||
|
|
9c024064bb | ||
|
|
2393ca536c | ||
|
|
020737de57 | ||
|
|
6be627e246 | ||
|
|
01f9ebb57b | ||
|
|
8dc4027c4b | ||
|
|
2d76233b02 | ||
|
|
8ca1bb7bab | ||
|
|
0a2e832a66 | ||
|
|
8f001ec868 | ||
|
|
e8807a7333 | ||
|
|
53bd7beee8 | ||
|
|
efe33b76c5 | ||
|
|
c09f2b2630 | ||
|
|
5d348a711f | ||
|
|
437697e961 | ||
|
|
09200c5274 | ||
|
|
e591510160 | ||
|
|
5b03ac28a2 | ||
|
|
c3ba540372 | ||
|
|
4a00a60494 |
@ -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.
|
||||
|
||||
@ -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,10 @@ 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 |
|
||||
|
||||
---
|
||||
|
||||
@ -77,6 +81,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 +660,52 @@ 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 L0–L4 + 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".
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 L0–L4, 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).
|
||||
|
||||
@ -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.]
|
||||
|
||||
18
CLAUDE.md
18
CLAUDE.md
@ -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).
|
||||
|
||||
|
||||
@ -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 |
|
||||
|
||||
10
USAGE.md
10
USAGE.md
@ -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,
|
||||
|
||||
@ -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}')"
|
||||
|
||||
20
install.sh
20
install.sh
@ -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"
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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" \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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`.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user