Skip to content

B1 Phase 3: expand bin/sync to the full Option-B corpus (shared bin/_manifest.py) - #34

Merged
KJ5HST merged 5 commits into
KJ5HST:mainfrom
rmsharp:fix/issue-32-phase3-sync-coverage
Jun 21, 2026
Merged

KJ5HST merged 5 commits into
KJ5HST:mainfrom
rmsharp:fix/issue-32-phase3-sync-coverage

Conversation

@rmsharp

@rmsharp rmsharp commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Part of #32 (B1 sync-coverage expansion). Phase 3 of 4 — not Closes, because Phase 4 (bin/status per-file rows) still remains.

What this does

Expands bin/sync from the legacy 3-file scope to the full Option-B corpus (21 files) and introduces a single shared source of truth for the distribution mapping.

Changes (7 files)

  • bin/_manifest.py (new, data-only) — DISTRIBUTION = [(src, dest, disposition), …], 21 entries (18 tracked, 3 seed); the single source of truth (plan Decision 5). Imported by bin/sync and bin/check-links.
  • bin/sync — iterates DISTRIBUTION; honors dest subdirs (mkdir -p); new seed_file (write-if-absent, never overwrites — even with --force); IGNORE/tracking restricted to tracked dests so seed files stay committable. Produces an idempotent 21-file tree.
  • bin/check-links — imports DISTRIBUTION (no longer inlined); new --tree <dir> mode validates a real, sync-produced tree, not only the simulated one.
  • bin/tests.sh — +4 tests (T11 faithful per-file manifest incl. subdir spot-checks; T12 seed created-once / never-clobbered incl. --force; T13 instances never targets; T14 check-links --tree on sync output).
  • README.md / starter-kit/BOOTSTRAP.md — scope claims updated to the full corpus + seed semantics; BOOTSTRAP points at bin/_manifest.py as the authoritative list.
  • .gitignore — ignore bin/__pycache__/ (Phase 3 makes bin/ importable via bin/_manifest.py, the same situation as v2.6.1's tools/__pycache__/).

Known interim (intentional; resolved in Phase 4)

bin/sync now distributes 21 files, but bin/status still reports the legacy 3 until Phase 4 imports the shared manifest. Half the false-confidence gap remains — accepted per the plan, since sync coverage and status reporting are separate capabilities (bundling them would be FM #26).

Verification

No CI on this repo and the fork lacks merge rights → operator merges.

🤖 Generated with Claude Code

rmsharp and others added 5 commits June 20, 2026 17:44
Single source of truth for the distribution map, shared by bin/check-links
now and bin/sync next. Entries gain a third field, disposition (tracked|seed),
unused by check-links but consumed by sync in the following commit.

bin/check-links imports DISTRIBUTION instead of inlining it; its two unpack
sites widen to the 3-tuple. Behavior unchanged: 77 links across 20 files
resolve; ./bin/tests.sh 29/0.

Part of KJ5HST#32 (B1 Phase 3).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bin/sync now distributes all 21 manifest files instead of 3:
- iterates DISTRIBUTION (src, dest, disposition); reads each src by its
  repo-relative path (no longer hard-coded under starter-kit/).
- sync_file honors dest subdirs and mkdir -p's parents (docs/methodology/,
  docs/methodology/workstreams/); .py chmod preserved.
- new seed_file implements the SEED disposition (write-if-absent, never
  overwrite even with --force) for SESSION_NOTES/CHANGELOG/ROADMAP (Decision 2a).
- IGNORE_ENTRIES / currently_tracked restricted to TRACKED dests, so adopter-
  owned SEED files stay committable; .gitignore entries now correct for subdirs.
- drift/--force/upgrade/dry-run machinery is per-file and generalized unchanged.

Adopter-owned instances (CONTEXT.md, CLAUDE.md, …) are never dests, so they can
never be sync targets (Decision 2) — no guard needed.

Manual verify: sync produces the 21-file Option-B+ tree; re-run idempotent;
pre-existing SESSION_NOTES.md not clobbered; ./bin/tests.sh 29/0 (suite expands
next commit). bin/status still on 3 files until Phase 4 (planned split).

Part of KJ5HST#32 (B1 Phase 3).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ced tree

bin/check-links gains a --tree <dir> mode: validate an existing (e.g. sync-
produced) adopter tree instead of a freshly simulated one — it only adds the
adopter-created placeholders and never deletes the caller's tree. materialize
splits into _distribution/_adopter_local; check() reports a missing distributed
file instead of crashing.

bin/tests.sh +4 tests (now 39 assertions, 0 failed):
- T11 faithful per-file check: every manifest dest present + tracked files match
  canonical (gate d — asserts real multi-dir paths, not just filenames), plus
  docs/methodology/ and workstreams/ subdir spot-checks.
- T12 seed created-once / never-clobbered, including under --force (SEED-ONCE
  dragon).
- T13 instances (CONTEXT.md/CLAUDE.md) are never sync targets; templates are.
- T14 check-links --tree green against the actual sync output (plan §6 DONE).

Part of KJ5HST#32 (B1 Phase 3).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bin/sync no longer copies just 3 files. README Option A and BOOTSTRAP's two
scope claims now describe the full corpus (operating files at root + framework
under docs/methodology/ + workstreams/), the seed disposition (SESSION_NOTES/
CHANGELOG/ROADMAP written if absent, never overwritten), and the ignore-mode
distinction (tracked files gitignored, seed files committed). README Option B
(manual) brought to parity. BOOTSTRAP points at bin/_manifest.py as the single
authoritative distribution list so the prose can't silently drift from it again.

The Step 3 'three files' task-tracking copy (BACKLOG/CHANGELOG/ROADMAP) is a
different set and left as-is.

Part of KJ5HST#32 (B1 Phase 3).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 3 extracted the DISTRIBUTION manifest to bin/_manifest.py, imported
by bin/sync and bin/status. Running either now generates bin/__pycache__/,
which was untracked. Mirror the existing tools/__pycache__/ rule (added in
v2.6.1 for the same reason once tools/ held an importable module).

Part of KJ5HST#32.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@KJ5HST
KJ5HST merged commit 3615117 into KJ5HST:main Jun 21, 2026
KJ5HST pushed a commit that referenced this pull request Jun 21, 2026
…#37)

Document the B1 campaign: bin/sync + bin/status expanded from the legacy
3-file scope to the full 21-file Option-B corpus via a shared bin/_manifest.py,
plus bin/check-links, the seed disposition, and the #37 checker-hygiene fix
(check-links --tree no longer writes to the tree it validates, closing #36).

README "What's New in v2.8" entry; CLAUDE.md version-history bullet;
current version v2.7.2 -> v2.8. Tooling only — no principle, phase, gate,
workstream, or FM change; FM count stays 26.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LDt75tB93yc777ZfemRms3
@rmsharp
rmsharp deleted the fix/issue-32-phase3-sync-coverage branch June 21, 2026 04:48
rmsharp added a commit to rmsharp/methodology that referenced this pull request Aug 1, 2026
…buted files

Found while correcting upstream PR KJ5HST#63; kept OUT of that PR per FM KJ5HST#17 (one
deliverable per session), since it is a separate defect in different files.

The Learnings table ends at KJ5HST#12, but five sites in two bin/_manifest.py-
distributed files cite Learnings KJ5HST#28/KJ5HST#30/KJ5HST#34, which have no referent anywhere
in the corpus. DEVELOPMENT_WORKSTREAM.md:23 points the reader at
"ITERATIVE_METHODOLOGY.md §Knowledge Accumulation", which contains no numbered
learnings at all. Every adopter already has these.

Same defect class as PR KJ5HST#63 — a citation resolvable only against a source the
reader does not have. Notes Learning KJ5HST#12's fork-only S9-S16 / Layer citations
as the related convention question to decide alongside it, and proposes the fix
as a bin/tests.sh assertion (driven RED first) rather than another review-time
grep, per Learning KJ5HST#12's own rule.

Also reconciled two now-stale "both are open" claims in the file's header that
adding a third item invalidated (Learning KJ5HST#7), and recorded the PR KJ5HST#63
correction itself in CHANGELOG.md per FM KJ5HST#27.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KJ5HST pushed a commit that referenced this pull request Aug 2, 2026
checkpoint 1/3

starter-kit/RECOMMENDED_SKILLS.md and workstreams/DEVELOPMENT_WORKSTREAM.md
cited Learnings #28, #29, #30 and #34. The canonical table holds 1-13, so
none of those has a referent anywhere in the corpus -- and one site sent the
reader to "Learning #30 (in ITERATIVE_METHODOLOGY.md section Knowledge
Accumulation)", a section that contains no numbered learnings at all.

Root cause: all five trace to docs/audits/2026-05-02-mattpocock-skills-
evaluation.md, which cites *rad-con's* project Learnings by that project's
own numbering ("Learning #30 (rad-con UDP issue batch, S357...)"). When v2.6
distilled that audit into the distributed corpus, the numbers came along and
lost their referent.

Fixed by stating the substance instead of the number -- the parentheticals
already carried it, so nothing is lost and the text now stands alone in an
adopter's single-repo install, which is where these files actually land.
The /to-issues row gains a real relative link to the workstream section that
does cover issue batching, in adopter layout per the v2.8 convention.

The audit doc itself is deliberately untouched: it is dated record prose, it
is canonical-only, and it correctly attributes the numbers to rad-con. Same
treatment as the v2.7.1 precedent.

Verified: no `Learning #N` with N > 13 remains in starter-kit/ or
workstreams/; all surviving refs resolve to #6/#7/#8/#10. bin/tests.sh 84/84;
bin/check-links OK (83 links / 21 files, up one from the added link).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018QpRyb1JxfMaRKik9EWm49
rmsharp added a commit to rmsharp/methodology that referenced this pull request Aug 2, 2026
…BL-13 raised

Phase 3D/3F close-out for the resync merged in 232514e. Fork-local; no
outward-facing action on KJ5HST/methodology was taken and none is authorized.

BACKLOG reconcile, the deliverable's second half:
  * BL-10 CLOSED as superseded-upstream. Its Completed row claimed "SHIPPED via
    PR KJ5HST#64" -- wrong on both counts: that PR was closed, never merged, and
    upstream fixed the same five sites itself in 15ccb38. The parked branch now
    survives for bin/check-citations alone.
  * BL-12's second bullet struck through and re-pointed at upstream issue KJ5HST#65,
    which the maintainer filed and which is strictly broader than the bullet.
  * BL-12's first bullet re-measured: the false "19 anti-patterns" count is at
    FOUR live sites, not the one originally recorded. All four are one fix on
    this repo's own precedent (ac770fe, "same drift, same fix").
  * BL-11 re-verified line by line against e02538b; every site still stands, and
    upstream's own f85a324 now supplies a maintainer-stated rationale for it.
  * BL-13 raised: 15ccb38 stripped the dangling Learning KJ5HST#34 citation from
    starter-kit/RECOMMENDED_SKILLS.md:94 but kept the claim it was attributing.
    "handoff length discipline" occurs once in the whole distributed corpus --
    that line -- while FM KJ5HST#15, the Phase 3D "<5 lines" tripwire and
    ITERATIVE_METHODOLOGY.md:509 all argue the opposite. BL-10's own session
    predicted this in writing before it happened.

Put through a four-lens adversarial review before commit: 13 raw findings, 9
refuted, 3 confirmed and all 3 fixed here. Every one was a miscount of mine, the
same class this session spent the day correcting in other records:
  * BL-12 recorded as "two" sites when it is four -- grepped the literal string
    and missed the "19 documented anti-patterns" phrasing.
  * "all four prior stubs fail --allow-pending" -- the true figure is 17 distinct
    sessions; I counted the live file and reported it as the population.
  * Two unhedged BACKLOG.md pointers in the receipt, including the "read this
    first" one, pointed 7 and 9 lines off after my own edits moved the targets.
A fourth, the ledger total written as 67 when this entry makes it 68, was caught
by re-running the audit command. All four are recorded in the receipt's
self-score rather than quietly patched.

Verified: bin/tests.sh 92/92; bin/check-links OK 83/21; bin/check-handoff green;
ledger audit 68 = 18 live + 50 archived; both archives md5-unchanged
(CHANGELOG d6568960..., HANDOFFS f6cb814a...); the two union proofs re-run
against the final tree report exactly one expected finding each -- the
stub-to-complete receipt and this session's own ledger entry, the only two
intentional additions -- with every other receipt and entry still byte-identical;
all 8 BACKLOG pointers in the receipt re-audited to land on what they name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Aug 11, 2026
15ccb38 removed a dangling `Learning KJ5HST#34` citation from RECOMMENDED_SKILLS.md's
/caveman row but kept the claim it was attributing: "the methodology's own
handoff length discipline". That phrase has no referent anywhere in this
distributed corpus, and the corpus actually says the opposite -- failure mode
Requirements gate on content, not length.

Re-grounded the row on those two verified, reachable sources instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
Phase 1B claim. Phase 2 of an ALREADY-RATIFIED plan
(docs/planning/record-budget-reduction-plan.md Sec 6), so there is no new design
gate. Phase 1 landed at S106; Phases 2 and 3 have stood pending through six
sessions that trimmed files instead.

WHY NOW -- the operator asked why this repo spends its effort trimming when three
larger adopters do not. The measurement inverts the premise. Read-only across all
four repos: this repo holds the SMALLEST ledgers of the four (CHANGELOG.md
37,659 B, HANDOFFS.md 51,622 B) and is the ONLY one under the 65,536 B ceiling --
--check is silent on both. wsfct FIRES on CHANGELOG.md (74,180 B); nprcgenekeepr
FIRES on both (218,298 / 286,154 B); vscode_quarto_ext FIRES on CHANGELOG.md
(811,069 B) and its HANDOFFS.md (1,780,187 B, 27x the ceiling) cannot be trimmed
at all -- the trimmer refuses with [ZONE_UNCLASSIFIED] because the bootstrap
seed-sentinel line was never deleted, so it has ZERO archive shards.

THE TERM THAT IS GENUINELY WRONG HERE IS THE RECEIPT, NOT THE FILE. Measured over
live ledgers PLUS every archive shard, so the population is the whole history and
not the post-trim remnant: median B/receipt -- this repo 11,483 (n=115),
vscode_quarto_ext 7,912 (n=216), nprcgenekeepr 4,664 (n=325), wsfct 4,059 (n=67).
This repo's receipts are 2.5-2.8x the adopter median: 5.7 receipts to fill the
ceiling against their 14-16. Its CHANGELOG entries are the SMALLEST of the four
(median 1,387 B), so the whole excess sits in HANDOFFS.md. That is Sec 2 of the
plan restated by independent measurement.

WHAT PHASE 2 DOES:

1. Collapse the archive pointer blocks in HANDOFFS.md front matter into one
   compact index. Re-measured at this Orient, not inherited: there are 8 blocks,
   not the plan's 7, totalling 3,580 B = 48.6% of a 7,360 B front matter. The
   plan recorded 7 / 3,132 B / 45% of 6,913 B -- the drift is exactly one block
   at the stated ~447 B, so the growth model is confirmed by its own error.

2. Give the 8,000 B header reserve A NAME AND AN EXECUTABLE FIT ASSERTION. Today
   it exists only in prose in bin/check-handoff's derivation comment: no
   constant, and nothing that fails when it is wrong. This is the urgent half --
   the front matter is at 92.0% of it (7,360 / 8,000) and grows ~447 B per trim,
   so it BREACHES IN TWO TRIMS, and nothing would say so.

DECIDED HERE, NOT DISCOVERED LATER (S108's next_steps (d)): the fit assertion
goes in bin/tests.sh reading the constants out of bin/check-handoff, NEVER as a
module-scope assert -- that runs at import, so a mutant violating it dies with a
traceback before the code under test executes and is scored killed by the crash
rather than by the behaviour.

RECORD_BUDGET_BYTES STAYS 12,288. Sec 4.3 is binding: shrinking the front matter
must BANK the saving as slack, never feed it back through a division.

CONTROL IS FLAKY, AND THAT IS DIAGNOSED RATHER THAN TOLERATED. Two runs of
bin/tests.sh on the identical clean tree: 278/2/0 then 279/1/0. Test 9's
--source=github 404 is the standing failure; the second is Test 38 assertion (5),
a RACE and not a regression. bin/tests.sh:5 is `set -uo pipefail` -- pipefail IS
on -- and `echo "$(ch38)" | grep -q PAT` lets grep -q exit at the first match, so
echo can take SIGPIPE and the pipeline is scored failed EVEN THOUGH THE PATTERN
MATCHED (Learning KJ5HST#34). Six assertions carry that form -- :2591, :2596, :2605,
:2620, :2864, :2880 -- ALL on the `&& pass || fail` polarity, so each fails
noisily rather than passing silently; none is in the dangerous `&& fail || pass`
direction that would assert nothing. Recorded, deliberately not fixed here.

RECORDED AT CLAIM -- A SCOPE COLLISION IN THE RATIFIED PLAN. Sec 7 puts
methodology_trim.py and "anything distributed" out of scope, but the pointer
blocks are GENERATED by starter-kit/methodology_trim.py:935-936, which IS
distributed. So the compaction is durable only until the next trim appends a
fresh 447 B block in the old format. Compacting is a data edit and is in scope;
teaching the generator the compact format is not, and is raised as a follow-on.

NOT claimed: the 65,536 B ceiling, Test 34's floor of 3, methodology_trim.py,
anything distributed, Phase 3, the FRAMEWORK_LEARNINGS.md ceiling, BL-36's four
failing proofs. NO OUTWARD-FACING ACTION.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…nd the

ceiling is broken the other way

S121's deliverable. VERDICT: S120's "Phase 3C cannot be performed" is false as
written. The arithmetic is right and the denominator is wrong.

FOUR INDEPENDENT REFUTATIONS, each attacked by an agent told to break it.
1. METERED, the file is 19,617 tok = 78.5% of the 25,000-token cap. Six
   collinear probe points with ZERO residual on the three the model never saw;
   the concatenation seam MEASURED at exactly zero tokens, so f(1) is a
   measurement, not an extrapolation. Headroom 5,383 tokens.
2. 56,750 B is applied to this file by NO code path: methodology_trim.py
   answers [NO_CONFIG]/exit 3, both dashboard twins' read_cap_class() answer
   None, check-learnings has no whole-file arm. It is a detector FLOOR
   (2.27 B/tok, the conservative end of a measured band), not a budget.
3. Learning KJ5HST#34, in this very table, already moved the guard off the per-file
   axis at S97: read whole once, in part 243 times. The published budget is
   1,500 B PER ROW and all 46 rows comply.
4. No gate fires when a session appends nothing; BL-45 is the precedent, where
   S110-S114 ran through an identical declared deadlock and closed normally.

THE REAL DEFECT RUNS THE OTHER WAY, AND IT IS MEASURED, NOT MODELLED. 73,646 B
of this content -- 82 B UNDER the declared 73,728 B ceiling -- is refused at
25,486 tokens. BL-45 deliberately set that ceiling 2,023 B UNDER the then-cliff;
S119's compaction lowered density 3.0444 -> 2.8897 and inverted the margin. A
byte ceiling is tokens x density, and compaction is the operation that changes
density, so it rots silently. That is Learning KJ5HST#46's own mechanism, committed by
the framework's most recent remedy.

AND THE FINDING THAT ACTUALLY MATTERS: whenever headroom falls below ~1,500 B,
the row written EQUALS the headroom minus a few bytes (KJ5HST#34=604 at 604, KJ5HST#46=229
at 245). The file has saturated four times. The defect is not a blocked append,
it is a silent QUALITY TAX on the append.

SIX OF MY OWN NUMBERS WERE WRONG AND ARE CORRECTED IN PLACE, marked in the doc.
Two of them repeat, one level down, the exact error this document faults S120
for: I converted token headroom to bytes at the WHOLE-FILE density (2.8897) when
the headroom is consumed by ROWS, which meter 3.1974 B/token. Corrected capacity
is 11.5-16.5 rows, and the only safe unit is tokens (5,383). I also withdrew a
"the config refutes itself" division that compares two quantities the repo
explicitly declares non-comparable, and a fabricated quotation ("append a
Learning row") that I introduced into the record in claim commit 43387e1.

S120 WAS APPLYING ITS OWN RATIFIED PLAN'S STANDARD (:95, :106, :123). The defect
is in the plan. S120's SECOND reason -- byte-identity with the unpushed port
branch, blob b21854c identical on both -- is real, was never refuted, and is
answered as recommendation (4), a precondition rather than a remedy.

S119'S COMPACTION MUST NOT BE REVERTED: leg 1 (the row budget) independently
justifies every row, since only the 20-row option turns the checker green.
The operator's S119 decision table was scored on a column mis-scaled by ~19 KB;
the outcome is unchanged, but that is a finding he is entitled to be told.

NO REMEDY APPLIED. Present->Implement gate holds; recommendation sec 6 is an
answer proposed to open decisions D4/D5, not a correction an agent may apply.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…self-score 8/10

Deliverable 4b7224e (docs/planning/phase3c-deadlock-adjudication.md, 19,104 B).
Predecessor S120 scored 6/10.

VERDICT: S120's "the framework's own mandatory close-out step cannot be
performed" is FALSE AS WRITTEN. Four independent refutations, each handed to an
agent told to break it; all six lenses returned SURVIVES_WITH_CORRECTION.
Metered, the file is 19,617 tok = 78.5% of the 25,000-token cap, headroom 5,383
tokens. 56,750 B reaches this file through NO code path. Learning KJ5HST#34 already
moved the guard off the per-file axis at S97. BL-45 is the precedent, where
S110-S114 ran through an identical declared deadlock and closed normally.

THE REAL DEFECT RUNS THE OTHER WAY AND IS MEASURED: 73,646 B -- 82 B UNDER the
declared 73,728 B ceiling -- is refused at 25,486 tokens. S119's compaction
lowered density 3.0444 -> 2.8897 and inverted BL-45's deliberate 2,023 B margin.

THE FINDING THAT MATTERS: whenever headroom < ~1,500 B the row written EQUALS
the headroom minus a few bytes. Four saturations. Not a blocked append -- a
silent QUALITY TAX on the append.

SIX OF MY OWN NUMBERS WERE WRONG, corrected in place and marked in the doc. Two
repeat one level down the exact error the doc faults S120 for: I converted token
headroom to bytes at the WHOLE-FILE density when rows meter 3.1974 B/token, so
every capacity figure I published was low. I also withdrew a "the config refutes
itself" division comparing two quantities the repo declares non-comparable, and
I put a fabricated quotation ("append a Learning row") into claim 43387e1.

NO LEARNING ROW APPENDED, and NOT for the refuted cap: HEAD and
port/framework-learnings-extraction carry the identical blob b21854c, and
appending breaks the byte-identity that lets bin/sync agree from either source.
That was S120's second reason, it was never refuted, and choosing among the
three options is the operator's call.

NO REMEDY APPLIED. Present->Implement gate holds; sec 6 proposes answers to the
open decisions D4/D5, which the plan itself says are not derivable from
measurement. NO OUTWARD-FACING ACTION.

BUILD-EQUIVALENT AGAINST A CONTROL WORKTREE AT a4c4420: control 287 passed /
2 failed / 0 skipped exit 1; live identical, ZERO status flips across 284 shared
assertion texts. Both failures pre-existing and neither mine -- the known Test 9
upstream-404, and A2 truth VIOLATED on a front matter byte-identical at both
commits. check-links/check-learnings/check-handoff all 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…e building one

15 new assertions in TestTokenCeiling, all failing: 14 errors (no file_density,
token_ceiling, config_defects, WHOLE_READ_CLASSES, MIN_BYTES_PER_TOKEN yet) and
1 failure (precommit still gates on bytes alone). The 42 pre-existing tests stay
green, so the red is confined to the new behaviour.

Committed on its own so red-before-green is verifiable with git show rather than
asserted in prose.

WHAT THE CLASS PINS, and why each is load-bearing:
 * A declared max_tokens above the read cap is a CONFIG DEFECT, reported not
   silently clamped. This is the guard that makes the shipped bug
   unrepresentable rather than merely fixed once.
 * THE CLASS GATE IS THE LOAD-BEARING PART and it is Learning KJ5HST#34's: the cap
   binds a file read WHOLE; a file read in PART is not bound by it. An
   on-demand file gets NO token verdict at all. Narrowed rather than deleted --
   the weaker no-class-gate implementation is asserted to give the wrong answer,
   because reddening every partially-read file is the per-file-vs-per-row error
   this whole arc was about.
 * A derived ceiling is computed at the 2.27 FLOOR, which MAXIMISES the token
   estimate and therefore can never certify an unreadable file as fine. The
   direction is asserted explicitly; it has been got backwards twice this arc.
 * Drift from the size a density was measured at turns a confident ok into a
   warn -- S119's compaction moved density 3.0444 -> 2.8897 and that is exactly
   what inverted the ceiling.
 * precommit must gate on tokens too. The plan's own lesson was a KeyError at
   BOTH sites; a gate that reports and cannot refuse is half a gate.

Fixture proved before use, per this file's stated discipline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…d by class

Turns 0d3e3a6's 15 red assertions green (61 tests OK; selftest 35 PASS / 0 FAIL)
without touching the 42 that were already passing. VERSION 1.1.0 -> 1.2.0.

WHY. A byte ceiling is `tokens x density`, and density is a property of the
content, so every edit that changes how densely a file is written moves it and
nothing goes red. Measured on this repo: the declared 73,728 B ceiling certified
"ok" a file the read tool REFUSES at 25,486 tokens, and four of five declared
ceilings converted to more than the 25,000-token cap. Declaring the ceiling in
tokens makes that class of defect UNREPRESENTABLE, not merely fixed once.

WHAT LANDED.
 * READ_CAP_TOKENS, MIN_BYTES_PER_TOKEN, WHOLE_READ_CLASSES, DENSITY_DRIFT_WARN.
 * file_density() -- per-file measured beats config global beats the floor, and
   RETURNS ITS SOURCE so output never speaks a derived number and a measured one
   in the same voice.
 * token_ceiling() -- explicit max_tokens governs; otherwise DERIVE one from
   max_bytes at the 2.27 FLOOR, which maximises the token estimate and so can
   never certify an unreadable file as fine. Clamped at the cap either way.
 * config_defects() -- a declared max_tokens above the cap is REPORTED, never
   silently clamped: a clamp fixes the symptom and leaves the operator believing
   a number that is not in force.
 * ledger_dimension() now reports tokens when a token ceiling fires. That
   function's own docstring already argued the cap is token-denominated and
   bytes were the best available proxy; tokens belong there.

THE CLASS GATE IS THE LOAD-BEARING PART, and it is Learning KJ5HST#34's. The cap binds
a file read WHOLE; a file read in PART is not bound by it. on-demand files get NO
token verdict at all -- judging them would be the per-file-vs-per-row error this
whole arc was about. Operator chose this scope explicitly over "every file".

ADOPTERS KEEP WORKING WITH NO EDIT. bin/sync overwrites the TOOL (tracked) but
never the config (seed: "never overwrite an existing file, even with --force"),
so an un-migrated config is the normal case, not the exception. Every adopter
entry inspected declares max_bytes alone; all of them now gain the guard by
derivation.

BOTH ENFORCEMENT SITES MOVED TOGETHER. precommit() gates on tokens too, keeping
the relative rule so a shrinking commit is never blocked. A gate that reports in
one unit and refuses in another is half a gate -- the plan's own KeyError lesson.

WIRING GAP CAUGHT AND PINNED: main() called measure_file without cfg, which would
have run the token arm at the floor and discarded every per-file density while
the tests stayed green. Fixed, plus a test that fails if it regresses.

END TO END, not just unit-green: a read-mandated file of 63,000 B UNDER its
65,536 B byte ceiling now reports "26,250 tok / 25,000 tok  over" and exits 2,
while a 900,000 B on-demand file beside it stays in bytes and ok.

RECORDED, NOT FIXED (out of scope, already scheduled): cfg["classes"] raises
KeyError on a config with no classes key -- reproduced live at :1025.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…ken ceilings

26 insertions, ZERO deletions across both files. The configs are hand-formatted
with long _ notes, so every value was spliced into the raw text rather than
round-tripped through json.dumps, which would have buried the prose in a
whole-file diff. Both still parse.

THIS REPO (.context-budget.json). read_cap_tokens: 25000, plus per-file
max_tokens, a MEASURED bytes_per_token, and the measured_bytes/measured_on
provenance that lets drift be detected later:

  CLAUDE.md                            2.6144 B/tok   max_tokens  7,114
  CHANGELOG.md                         2.4674 B/tok   max_tokens 25,000
  HANDOFFS.md                          2.3648 B/tok   max_tokens 25,000
  docs/planning/BACKLOG.md             2.3808 B/tok   max_tokens 25,000
  starter-kit/FRAMEWORK_LEARNINGS.md   2.8897 B/tok   NO max_tokens (on-demand)

Each density was metered, not estimated: concatenate the file n and n+1 times and
read an over-cap explicit range, which is refused with an exact token count and
returns no content. The intercept came out EXACTLY 5.0 on all five files across
very different content, which is what makes the method trustworthy rather than a
fit. The spread is 2.36-2.89 B/token, so the single global 2.8 was wrong for four
of the five -- per-file measurement is not a refinement here, it is the point.

FOUR OF THE FIVE OLD BYTE CEILINGS CONVERTED TO MORE THAN THE CAP: 65,536 B is
26,561 / 27,714 / 27,527 tokens for the three ledgers at their real densities,
and 73,728 B is 25,514. Every one of those permitted a file that cannot be read.

NO STATUS FLIPS. Verdicts before and after are identical (ok/over/over/ok/ok,
exit 2). The ceilings are the same limits expressed in the honest unit, not new
policy -- which is the property that makes this safe to ship.

THE SEED (starter-kit/context-budget.json), which is what a NEW adopter gets:
read_cap_tokens plus max_tokens on the two whole-read entries, and on the
on-demand entry a _max_tokens note recording that its ABSENCE is deliberate and
why -- Learning KJ5HST#34's read-whole-once-and-in-part-243-times. No per-file density
is declared there, because none has been measured for a hypothetical project.

VERIFIED END TO END AT A FRESH ADOPTER, not just in unit tests: a real bin/sync
into a scratch git repo, then the shipped seed alone reports
"SESSION_NOTES.md  ~30,695 tok  25,000 tok  over" for a file UNDER its 120,000 B
byte ceiling -- the defect class that was previously invisible -- while a 400,000 B
on-demand file beside it reports in BYTES and gets no token verdict at all.

bin/tests.sh 287 passed / 2 failed / 0 skipped, exit 1: IDENTICAL to the S121
baseline with ZERO status flips across 283 shared assertion texts. Both failures
pre-existing (Test 9's upstream 404; the A2 front-matter reserve).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
…-score 8/10

Deliverable shipped across 0d3e3a6 (RED), 28a02a6 (GREEN), 97c8066 (configs).
Predecessor S121 scored 8/10.

THE DEFECT WAS SYSTEMIC, NOT SINGULAR. S121 found one ceiling permitting an
unreadable file; metering all five showed four of five do. Measured densities
span 2.3648-2.8897 B/token, so the config's single global 2.8 was wrong for four
of the five. The intercept came out EXACTLY 5.0 on all five files, which is what
makes the method trustworthy rather than a fit.

AND NOT CONFINED TO THIS REPO: read-only inspection of three real adopters found
FIVE read-mandated files over the read cap, two of them metered (29,739 and
30,311 tokens). The protocol orders those files read and they cannot be read
whole -- failure mode KJ5HST#28 detected in the wild for the first time. Nothing in any
adopter repo was touched; these are findings, not work.

THE CLASS GATE WAS THE OPERATOR'S CHOICE from three costed options, and it is
Learning KJ5HST#34's: the cap binds a file read WHOLE, so on-demand files get no token
verdict at all. Adopters need do nothing -- sync overwrites the tool but never
the config, so an un-migrated config is the normal case, and it gains the guard
by derivation at the floor, which can never certify an unreadable file as fine.

A WIRING GAP THE TESTS COULD NOT SEE: main() called measure_file without cfg,
which would have run the arm at the floor and discarded every per-file density
while 61 tests stayed green. Fixed and pinned.

bin/tests.sh 287/2/0 exit 1, IDENTICAL to the S121 baseline with zero status
flips across 283 shared assertions. tools/ 505 OK. Config migration is 26
insertions, zero deletions, no verdict changed.

NOT DONE: no Learning row (port-branch blob b21854c identity, operator's call);
cfg["classes"] KeyError reproduced live at :1025 and left alone as scheduled;
the dashboard "budget" wording and the live-artifact check remain.

RECORDED AGAINST MYSELF: I inverted the floor's direction and briefly published
the adopter findings on the anti-conservative basis. Third instance of this same
bytes-vs-tokens confusion in two sessions -- which is the argument that the
countermeasure must be mechanical, and is what this session shipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJo3fDBzjoYXwzhygVK1SM
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 5, 2026
Completes Phase 3 of docs/planning/upstream-read-set-pr-plan.md section 5.
ADOPTER-FACING. All four DONE criteria demonstrated on named surfaces.

STEP 2 -- PER-FILE CEILINGS, AND THEY ARE A PARTITION.
starter-kit/SESSION_RUNNER.md (41,364 B) and SAFEGUARDS.md (15,386 B)
declared in the canonical root config under a new read-set class:
41,364 + 15,386 = 56,750 exactly, so the two per-file ceilings SUM to the
class total. SAFEGUARDS.md is pinned at its current size because it is
byte-identical on upstream/main (blob f096419, verified both sides), so
the whole 12,999 B of debt sits on the file the plan wants shrunk. NOT
synced[]: check_synced() is drift-only by its own docstring and
precommit() iterates files[] alone, so a max_bytes in a synced entry
looks configured and refuses nothing. read-set joins WHOLE_READ_CLASSES
-- deliberate and recorded: the pair is read WHOLE, Learning KJ5HST#34's
condition, and bytes-only gating would reintroduce the density drift the
token arm exists to remove.

STEP 3 -- THE CLASS TOTAL, IN main() AND precommit().
class_totals() generalises a hardcoded resident aggregate to N classes.
Per-file ceilings do not sum: bytes can move out of SAFEGUARDS.md into
SESSION_RUNNER.md with both rows green and the Phase 0 read unchanged. An
aggregate that reports and cannot refuse is half a gate, so precommit()
gained the same arm under the same relative rule. A declared class with
no members totals 0 rather than vanishing; an unsizeable member makes the
total an announced LOWER BOUND, never a silent zero.

STEP 4 -- THE CEILING IS DERIVED, NOT PICKED.
READ_CAP_BYTES = int(READ_CAP_TOKENS * MIN_BYTES_PER_TOKEN) = 56,750, the
same expression methodology_trim.py:129 uses. framework_share :=
READ_CAP_BYTES - adopter_reserve_bytes; derive_from_read_cap puts the
computed value in force and a disagreeing written value is REPORTED.
Reserve ships at 0 -- the least favourable assumption for the framework's
own numbers. Checked at RUN time, not module scope: a module-scope assert
runs at import, so a mutant violating it dies by traceback before the
code under test runs.

A GUARD NOTHING CALLED. config_defects() had ZERO call sites while the
distributed seed tells adopters a defect "is rejected". Wired into main()
and precommit(); verified no adopter reddens (all three declare
max_tokens <= cap).

THE FOUR CRITERIA. (1) Bare run prints (read-set total) 69,749 B /
56,750 B over and exits 2. (2) On the REAL config: +1 byte REFUSED (2)
naming both rows; -5,000 B while still 8,000 B over PASSED (0). (3) A
synthetic third class totals {resident 40, pair 1200, third 85}, covered
in unit tests AND in --selftest, the only coverage adopters get. (4) The
three instrumented adopters -- chat_verification, vscode_quarto_ext,
wsfct, never named in the plan -- have ENTIRE stdout byte-identical, same
exit code, canonical tool both sides against frozen inputs. Limitation:
the frozen fixture leaves synced[] rows unmeasured, so it does not
exercise vscode_quarto_ext's synced row for context_budget.py.

THREE PLACES THE PLAN IS WRONG, for its section 8. (a) 3.4(e)'s "the SEED
declares no total" is FALSE -- it declares total_bytes 34000, and
upstream's copy is byte-identical. (b) "one byte short" is the FLOOR:
CRLF loses 3 B, and non-UTF-8 raises UnicodeDecodeError rather than
miscounting. (c) :339/:892 are stale; navigate by symbol.

Config hygiene, same commit because leaving it contradicts files[]:
_deliberate_exclusions still listed both files as deliberately
un-ceilinged, and it and _synced carried SESSION_RUNNER.md at 52,386 B,
1,977 B stale.

VERIFICATION. bash bin/tests.sh bare, exit read on the next line: 288
passed / 1 failed / 0 skipped, exit 1 -- IDENTICAL to the control at
6a8aacc. The failure is Test 9's github 404, out of scope.
test_context_budget.py 61 -> 108 OK. --selftest 35 -> 50 PASS, exit 0.
An earlier run showing 6 sync gitignore failures was DISCARDED: it
overlapped my edits to the tool and did not reproduce on a frozen tree.

COST, STATED: the tool that polices size grew 50,580 -> 68,081 B
(+34.6%). 5,747 B is the selftest gates; 11,754 B the arms. Nothing
declares a ceiling for context_budget.py itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDsoBhfExgxrmWjAmTk9dX
rmsharp added a commit that referenced this pull request Sep 15, 2026
The review of PR #80 (F1, option (a)) keeps starter-kit/FRAMEWORK_LEARNINGS.md
to rows 1-13 plus the reserved #14. Before that cut, every citation it would
leave dangling now states the rule it cited: context_budget.py:77 and :378
(Learning #34) and :409 ("learning #22 / #26a", another numbering), plus
five comments and docstrings in the two canonical-only test files (#34,
#16, #43).

bin/check-learnings sweeps only the Markdown files of the distributed
corpus, so the context_budget.py citations would have dangled in every
adopter with the check green. context_budget.py and test_methodology_trim.py
parse to an AST identical to b82dcff's; test_context_budget.py changes two
docstrings. No behaviour change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 15, 2026
…rowth warning; raise BL-53

Operator decision ("A, reworded as a growth warning"), from four options each
run in a --no-local clone before it was offered.

.context-budget.json, the file's entry: max_bytes 73,728 -> 81,920, density
fields re-measured (2.9051 B/token at 73,920 B, doubled-file method), and the
note rewritten to claim only a growth warning. The file is on-demand, so
context_budget.py computes no token verdict for it (Learning KJ5HST#34), and it
already measured 25,445 tokens -- past one Read -- before this change: the old
73,728 was a token limit in bytes that compaction had silently invalidated.

BL-53 records the question no limit answers -- how many learnings the
framework should carry before old ones retire -- with the S159 cost table.
Adopters are unaffected: the adopter seed does not budget this file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xuyQjauGqcqY3BYvbrfFT
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 20, 2026
The catch-up pass of the retirement plan, under D1-D4 as ratified at this
session's Phase 0. Every row of docs/FORK_LEARNINGS.md (15-83) was read in full
and tested against all three limbs of D1. Result: 0 retirements. The file is
untouched at 85,228 B, 3,308 B over its growth warning.

This corrects the plan's estimate in the direction it already pointed. Its "at
most 2 rows, ~2,900 B" was the optimistic bound of a ten-row sample that marked
KJ5HST#15 and KJ5HST#19 PARTLY covered; D1 retires a row "when, and only when, one of these
holds", and partly is not holds. Six rows are partly covered in total.

Two limbs are unsatisfiable across this corpus, both measured rather than
argued. (b) 13 rows cite an earlier row and every citation is a differentiation
-- sibling of, distinct from, the converse of -- never a restatement; and eight
rows are cited BY another live row or live config, so retiring one strands an
in-table reference. (c) 38 rows name a file path, 56 mentions, every one
resolving to a tracked file.

The sweep instrument was audited and had failed: six false hits in four rows
(FM KJ5HST#27, upstream's quoted "learning KJ5HST#22 / #26a", rad-con's KJ5HST#28/KJ5HST#29/KJ5HST#30/KJ5HST#34)
while also dropping bare KJ5HST#28-style references. Fork Learning KJ5HST#83 reproduced by
the document written to adjudicate it, recorded rather than quietly fixed.

Recommends keeping D3 and taking option C, for the operator to decide. Changes
no row, no ceiling, and does not write D3 into the close-out path (P4).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 20, 2026
…ts old subject's truths

Re-pointing a note to a new subject silently inverts every clause that was
true of the old one. Dated with git log -S: the clause entered at a51d848
(S159) true of the distributed file, inverted at 8cfaf0d (S176) which never
touched it, removed at 9db2c18 -- 26 sessions false.

D3 statement: 0 retired, 1 appended, no row qualifies. Considered KJ5HST#34 (the row
that justified option C; the ceiling still exists as a reported series), KJ5HST#26
(budgets generally, no gate enforces it) and KJ5HST#85 (one session old, a different
failure). None is mechanized, superseded or spent.

check-learnings --file docs/FORK_LEARNINGS.md --first 15 --no-citations:
72 rows, contiguous 15..86, 0 over 1,500 B.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Sep 20, 2026
P5 shipped at 9db2c18: the 81,920 B figure is a reported series, not a limit,
in the last artifact that still called it a warning to be answered. BL-53
closed at fc4a006 with its limits named -- no row has ever been retired,
option B stays declined and un-foreclosed, D3 is held by prose, not a gate.

Three claims failed verification and were corrected, one of them mine.
Phase 3A: S201's handoff scored 9/10 -- its predictions held exactly.
Phase 3B: self 8/10; I read an exit code through a pipe and briefly believed
the budget tool exits 0.
Phase 3C: fork Learning KJ5HST#86, D3 statement 0 retired / 1 appended / KJ5HST#34, KJ5HST#26
and KJ5HST#85 considered.
Phase 3E: 11/11 pass, results 10575dac7361, manifest 01a4ae7aa511, in a
--no-local clone of 4504996 with HEAD asserted by sha.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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