Compare commits
No commits in common. "2393ca536ce66709caf3119e6d024522760df768" and "2d76233b025d03b728647b5c3b784b3cd98cf78b" have entirely different histories.
2393ca536c
...
2d76233b02
@ -33,7 +33,6 @@ rules:
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
@ -166,14 +165,3 @@ rules:
|
||||
- **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]].
|
||||
|
||||
---
|
||||
|
||||
## 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]].
|
||||
|
||||
@ -67,7 +67,6 @@ rules:
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
@ -694,17 +693,3 @@ rules:
|
||||
- (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.
|
||||
|
||||
@ -290,5 +290,3 @@ rules:
|
||||
|
||||
## 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.
|
||||
|
||||
@ -104,7 +104,6 @@ rules:
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
@ -916,13 +915,3 @@ rules:
|
||||
- **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).
|
||||
|
||||
20
install.sh
20
install.sh
@ -22,9 +22,8 @@ echo ""
|
||||
# ── 1. Check prerequisites ──
|
||||
echo "── Checking prerequisites..."
|
||||
|
||||
# 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.
|
||||
# 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.
|
||||
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
|
||||
@ -55,20 +54,9 @@ ok "npm $(npm -v)"
|
||||
|
||||
# ── 2. Install Claude Code CLI ──
|
||||
echo ""
|
||||
echo "── Installing Claude Code..."
|
||||
echo "── Installing Claude Code (latest)..."
|
||||
|
||||
# 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"
|
||||
if npm install -g @anthropic-ai/claude-code@latest; then
|
||||
ok "Claude Code installed: $(claude --version 2>/dev/null || echo 'unknown')"
|
||||
else
|
||||
err "Claude Code installation failed"
|
||||
|
||||
@ -27,15 +27,7 @@ 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"
|
||||
# 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
|
||||
if npm install -g @anthropic-ai/claude-code@latest 2>/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)"
|
||||
@ -43,7 +35,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: ${UPDATE_CMD[*]}"
|
||||
warn "Claude Code update failed — try manually: npm install -g @anthropic-ai/claude-code@latest"
|
||||
fi
|
||||
else
|
||||
warn "Claude Code not found — install first with: make install"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user