Skip to content

context_budget.py: --status becomes a real run that writes nothing, a refused argument is told what it most likely meant, and the headline and advisory stop contradicting the table - #86

Merged
KJ5HST merged 6 commits into
KJ5HST:mainfrom
rmsharp:fix/context-budget-status
Oct 1, 2026

Conversation

@rmsharp

@rmsharp rmsharp commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Base main (6b29d3d), head rmsharp:fix/context-budget-status (c1167ae). Six commits, one per change,
each with its own CHANGELOG.md entry: 5 files, +631 / −11, of which CHANGELOG.md is +156.
starter-kit/context_budget.py +78 / −9, tools/test_context_budget.py +365, bin/tests.sh +30,
.quality-gates.json 2 thresholds. No Learning row, no failure-mode change, no hook change.

The problem

Three defects in what starter-kit/context_budget.py does and what it says.

1. There is no --status, and an argument the tool does not recognise is ignored. main() dispatches on
membership tests, and anything it does not match falls through to the default measurement. That run appends a row
to .context-budget-history.jsonl whenever a size changed. In a fresh clone of main, --status, --check,
--force, --dry-run, the misspelling --stauts and --zzz each exit 0 and leave
?? .context-budget-history.jsonl in the tree.

--status is nonetheless cited 12 times in this repository's own ledgers as a verification step (5 in
CHANGELOG.md, 7 in HANDOFFS.md), and once in the body of #84. Each of those readings was sound, since the
default run prints the same ledger. The defect is the write, and the silence. It is also the blocker you named
reviewing #82 (point 6): "--status
writes .context-budget-history.jsonl into the tree on every run … Tracked-or-ignored gets decided first; then the
gate."

2. The growth-run advisory contradicts the table. When the growth run fires, render() adds "Nothing is over
a ceiling yet — that is the point. Ceilings fire late."
The sentence was a literal. It printed in every such run,
including runs whose headline read context budget OVER above rows marked over.

3. A row over a ceiling could read instrument-failed. measure_file() gave a row the status of whichever
check wrote last. A structure pattern that matched fewer records than its expect_min overwrote a ceiling's over
with instrument-failed, which render() ranks just below over. The headline then read INSTRUMENT-FAILED, and
when the growth run fired, the advisory said nothing was over directly above the finding that the ceiling was
exceeded. The comment above main()'s exit said the tool's ordering ranks an instrument failure above over.

What this changes

Arguments Measures Writes history Output Exit
(none) yes when a size changed ledger 0 / 1 / 2 by verdict
--json yes when a size changed JSON same
--status, --check yes never ledger same as (none) on the same tree
--status --json, --check --json yes never JSON same
--precommit, --calibrate, --selftest, install-hook unchanged unchanged unchanged unchanged
-h, --help (with anything) no no usage 0
anything else no no unknown argument: …, a hint where one applies, then usage 3
  • --status is the default run with its one write removed (e859196): the same ledger and exit code, and no
    history row. Like quality_ratchet.py --status, it changes nothing in the tree. It makes the gate from Quality ratchet — declared thresholds that bind every actor and only tighten (plan #81, Phases 1–4) #82
    declarable without first settling whether the history file is tracked or ignored.

  • --check is a second name for --status (612570b). It is the ledger trimmer's name for its report-only
    run (methodology_trim.py --check: "evaluate the trigger and report; never writes"), and the one argument
    outside the tool's list that an adopter project's instructions type.

  • An unknown argument exits 3, the tool's documented usage code ("config or usage"), before the tree is read
    (e859196). Each one gets a line of its own saying what it most likely meant (612570b), from what the
    sibling tools use the same flag for:

    • --force (the trimmer's and the dashboard's override): "there is deliberately no --force: to permit growth,
      raise that file's ceiling in .context-budget.json"
      ;
    • --dry-run (the dashboard's preview): "did you mean --status? It measures and writes nothing";
    • --run and --write (the ratchet's and the trimmer's real run): "run with no argument to measure and
      record"
      ;
    • a misspelling of an accepted argument: "did you mean ?", from difflib.get_close_matches with a
      cutoff of 0.75. At the default 0.6, --version is offered --json; at 0.75 it is offered nothing;
    • anything else: nothing more.

    The accepted list, ACCEPTED_ARGUMENTS, is declared above the selftest, because the selftest's check that the
    string --force appears nowhere above it is the one existing guard that can read the list. The hint table
    names --force, so it sits below the selftest, and hints are looked up by key, never by the
    "--force" in args expression the two source greps match. The usage text's "There is deliberately no
    --force"
    becomes observable.

  • The advisory's second sentence is chosen by worst, the variable the headline prints, so the two cannot
    disagree (c299c30). When nothing is over, the sentence is unchanged, word for word. When something is, it
    reads "A ceiling has fired as well — see the rows marked over."

  • A check may raise a row's status, never lower it (2f73733). A failed structure pattern now leaves an
    over row as it is. Both findings still print, the exit code is 2 either way, and main()'s comment now says
    what the code does. No other output changes: test_a_declared_ceiling_still_renders_exactly_as_before still
    holds.

  • VERSION 1.2.0 → 1.3.0, for the usage banner only: bin/status compares blobs, not versions. The usage
    text gains --status and --check lines, and the default's "append one history line" now says "when a
    size changed"
    , which is what append_history does.

  • Two floors tightened to the values this branch measures, in two commits: tests-sh-passed 139 → 141
    (d4dbc26) → 142 (c1167ae), and context-budget-unit-tests 118 → 129 → 140, since the manifest owes a
    tightening whenever a measured value rises. Every other gate measures exactly its threshold.

How it was tested

  • 22 unit tests, each written first and run against the tool as it stood before its change. 15 fail on the
    old tool; the other 7 are controls that pass on it by design.
    • --status and the refusal, in TestCommandLine (8): 6 fail; the controls are that the default run still
      writes and that --help still wins.
    • The advisory, in TestGrowthRunAdvisory (3): a matrix over every status render() ranks, with and without
      the growth run, calling render() in process; a control that every status below over still prints the
      original sentence, so deleting it cannot pass; and one run of the real main() → render() path. 2 fail.
    • --check and the hints, in TestCommandLine (7, and --check added to its frozen accepted set): 5 fail,
      and so does the frozen set; the controls are that --zzz and --version are offered nothing.
    • Status precedence, in TestStatusPrecedence (4): the end-to-end run and the --json row fail; the
      controls are that a row which only fails its pattern still reads instrument-failed, and that a row past
      its warn line is still raised to it.
  • 3 rows in bin/tests.sh, each in a mktemp project with the seed config: --status leaves
    git status --porcelain --ignored empty; --zzz exits 3 and changes nothing; --check exits as --status
    does and writes nothing. Each fails on the tool as it stood before its change.
  • 17 mutants, each run and each caught by at least one test. For the command line: the append made
    unconditional again; the rejection removed; --force added to the list; a comment above the list naming the
    selftest's definition, plus --force. For the advisory: the literal restored; the sentence deleted; the
    condition inverted; the condition widened to instrument-failed. For the hints: --check dropped from the
    write guard; the hint table emptied; the cutoff at 0.6; the suggestion printed unconditionally; the hint table
    moved above the selftest. For status precedence: the guard removed; the guard never setting the status;
    raising from warn blocked; raising from ok blocked. --selftest, the part that ships to adopters, catches
    4 of the 17. One is worth a word: the selftest's check splits the source on the first mention of the
    selftest's definition, so a comment naming it moves the cut up, and --force in the list then passes the
    selftest. test_the_selftest_escape_hatch_check_still_reads_the_accepted_list pins the split point.

Verified

On the branch tip c1167ae, in a fresh --no-local clone with HEAD asserted:

  • python3 starter-kit/quality_ratchet.py --run: 10/10 pass. bin/tests.sh 142 passed, 0 failed; budget
    units 140, dashboard units 226, trimmer units 123, ratchet units 45; check-links, check-learnings,
    check-handoff --all and commit-msg --selftest all at 0.
  • python3 starter-kit/context_budget.py --selftest: 52 PASS, exit 0.
  • Each command in a clean clone of main and of the tip, the tree restored between runs:
Command main (6b29d3d) this branch (c1167ae)
--status, --status --json exit 0, leaves ?? .context-budget-history.jsonl exit 0, tree unchanged
--check, --check --json exit 0, leaves the history file exit 0, tree unchanged
--force exit 0, leaves the history file exit 3, unknown argument: --force — there is deliberately no --force: …, tree unchanged
--dry-run exit 0, leaves the history file exit 3, … — did you mean --status? It measures and writes nothing
--stauts exit 0, leaves the history file exit 3, … — did you mean --status?
--zzz exit 0, leaves the history file exit 3, unknown argument: --zzz, no hint
--help --zzz exit 0, usage exit 0, usage
bare writes the history file writes the history file
  • The two contradictions, in a mktemp project holding one 1,500 B file, with a growth-run limit of 2 and a
    seeded history that fires it:
Project main this branch
a class total over its ceiling headline OVER; "Nothing is over a ceiling yet" headline OVER; "A ceiling has fired as well — see the rows marked over."
a file over its byte ceiling that also fails a structure pattern headline INSTRUMENT-FAILED, row instrument-failed; "Nothing is over a ceiling yet" headline OVER, row over; "A ceiling has fired as well …"

Every run in that table exits 2.

Against the three open PRs

Computed with git merge-tree --write-tree --name-only from c1167ae, then merged for real in scratch clones
(any CHANGELOG.md conflict resolved by keeping both sides; every entry kept, and counted). The quality ratchet
then ran on each merge result:

PR Merge On the merge result
#84 (77afc12) clean, CHANGELOG.md included, though both touch tools/test_context_budget.py and bin/tests.sh 10/10 pass; bin/tests.sh 166 passed, 0 failed (142 + #84's 24); budget units 144 (140 + #84's 4)
#85 (e2501c5) CHANGELOG.md only; .quality-gates.json merges cleanly (its new gate sits below the two changed thresholds) 11/11 pass, #85's pre-commit-selftest included; bin/tests.sh 142 passed, 0 failed
#83 (219fb9d) CHANGELOG.md only 10/10 pass; bin/tests.sh 142 passed, 0 failed

Whichever of these you merge first, the next conflicts at the top of CHANGELOG.md; I will merge main into
the branch after it.

Who notices

  • A session that types --status or --check gets the same ledger and exit code as before, and no history
    row. The growth series is now fed only by bare and --json runs.
  • One adopter project of the seven checked has a live instruction in its session notes: "Re-measure
    (python3 context_budget.py --check) before writing more"
    . It now does what its author meant, measuring and
    reporting without appending a history row, where before it ran the default measurement, write included.
  • Anything passing another unrecognised argument now gets exit 3 and a line saying what it most likely
    meant, not a silent measurement. None of the seven adopters types one after the tool's name. No caller passes
    "$@": the installed hook passes only --precommit.
  • A script reading a row's status from --json: a row over a ceiling that also fails a structure pattern
    now reports over, not instrument-failed. The exit code is 2 either way.

Not changed here

  • Declaring a context-budget gate. This PR makes one declarable; whether to declare it is yours.
  • Combinations of known commands (--selftest --calibrate): their precedence is unchanged.
  • No existing ledger entry or receipt that cites --status or --check is edited. Each was a sound reading
    of the default run, and the command it names now exists.

What can be dropped

Each change is its own commit. The likeliest to be unwanted are the two floor commits, d4dbc26 and c1167ae,
if you would rather tighten the floors yourself; they go together, and without them the floors stay at 139 and
118, below what the branch measures. A plain git revert of any one commit conflicts in CHANGELOG.md, because
later entries sit above its own; say which you would drop and I will drop it on the branch.

🤖 Generated with Claude Code

rmsharp and others added 6 commits September 21, 2026 09:54
… unknown arguments

context_budget.py had no --status command and ignored any argument it did
not recognise, so --status, --check, --force and a typo each ran the default
measurement, which appends to .context-budget-history.jsonl whenever a size
changed. --status is cited as a verification step in this repository's own
ledgers, and the PR KJ5HST#82 review thread named its write as what stands in the
way of a context-budget gate.

--status (with or without --json) is now the default run without its one
write: same ledger, same exit code, no history row. Any argument outside a
fixed list exits 3, the documented usage code, printing the argument and the
usage text, before the tree is read; -h/--help still win. VERSION 1.2.0 ->
1.3.0; the usage text gains --status and says the default appends only when
a size changed.

The list sits above `def selftest` because the selftest's escape-hatch check
reads only the source above that function, and main() is below it. While it
was being written, a comment above the list named that function's
definition, moving the check's split point up so that --force added to the
list passed the selftest. A new test pins the split point.

RED first against the unchanged blob b1111d9: 8 new tests, 6 fail and 2 are
controls that pass by design; both new bin/tests.sh rows fail. Four mutants
run and killed (unconditional append, rejection removed, --force accepted,
comment moving the split point plus --force). The two `"--force" in args`
greps catch neither --force mutant. tools/test_context_budget.py 118 -> 126,
bin/tests.sh 139 -> 141 passed, 0 failed; no gate threshold changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s over a ceiling when something is

When the growth run fires, render() printed "Nothing is over a ceiling yet
-- that is the point. Ceilings fire late." as a literal, including in runs
whose headline read OVER above rows marked over. The second sentence is now
chosen by `worst`, the variable the headline prints, so the two cannot
disagree: unchanged word for word when nothing is over, and "A ceiling has
fired as well -- see the rows marked over." when something is. No other
output changes.

RED first against the unchanged blob 131158c: 3 new tests in
TestGrowthRunAdvisory. A matrix over every status render() ranks, with and
without the run, in process; a presence control that the original sentence
still prints below over; and the real main() -> render() path on an over
project with a fired run. Two fail on the old tool; the control passes on
it by design. Four mutants run and killed after the fixed tool passed the
same harness (literal restored, sentence deleted, condition inverted,
condition widened to instrument-failed); --selftest catches none of them.

Not changed: measure_file() lets a failed structure pattern overwrite a
byte ceiling's over, so such a row reads instrument-failed and the advisory
keeps the original sentence above a finding that says the ceiling was
exceeded. That is status precedence in measure_file(), not the advisory.

tools/test_context_budget.py 126 -> 129, --selftest 52 unchanged,
bin/tests.sh 141 passed, 0 failed; no gate threshold changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-tests to the measured values

tests-sh-passed 139 -> 141 and context-budget-unit-tests 118 -> 129: what
quality_ratchet.py --run measures on this branch after the two
context_budget.py changes (11 unit tests, 2 bin/tests.sh rows). The manifest
owes a tightening whenever a measured value rises. Every other gate measures
exactly its threshold, so nothing else moves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…argument what it most likely meant

The refusal added for unknown arguments (exit 3 and the usage text) said
what was wrong and not what to do. Of the arguments typed after this tool's
name in this repository and seven adopter projects, the two it did not
define were --status, which now exists, and --check: the ledger trimmer's
name for its report-only run, and what one adopter's session notes tell the
next session to type.

--check (with or without --json) is now accepted and is the --status run:
same ledger, same exit code, no history row. Every other refused argument
gets its own line with a hint drawn from what the sibling tools use the
flag for: --force is told the one way to permit growth (raise the ceiling
in .context-budget.json); --dry-run is offered --status; --run and --write
are told to run with no argument; a misspelling is offered the nearest
accepted argument (difflib, cutoff 0.75, measured: at 0.6 --version is
offered --json); anything else gets nothing more. Exit 3 and the no-read,
no-write contract are unchanged. The hint table names --force, so it sits
below the selftest and is looked up by key.

RED first against the unchanged blob dd4803b: 7 new tests in
TestCommandLine plus --check in the frozen accepted set; six fail on the
old tool, and the --zzz and --version controls pass on it by design. One
bin/tests.sh row: --check on the seed config exits as --status does and
writes nothing (fails on the old tool, 3 against 1). Five mutants run and
killed after the fixed tool passed the same harness: --check dropped from
the write guard, the hint table emptied, cutoff 0.6, the suggestion printed
unconditionally, and the table moved above the selftest (--selftest exits
2). --selftest catches only the last.

tools/test_context_budget.py 129 -> 136, --selftest 52 unchanged,
bin/tests.sh 141 -> 142 passed, 0 failed; VERSION stays 1.3.0; no gate
threshold changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… pattern also fails

measure_file() gave a row the status of whichever check wrote last, so a
structure pattern below its expect_min overwrote a ceiling's `over` with
`instrument-failed`, which render() ranks just below `over`. The headline
then read INSTRUMENT-FAILED and the growth-run advisory said nothing was
over a ceiling directly above the finding that said one was. That write was
the only one that could lower a status; it now leaves an `over` row as it
is, so a check can raise a row's status and never lower it. Both findings
still print; the exit is 2 either way.

Also corrects the comment above main()'s exit, which said the ordering
ranks an instrument failure above `over`.

Tests, RED first against blob f75482c: 4 in TestStatusPrecedence. The
end-to-end and --json tests fail on the old tool; the two controls pass on
it by design. Four mutants, each killed by at least one test and each test
killing one the others miss.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-tests again, to the measured values

tests-sh-passed 141 -> 142 and context-budget-unit-tests 129 -> 140: what
quality_ratchet.py --run measures on this branch after the two further
context_budget.py changes (11 unit tests, 1 bin/tests.sh row). Every other
gate measures exactly its threshold, so nothing else moves. Separate from
the first tightening so either can be dropped alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 21, 2026
…gin and the PR opened as KJ5HST#86

The plan's status block and a P4 outcome under section 5 P4; the body file's
fork-only preamble now says the text was posted unchanged as KJ5HST#86 (kept to
three lines, so the title stays at :12 and the body at :16, and the body still
cmp-equals what was posted); the BL-75 and BL-80 index rows and detail each
gain an S215 paragraph, nothing above them edited. Both items stay open until
the PR merges.

CHANGELOG: the push and the PR open as two non-commit action entries, and this
records commit. BACKLOG-DETAIL.md.verify.sh C1-C5 OK; bin/check-links OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 21, 2026
…pushed to fork origin and the upstream PR opened as KJ5HST#86 with the approved text

HANDOFFS.md receipt complete (check-handoff OK, 8.6 KB of the 12,288 B
record budget); CHANGELOG close-out entry with the Phase 3A evaluation of
S214 (9/10) and the self-assessment (9/10).

P4: fix/context-budget-status pushed (c1167ae), KJ5HST#86 opened, read back equal
(head c1167ae, 6 commits, +631/-11, mergeable clean). Records 34011a7.
Supporting: 0b3e355 claim, fc1f05a + b4d22c4 HANDOFFS trim and fold
(verify.sh OK; bin/tests.sh 343/0/6 on a re-run after a Test 9 network
timeout). Fork main at 34011a7: quality_ratchet 11/11 - results 10575dac7361
- manifest 01a4ae7aa511, identical to Phase 0.

Next: the maintainer's review of KJ5HST#83-KJ5HST#86; P5 after KJ5HST#86 merges; failing a
reply, BL-78's closing edits (fork-local).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 22, 2026
…ove to Completed items, and .context-budget.json's unwired "refused" sentence

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt.

Phase 0: CHANGELOG frontier = HEAD 68160ba, gap empty; HANDOFFS frontier
78cb080, the one commit after it S215's announced push record. No pending
stub, 2 receipts before this one; nothing backfilled. Gate citation re-run in
a --no-local clone at 68160ba: 11/11 - results 10575dac7361 - manifest
01a4ae7aa511, S215's citation exactly. Dashboard 76/100, medium, 0 high+ (run
in the clone). Upstream 0 open issues; KJ5HST#83, KJ5HST#84, KJ5HST#85, KJ5HST#86 open at unchanged
heads, 0 reviews, only our comments. main = origin/main = 68160ba;
upstream/main 6b29d3d.

Operator picker: deliverable = BL-78's closing edits (decided S206). Side
actions: HANDOFFS.md retention trim + fold, push fork main at close-out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 22, 2026
…atchet exists, unwired); BL-83 raised; nothing upstream-facing

HANDOFFS.md receipt completed (status: complete, self 8, predecessor 9) and
the close-out ledger entry with the Phase 3A/3B evaluations.

Deliverable: BL-78's closing edits (2674c95). Found on the way and recorded on
the operator's choice: BL-83 (38e4e11), fork Learning KJ5HST#85's false example.
Supporting: 461e38b claim, 1c1c4e3 + 2701247 HANDOFFS trim and fold.

Gate citation, fork main clone of 38e4e11: quality_ratchet 11/11 pass -
results 10575dac7361 - manifest 01a4ae7aa511, identical to Phase 0.

Next: the maintainer's review of KJ5HST#83-KJ5HST#86 (P5 after KJ5HST#86 merges); failing a
reply, planning BL-66 (upstream-bound, opens nothing).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 22, 2026
…vs BOOTSTRAP.md's --source=local advice

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt.

Phase 0: CHANGELOG frontier = HEAD f853edd, gap empty; HANDOFFS frontier
01116c6, the one commit after it S216's announced push record. No pending
stub, 2 receipts before this one; nothing backfilled. Gate citation re-run in
a --no-local clone at f853edd: 11/11 - results 10575dac7361 - manifest
01a4ae7aa511, S216's citation exactly. Dashboard 76/100, medium, 0 high+ (run
in the clone). Upstream 0 open issues; KJ5HST#83, KJ5HST#84, KJ5HST#85, KJ5HST#86 open at unchanged
heads, 0 reviews, only our comments. main = origin/main = f853edd;
upstream/main 6b29d3d.

Operator picker: deliverable = plan BL-66. Side actions: HANDOFFS.md
retention trim + fold, raise BL-84 (seed CLAUDE.md warn line vs mandatory
purpose fence, relayed from mts-system S143), push fork main at close-out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 22, 2026
…resh clone plus the local path

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt.

Phase 0: CHANGELOG frontier = HEAD 63de9e0, gap empty; HANDOFFS frontier
fbf269b, the one commit after it S217's push record. No pending stub, 2
receipts before this one; nothing backfilled. Gate citation re-run in a
--no-local clone at 63de9e0: 11/11 - results 10575dac7361 - manifest
01a4ae7aa511, S217's citation exactly. Dashboard 76/100, risk HIGH (1 high+):
docs/planning/BACKLOG.md 57,603 B past the 56,750 B one-read budget, crossed at
2e0fd02; a whole-file Read in a subagent returned all 228 lines. Upstream 0
open issues; KJ5HST#83-KJ5HST#86 open at unchanged heads, 0 reviews, no maintainer
comments. main = origin/main = 63de9e0; upstream/main 6b29d3d.

Operator picker: deliverable = P1 of sync-github-route-plan.md; D1-D8 all
option (a). Side actions: HANDOFFS.md trim + fold, raise the prose-route rules
backlog item, push fork main at close-out.

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

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt, plus the dashboard's history row from Phase 0.

Phase 0: CHANGELOG frontier = HEAD 6a8fe87, gap empty; HANDOFFS frontier
2f51cc9, the one commit after it S218's BL-79 record (its own ledger entry).
No pending stub, 2 receipts before this one; nothing backfilled. Gate citation
re-run in a --no-local clone at 6a8fe87: 11/11 - results 10575dac7361 -
manifest 01a4ae7aa511, S218's citation exactly. Dashboard 76/100, risk HIGH
(docs/planning/BACKLOG.md 58,077 B). Upstream 0 open issues; KJ5HST#83-KJ5HST#86 at
unchanged heads, 0 reviews. main 2 ahead of origin/main (2f51cc9, 6a8fe87).

Operator picker: deliverable = P2 of sync-github-route-plan.md. Side actions:
HANDOFFS.md trim + fold, CHANGELOG.md trim if it fires, push main and the
branch at close-out.

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

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt, plus the dashboard's and the budget tool's history rows from Phase 0.

Phase 0: CHANGELOG frontier = HEAD f07abe4, gap empty; HANDOFFS frontier
0af89a4, the one commit after it f07abe4 the push record (its own ledger entry).
No pending stub, 2 receipts before this one; nothing backfilled. Gate citation
re-run in a --no-local clone at f07abe4: 11/11 - results 10575dac7361 -
manifest 01a4ae7aa511, S219's citation exactly, two commits later. Suite in the
same clone 343 passed, 0 failed, 6 skipped. Dashboard 76/100, risk HIGH
(docs/planning/BACKLOG.md 58,077 B). Upstream 0 open issues; KJ5HST#83-KJ5HST#86 at
unchanged heads, 0 reviews, the only comments ours. main level with origin/main.

Two Phase 0 findings reported: the ratchet's first --run here measured 342/1
because other commands ran against the repo at the same time, and it keeps no
suite output, so a red run cannot be diagnosed without re-running it; and
S219's next-step (2) named T8_keeping_current.md where the plan's P3 names
T1_setup.md -- section 2.2 and D6 (a) resolve it, T8 is unchanged.

.context-budget-history.jsonl's row is BL-75 live: --status does not exist on
this tree, the unknown argument is ignored, and the default measurement runs
and appends a tracked history.

Operator picker: deliverable = P3 of sync-github-route-plan.md. Side actions:
HANDOFFS.md trim + fold, push main and the branch to fork origin at close-out.

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

Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt, plus the dashboard's and the budget tool's history rows from Phase 0.

Phase 0: CHANGELOG frontier = HEAD 43cf345, gap empty; HANDOFFS frontier
498e32a, the one commit after it 43cf345 the push record (its own ledger entry),
the same shape S219 and S220 both recorded. No pending stub, 2 receipts before
this one; nothing backfilled. Gate citation re-run in a --no-local clone at
43cf345: 11/11 pass - results 10575dac7361 - manifest 01a4ae7aa511, S220's
citation exactly, two commits later; suite in the same clone 343 passed,
0 failed. Dashboard 76/100, risk HIGH (docs/planning/BACKLOG.md 58,077 B).
Upstream 0 open issues; KJ5HST#83-KJ5HST#86 at unchanged heads, 0 reviews, the only comments
ours. main level with origin/main; upstream/main unmoved at 6b29d3d.

Three Phase 0 findings reported. The tracked .quality-gates-results.json is
stale (head 431279b, 2026-09-19), so the receipt's citation was confirmed from
the clone run rather than from that file. The dashboard's "1 loosened" was
traced to its one cause and is not new: tests-sh-passed 327 -> 294 at 368b29c
(2026-09-16), the operator-approved BL-57 D10 change, and the only loosening in
the manifest's whole history. .git/REBASE_HEAD absent and core.hooksPath is
.githooks, so the hooks are armed in this clone.

.context-budget-history.jsonl's row is BL-75 live again: --status does not exist
on this tree, the unknown argument is ignored, and the default measurement runs
and appends a tracked history row.

Operator picker: deliverable = P4 of sync-github-route-plan.md. Side actions:
the HANDOFFS.md retention trim this claim makes owed, and its fold.

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

Branch fix/sync-github-history, tip 67feb9f (one commit this session, the gate
tightening). Everything else P4 produced is measurement plus the approved body.
P5 opens the PR and is its own go-ahead.

The trial merge into upstream/main is a FAST-FORWARD -- merge base =
upstream/main = 6b29d3d, and merge-tree --write-tree returns the branch tip's
own tree dee697f -- so P4's two suite clauses are one measurement: 188 passed /
0 failed / 0 SKIP in a --no-local clone of 67feb9f, ratchet 10/10, results
2162213f5332, manifest 24be12b693f1.

Both cross-PR conflicts were resolved, BUILT and RUN rather than predicted. With
KJ5HST#84 only starter-kit/BOOTSTRAP.md conflicts (section 2.5 also predicted
CHANGELOG.md, which auto-merges); each side's untouched half is byte-identical
to the merge base, so the head+tail resolution is a fact and not a reading of
one very long line, and the merged tree runs 212/0 with BOTH of KJ5HST#84's phrase
pins passing -- which discharges what P3's departure (b) handed to the rebase.
With KJ5HST#86 it is .quality-gates.json (188 vs 142, a minimum resolving upward) plus
CHANGELOG.md, and the merged tree measures 191/0.

upstream/main measures 139/0, so the old floor was exact, not slack: the branch
adds 49 assertions and removes none. The tightening went in now rather than at
P5 because no rebase is pending and a min gate cannot be invalidated by a merge
that only adds tests.

Six adopters, twelve --dry-run runs: two flip from refused to a clean update
(10 -> 15 written, 8 -> 16), every refused file inside the would-write set,
checked per file; four refuse the identical file sets (7, 8, 8, 7) member for
member. The old route makes 29 HTTPS calls per run at 12-15 s and had 4 of 29
time out in one run (exit 1, 52 s); the clone route ran 1.7-2.7 s.

The body is approved as drafted by the operator, shown inline first, both
editorial trims declined. Its quotations are verbatim against issue KJ5HST#32 and KJ5HST#84;
its recognized-terms grep is scoped to the body because the whole-file form
matched its own scaffolding; it names no adopter project, since the six are
private repositories and the evidence needs only their counts.

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

Phase 3D receipt completed (status: pending -> complete, 13 keys, 11,936 B
against the 12,288 B record budget), Phase 3C row appended, Phase 3F ledger
entry written.

Deliverable: P4 of sync-github-route-plan.md on fix/sync-github-history
(67feb9f), recorded on main at f79960e; the PR body is approved as drafted after
being shown inline, so P5 sends it unchanged. P5 opens the PR and is its own
go-ahead.

What P4 measured rather than predicted: the trial merge into upstream/main is a
fast-forward (merge base = upstream/main = 6b29d3d; merge-tree returns the tip's
own tree dee697f). Both cross-PR conflicts were built and run -- KJ5HST#84's
BOOTSTRAP.md head+tail resolution passes 212/0 with both of KJ5HST#84's phrase pins;
KJ5HST#86's .quality-gates.json (188 vs 142) plus CHANGELOG.md measures 191/0. Six
adopters, twelve dry runs: two flip refused -> clean, four refuse the identical
file sets member for member.

Phase 3A: the predecessor handoff scores 9/10. Every checkable claim held,
including the shard-name prediction and the two inherited KJ5HST#84 items that made
that conflict cheap. One deduction, for "tighten in P4 ... only after the
rebase" being internally ambiguous; resolving it cost one measurement, and the
answer is that no rebase is pending.

Phase 3C, D3: fork Learning KJ5HST#94 appended -- a predicted "mechanical" conflict
resolution is a claim about three trees, and the counterparty's own tests are its
only oracle. The owed retirement is REFUSED with the rows named: KJ5HST#55, KJ5HST#64, KJ5HST#69,
KJ5HST#78, KJ5HST#90 each keep their recorded basis; this session's only mechanical change
was a threshold, which enforces a count and not a lesson.

Gate at f79960e in a --no-local clone: 11/11 pass, results 10575dac7361,
manifest 01a4ae7aa511, suite 343/0 -- identical to Phase 0's at 43cf345.

Nothing pushed. KJ5HST/methodology untouched; main is 4 ahead of origin/main and
the branch 1 ahead of origin/fix/sync-github-history.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 27, 2026
Phase 1B claim. CHANGELOG entry (in progress) + HANDOFFS.md status: pending
receipt, plus the dashboard's history row from Phase 0.

Phase 0: CHANGELOG frontier = HANDOFFS frontier = HEAD 22bbbc3, gap empty. No
pending stub, 2 receipts before this one; nothing backfilled. Gate citation
re-run in a --no-local clone at 22bbbc3: 11/11 pass - results 10575dac7361 -
manifest 01a4ae7aa511, S221's citation exactly, one commit later; suite in the
same clone 343 passed, 0 failed. Dashboard 76/100, risk HIGH
(docs/planning/BACKLOG.md 58,555 B). Upstream 0 open issues; KJ5HST#83-KJ5HST#86 at
unchanged heads (219fb9d, 77afc12, e2501c5, c1167ae), 0 reviews, the only
comments ours -- so no maintainer reply outranks the plan's next phase.
upstream/main unmoved at 6b29d3d and an ancestor of fix/sync-github-history, so
P5 needs no rebase. main was 5 ahead of origin/main; .git/REBASE_HEAD absent and
core.hooksPath is .githooks, so the hooks are armed.

Operator picker, three questions: deliverable = P5 of sync-github-route-plan.md;
D7 sequencing = open now with the body unchanged, a stated departure from
"after KJ5HST#84 merges" on the three grounds recorded in the ledger entry; outward
go-aheads = the branch push, the PR open, and a separate push of fork main.

Side action owed by the retention policy, not chosen at the picker: this claim
makes three receipts, so the HANDOFFS.md trim and its fold follow.

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

Records the S224 deliverable on fork main. The branch itself is
fix/bootstrap-never-overwrite-rules, tip a88fce7, based on upstream/main
6b29d3d; this commit is its fork-side record, not its content.

Four files: the drafted pull-request body, BL-85's detail status paragraph,
BL-85's index row, and this ledger entry. Nothing outward was done -- no push,
no pull request, no comment. BL-85's four shapes remain open and remain the
operator's.

Two of BL-85's own three "before it goes up" warnings came back different from
what it predicted:

  * Rule 1's table needs NO re-derivation. bin/_manifest.py's DISTRIBUTION list
    is identical across the two trees; the manifests differ only in comments and
    STALE_FORMAT_MARKERS.
  * The half that could not port is rule 2, which BL-85 does not flag: it cites
    ledger-format: 2 and FRAMEWORK_APPARATUS.md §The Action Ledger, and
    upstream/main has neither. Rewritten to point at the existing "Updating an
    existing project..." paragraph instead of restating it, which is what makes
    it survive KJ5HST#84 untouched.
  * Rule 3 ports verbatim; its five verdicts were read from upstream's
    bin/status (:95, :98, :102, :103, :106).

Conflicts measured with git merge-tree and then re-run as real merges: KJ5HST#84
77afc12 is CLEAN including BOOTSTRAP.md, merged tree 163/0, gates 10/10. KJ5HST#83,
KJ5HST#85, KJ5HST#86, KJ5HST#87 collide in CHANGELOG.md only; KJ5HST#87's merged tree runs 188/0 with
its own raised floor met exactly, gates 10/10, results 2162213f5332 -- the
hashes KJ5HST#87 cites. This branch adds no tests and moves no floor.

Recorded and not fixed (FM KJ5HST#17): §Setup with bin/sync's prose at :74 omits
three installed executables and two seeds, stale against the manifest. Named
in the body's "Deliberately not in this pull request".

All three docs/planning/ proofs re-run green; check-links OK at 111.

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 27, 2026
…etires -- the first retirement under D1(b)

BL-83, shape (1) of three, chosen by the operator after all three were costed
against measurements.

Row KJ5HST#85 said the .context-budget.json ratchet "does not exist". It does:
def precommit, starter-kit/context_budget.py:1000, byte arm :1037. It is
unwired in this clone, which is a different thing. Re-measured rather than
inherited from S216, in a --no-local clone at 28c24d3: nothing staged exit 0;
a staged growth of starter-kit/SESSION_RUNNER.md gave context-budget: REFUSED
and exit 2; a staged shrink exit 0.

D1(b) citation: #98 states KJ5HST#85's lesson at least as generally -- grep for the
behaviour a note asserts, not the fields it names -- and corrects the example.
KJ5HST#85's own Repair says to grep every field the note names; S201 did that and
reached the opposite answer, because the claim rests on max_bytes, a field the
note never names. That is the generalization.

First row ever retired, and the first use of D2's reserved-gap mechanism:
docs/archive/FORK_LEARNINGS-retired.md did not exist before this commit and the
live file carried 0 reserved lines. D3 is satisfied by the retirement itself,
so this close-out owes no fifth consecutive refusal; #98 is both the deliverable
and the Phase 3C learning.

Row KJ5HST#86 asserts KJ5HST#85's false premise in its own text and stays live -- its own
lesson is sound and it meets none of D1's criteria. #98 names the inheritance.

Not a reduction, and said so: 104,339 -> 104,875 B, net +536 B.

Proof: KJ5HST#85 byte-identical across the move (cmp clean, 1,470 B); retained rows
diff empty; check-learnings OK, 83 rows contiguous 15..98, no checker change;
the negative control fails with "missing KJ5HST#85"; check-links OK 111.

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

Phase 1B: the (in progress) CHANGELOG.md entry, a status: pending receipt in
HANDOFFS.md, and Phase 0's dashboard_history.jsonl row (single-project mode,
76/100 MEDIUM, High+ 0).

Deliverable chosen at the Phase 0 task picker over the CHANGELOG.md trim, BL-84
and the FM KJ5HST#17 recorded-not-fixed list. P6 of the BL-66 plan is still blocked on
KJ5HST#87's merge, so it was stated as blocked, not offered.

Shapes (a)/(b)/(c) for BL-86 are uncosted and (d) was declined on sight at S225.
Each will be built and measured on a throwaway copy before a decision picker;
none is implemented without a go-ahead, because editing a proof so a change
passes is a loosening (SAFEGUARDS.md).

Three things measured at Phase 0 rather than carried:

- The CHANGELOG.md trim ground is ~2.5 sessions away, not the four the
  predecessor's receipt estimated: 220,220 B now, 41,924 B to the 262,144 B
  read refusal, and S225 moved the file 203,621 -> 220,220 = 16,599 B end to
  end. --check fires and is still not the reason.
- context_budget.py --status appended one row to the tracked
  .context-budget-history.jsonl during Phase 0; reverted, diff kept in the
  scratchpad. That is BL-75's documented behaviour and PR KJ5HST#86's target, not a
  new finding.
- Gate at 31e16e4 in a --no-local clone: bin/tests.sh 343 passed / 0 failed /
  6 skipped, exit 0; quality_ratchet 11/11, results 10575dac7361, manifest
  01a4ae7aa511 -- the hashes S225 cited. The untracked
  .quality-gates-results.json records head 6b29d3d, an upstream tree.

Receipts go 2 -> 3, so the retention trim is owed as its own next action.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 28, 2026
docs/planning/overhead-ratchet-plan.md, 374 lines. Nothing ratified, nothing
implemented; fork-side throughout, no branch and no pull request.

The finding that reshaped the answer: the overhead gate is not missing.
context_budget.py --precommit already refuses a staged growth and passes a
shrink (starter-kit/context_budget.py:1000, byte refusal :1038), has no
--force, and exits 2 on this tree every run -- and nothing in this repo's gate
chain calls it. That was closed as BL-78, whose hook-enforcement phase the
operator DECLINED at S206. The plan does not re-propose it: its recommended
D1(b) touches no distributed file, because .quality-gates.json is a SEED whose
shipped gates array is empty, and quality_ratchet.py --run measures the
resulting tree per session rather than each commit -- which answers the exact
objection that killed the hook shape.

Two of BL-91's framings did not survive re-derivation. "A hook would have
caught none of it" is true of a 3-event window and false of the population:
the merge share of growth bytes is 2.6% by the default walk and 9.9% by
--full-history, which walks 124 commits where the default walks 68, because
git log -- <path> prunes merges. And the tool's headline still prints "Nothing
is over a ceiling yet" while four rows read over (BL-80, PR KJ5HST#86).

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 a4eeef3 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
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