docs(claude): tighten version-consistency rules + add merge recovery procedure

After several merges from master where VERSION + package.json +
CHANGELOG.md drifted out of sync (each merge hit conflicts on those
three files; auto-merge sometimes resolved silently in the wrong
direction), CLAUDE.md gets an explicit drift-recovery checklist + a
3-line paste-ready audit command anyone can run.

Three additions to the existing "Version locations" section:

1. **Mandatory audit command** — three echo lines that print VERSION,
   package.json version, and the top CHANGELOG header. All three MUST
   match the wave's `MAJOR.MINOR.PATCH.MICRO`. Designed for paste-after-
   every-merge use.

2. **Merge-conflict recovery procedure** — exact sed/echo patterns for
   resolving VERSION + package.json + CHANGELOG conflicts, in the order
   to apply them. Names the anti-pattern (mixing `git checkout --ours`
   on the trio) that's bitten us before.

3. **Pre-push gate** — re-run the audit before `git push` of any merge
   commit. /ship Step 12 catches drift but only if you actually run
   /ship; manual pushes skip the check.

Confirmed consistent at d361482a, 7e8f6960, 65a5994a (every merge
commit on this branch). The doc gap was the rules being too loose,
not the rules being wrong — this beefs up the procedural side so the
next merge can't silently desync.
This commit is contained in:
Garry Tan
2026-05-10 12:57:12 -07:00
parent 65a5994a9b
commit fe050ae0ba
+77
View File
@@ -834,6 +834,83 @@ than master's VERSION. If a queue collision claims your version on
master before yours lands, /ship's queue-aware allocator (Step 12)
will detect drift and re-bump on the next run.
### Mandatory version-consistency audit (run after EVERY merge or commit that touches VERSION, package.json, or CHANGELOG)
**The trio MUST agree.** Every merge from master will hit conflicts on
VERSION + package.json + CHANGELOG.md because master ships its own
version bumps. Auto-merge sometimes resolves these silently in unexpected
ways. After any merge, branch update, or version-related edit, run this
audit. It's three lines and never lies:
```bash
echo "VERSION: $(cat VERSION)"
echo "package.json: $(node -e 'process.stdout.write(require("./package.json").version)')"
grep -E "^## \[" CHANGELOG.md | head -1
```
All three MUST show the same `MAJOR.MINOR.PATCH.MICRO`. If any one
disagrees, you have not finished the merge. Fix it before pushing or
shipping. There is no situation in which "I'll fix it next push" is OK,
because:
- A green local test run with mismatched VERSION/package.json still
fails the CI version-gate.
- A green CHANGELOG entry under the wrong version header silently lies
to release-notes consumers.
- /ship's Step 12 idempotency check classifies a mismatch as
`DRIFT_UNEXPECTED` and HALTS — but only if you remember to run /ship
before pushing. Manual `git push` skips the check.
### Merge-conflict recovery procedure (memorize this)
When `git merge origin/master` reports conflicts on VERSION,
package.json, or CHANGELOG.md, resolve in this exact order:
1. **VERSION** — overwrite with the wave's version (`echo -n "X.Y.Z.W"
> VERSION`). Highest semver wins; do NOT take master's lower version.
2. **package.json** — strip the conflict markers, keep the wave's
version line. Sed pattern:
`sed -i.bak '/^<<<<<<< HEAD$/d; /^=======$/,/^>>>>>>> /d' package.json && rm package.json.bak`
(assumes ours is above the `=======`).
3. **CHANGELOG.md** — strip ALL three conflict markers; both your entry
and master's entry stay. Sed pattern:
`sed -i.bak '/^<<<<<<< HEAD$/d; /^=======$/d; /^>>>>>>> origin\/master$/d' CHANGELOG.md && rm CHANGELOG.md.bak`
Then verify your entry is the topmost `## [X.Y.Z.W]` and master's
newer-than-yours entries (if any) sit below.
4. **Run the 3-line audit above.** If it doesn't show your version on
all three lines, you missed a marker.
5. **Run `bun install`** to refresh `bun.lock` against the resolved
`package.json`. Stage and commit if it changed.
6. **Run `bun run typecheck`** before committing the merge.
7. Only THEN run `git commit` for the merge.
If the audit shows drift after step 4, do NOT proceed to step 5. Re-run
steps 1-3 against the actual file content; you missed a marker or
resolved one in the wrong direction.
**Anti-pattern to avoid:** Resolving via `git checkout --ours package.json`
and `git checkout --theirs scripts/test-shard.sh` mixed in the same
commit. The selective directional resolution is fine, but on
VERSION/package.json/CHANGELOG specifically, ALWAYS use the explicit
`echo > VERSION` + sed-strip-markers pattern above. The directional
checkout flags have bitten us when the conflict shape was unexpected
(e.g. master stripped a section we expected to keep).
### Pre-push gate (manual; tighten when you remember to)
Before any `git push` of a merge commit, run the audit one more time:
```bash
echo "VERSION: $(cat VERSION)"
echo "package.json: $(node -e 'process.stdout.write(require("./package.json").version)')"
grep -E "^## \[" CHANGELOG.md | head -1
```
If you've been editing the branch via `/ship` you can rely on Step 12's
idempotency check. If you've been editing manually (merge resolution,
conflict fix, version bump), the audit is the last line of defense
before CI yells at you.
## Pre-ship requirements
Before shipping (/ship) or reviewing (/review), always run the full test suite.