Skip to content

The prose update route can wipe an adopter's ledgers: give the instruction the three rules that stop it - #88

Merged
KJ5HST merged 1 commit into
KJ5HST:mainfrom
rmsharp:fix/bootstrap-never-overwrite-rules
Oct 1, 2026
Merged

KJ5HST merged 1 commit into
KJ5HST:mainfrom
rmsharp:fix/bootstrap-never-overwrite-rules

Conversation

@rmsharp

@rmsharp rmsharp commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator

The defect

starter-kit/BOOTSTRAP.md §Without bin/sync is one sentence:

Tell your agent: "Update methodology using https://github.com/KJ5HST/methodology". It will fetch the latest
starter-kit files and overlay them.

It names no exception, and six of the files it tells the agent to overlay are seeds: CHANGELOG.md,
HANDOFFS.md, SESSION_NOTES.md, ROADMAP.md, .context-budget.json and .quality-gates.json. An agent that
follows the sentence literally replaces the adopter's action ledger and every close-out receipt with empty
templates.

bin/sync has never had this defect. bin/_manifest.py classes those six as seeds and installs them once, and
bin/sync refuses to overwrite them by construction. The gap is only in the prose route — which is the route
this very section tells people to use
, and for an adopter with no sibling checkout it is the only route there
is. The fix is delivered by the instruction that is broken: following it to get the corrected text overwrites the
ledgers first.

An acceptance test across six adopter projects rated this critical and measured the exposure. Three of them were
inspected directly and held identical text; their CHANGELOG.md / HANDOFFS.md pairs were 42 KB / 70 KB,
150 KB / 112 KB and 474 KB / 1.1 MB. The protection had reached none of the six.

What this changes

One section of one file. The instruction stays exactly as it is; three numbered rules follow it.

1. Overlay the tracked files; never overwrite the adopter-owned ones. A two-row table splitting the
distribution, with the consequence of getting it wrong in the sentence beneath it rather than left implicit. The
rows are derived from bin/_manifest.py's DISTRIBUTION list, not written from memory.

2. Reconcile the adopter-owned files by hand, because nothing else will. Never overwriting them means a
project moving up from an earlier version keeps its ledgers in their old format — new behaviour, missing
structure. This rule points at the Updating an existing project from an earlier methodology version paragraph
in §Setup with bin/sync
rather than restating the migration, so the two cannot drift apart and this section
needs no edit when that paragraph changes.

3. Verify afterwards, don't assume. bin/status and the five verdicts it prints, with the one that means
rule 2 is still owed called out.

Why it is prose and not a mechanism

Because the failure is a prose instruction being followed correctly. There is no code path to guard: the agent
never runs bin/sync, so no refusal in bin/sync can reach it. The only thing standing between the instruction
and an overwritten ledger is what the instruction says, which is what this changes.

Verification

Measured on the branch, and again on the merged trees:

No gate moves: the change is prose in one file and adds no tests.

Deliberately not in this pull request

🤖 Generated with Claude Code

…dopter ledgers

BOOTSTRAP.md's "Without bin/sync" section was a single sentence telling the
reader's agent to fetch the starter-kit files and overlay them, with no
exception named. CHANGELOG.md and HANDOFFS.md are seeds: an agent that follows
that sentence literally replaces the adopter's action ledger and every
close-out receipt with empty templates. A six-adopter acceptance test found
this and rated it critical. bin/sync has never had the defect -- it classes
those files as seeds and installs them once -- so the gap is only in the prose
route, which is the route that section tells people to use.

Adds three numbered rules beneath the instruction:

  1. A two-row table splitting the distribution into tracked files (overlay)
     and adopter-owned files (never overwrite), with the consequence of getting
     it wrong stated immediately after it. The rows are derived from
     bin/_manifest.py's DISTRIBUTION list, not written from memory: six files
     are seeds -- CHANGELOG.md, HANDOFFS.md, SESSION_NOTES.md, ROADMAP.md,
     .context-budget.json, .quality-gates.json.
  2. The hand reconcile the seeds still need, which points at the "Updating an
     existing project from an earlier methodology version" paragraph in
     "Setup with bin/sync" rather than restating it, so the two cannot drift.
  3. Verify with bin/status, naming the five verdicts it actually prints --
     missing, current, N versions behind, locally modified, and
     present (stale format) -- read from bin/status, not from documentation.

Measured on this branch: bin/tests.sh 139 passed, 0 failed, unchanged from the
base commit; bin/check-links OK, 107 links; context_budget.py --precommit
exit 0; quality_ratchet.py --run 10/10 pass, 0 fail, results 6542e640a956,
manifest 97a7aab85b9a. Prose in one file; no gate moves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 27, 2026
…opened

Two outward, explicitly authorized actions, taken after the session had
already closed out; each read back before the next.

Re-verified first: upstream/main re-fetched and unmoved at 6b29d3d, still the
branch's base by git merge-base --is-ancestor, all five previously open heads
unchanged. Branch re-run in a --no-local clone at the exact commit being sent:
bin/tests.sh 139 passed / 0 failed; quality_ratchet 10/10 pass, 0 fail,
results 6542e640a956, manifest 97a7aab85b9a.

Action 1: fix/bootstrap-never-overwrite-rules pushed to fork origin as a new
ref; git ls-remote reads back a88fce7.

Action 2: KJ5HST#88 opened against main from
rmsharp:fix/bootstrap-never-overwrite-rules. gh pr view reads back state
OPEN, head a88fce7, base main, cross-repository, MERGEABLE/CLEAN.

The body test that can fail: the channel appends an attribution line the
approved file does not carry (fork Learning #95), so "sent unchanged" and
"byte-identical read-back" are different tests. KJ5HST#86 and KJ5HST#87 were read first
to confirm the convention rather than recall it, the line was appended on
purpose, and the read-back minus exactly that line compares equal to the
approved text -- 3,849 B each side, 3,918 B as published.

The S224 receipt said "nothing outward happened", which stopped being true;
it, the body file's status line, BL-85's detail and its index row are all
corrected here. BL-85 is discharged by KJ5HST#88's existence; the merge is the
maintainer's. Six PRs are now open (KJ5HST#83-KJ5HST#88) with 0 reviews between them.

Five files, exactly the blast-radius cap. check-links, check-handoff and all
three docs/planning/ proofs green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 28, 2026
Phase 3C. Appended: git log -- <path> simplifies history and drops commits
from the walk, so a per-commit classification is computed on a denominator
that silently excluded them -- the merge share of read-set growth bytes reads
2.6% by the default walk and 9.9% by --full-history (68 vs 124 commits).
Sibling of #102 with a different mechanism, and a different remedy.
1,431 B / 1,500 B; table contiguous 15..103, 88 rows.

RETIRED NOTHING, DELIBERATELY, rows named in the ledger entry: KJ5HST#87 (closest --
its token half IS gated, its byte half is not), KJ5HST#88 and #99 (both confirmed
again, not superseded), KJ5HST#86 and #102 (adjacent, no gate). KJ5HST#85 was already
retired at S225. None meets criteria (a), (b) or (c).

Also corrects "374 lines" to 376 in two records: the count was taken before
three citation edits added two lines to the same file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
KJ5HST pushed a commit that referenced this pull request Oct 1, 2026
…st (88 → 87 → 86 → 85 → 84), not #84 first

The operator proposed 88 → 87 → 84. Simulated in a scratch clone, both
orders give the same final tree except CHANGELOG.md: only merging the
PR with the newest entries first keeps a keep-both resolution
newest-on-top (84-first put #88's 09-26 entry below #87's 09-21 ones).
bin/tests.sh on the 88 → 87 → 84 tree: 212 passed, 0 failed. #86 and
#85 are slotted by the same date rule, not simulated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsJekmqmNAnsjcEcDNj3Yk
@KJ5HST
KJ5HST merged commit 19566b6 into KJ5HST:main Oct 1, 2026
KJ5HST pushed a commit that referenced this pull request Oct 1, 2026
…lues — tests-sh-passed 215, context-budget-unit-tests 145, trimmer-unit-tests 124

Measured at d7768cb after merging #89, #88, #87, #86, #85, #84, #83
(--run 11/11, results 219197070a3b). Tightening only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsJekmqmNAnsjcEcDNj3Yk
KJ5HST pushed a commit that referenced this pull request Oct 1, 2026
….md entry

FRAMEWORK_APPARATUS.md §The Action Ledger says a committed entry is never
edited; nothing enforced it, and S26 broke it twice with every gate green.
With the ledger co-staged, .githooks/pre-commit now compares the staged
ledger with HEAD's entry by entry and refuses a changed or dropped entry,
unless the commit stages a docs/archive/ shard (the trimmer's commit).

RED first by replaying real commits: 746c17a and d1c1154 passed the old
hook and are refused by the new one; the trim, release docs, backfill and
every S26-S29 claim and close-out pass. All 119 ledger commits since v3.7:
71 pass (all of rmsharp's #84-#88), 48 refused, each an append to an
existing entry under the pre-#84 practice. --selftest 10 -> 17 checks;
two mutants of the check are each killed by it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsJekmqmNAnsjcEcDNj3Yk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants