# bootstrap-claude-md-merge ## Goal project-bootstrap upgrade mode currently treats `CLAUDE.md` as binary: either append the entire template (causing duplicate trigger lines) or leave it untouched. Result: projects bootstrapped before v1.2.0 silently miss new canonical triggers like `check across all projects` (→ `using-projects-meta`) and `we're on Windows` (→ `active-platform`) when re-run on the upgrade path. Fix: turn Step 5 into an idempotent merge — read existing CLAUDE.md, diff against the template, append only missing canonical lines after user confirm. Re-runs become no-ops. ## Key files - `skills/project-bootstrap/SKILL.md:220-249` — Step 5 (the broken binary choice) - `skills/project-bootstrap/assets/CLAUDE.md.template` — canonical trigger set - `skills/project-bootstrap/README.md` — public surface, mention idempotency - `dist/project-bootstrap.skill` — rebuild after install - `~/.claude/skills/project-bootstrap/` — reinstall target ## Decisions log - 2026-04-30: Diff strategy — substring match per template line against existing file (trim + lowercase). A trigger is "present" if any existing line contains the template trigger text. Avoids false-positive duplicates when user has rephrased a trigger but preserves canonical wording for missing ones. Rejected: full line-equality match (too brittle — user comments / case differences would re-add). - 2026-04-30: Confirmation gate stays — show user the diff (N lines to append) before touching the file. Idempotent run with no missing lines = silent no-op. - 2026-04-30: Version bump 1.2.0 → 1.3.0. Behavior change visible to users on every upgrade — minor bump fits semver intent. ## Open questions - [ ] Should the platform line (`we're on Windows`) be substituted to match the host during merge, the same way init does it? Decision: yes — if existing file has no `we're on (Windows|Linux|macOS)` line, append the host-appropriate one. If it has any of the three, leave it (user may have intentionally pinned a different platform). ## Completed steps - [x] open task - [x] patch Step 5 in SKILL.md (read → diff → confirm → append) — split Init / Upgrade-merge - [x] bump version 1.2.0 → 1.3.0 in SKILL.md frontmatter - [x] update `skills/project-bootstrap/README.md` `CLAUDE.md` row to note idempotent merge - [x] update root `README.md` + `README.ru.md` upgrade-mode paragraph - [x] reinstall + rebuild dist (`bash scripts/install.sh project-bootstrap && bash scripts/build.sh project-bootstrap`); verified `version: 1.3.0` on disk + Step 5 split - [x] wiki: concept page `.wiki/concepts/bootstrap-claude-md-merge.md`, index entry, log entry - [x] commit - [x] STATUS.md: 🔴 → 🟢 - [x] decision on platform line — preserve if user pinned non-host one (case-insensitive `we're on (windows|linux|macos)` match) ## Notes Existing related task `[bootstrap-recommend-projects-meta]` (Step 5.7) is **machine-level** detection (recommend `setup-projects-meta` if MCP server not registered). This task is **project-level** merge of the trigger line into the project's CLAUDE.md. They compose cleanly: 5.7 makes the trigger functional on the host, this task ensures the trigger is actually present in the file.