Skip to content

A methodology/ directory for a project's framework files, and bin/migrate-layout to move a project there - #99

Open
rmsharp wants to merge 33 commits into
KJ5HST:mainfrom
rmsharp:feat/methodology-directory
Open

rmsharp wants to merge 33 commits into
KJ5HST:mainfrom
rmsharp:feat/methodology-directory

Conversation

@rmsharp

@rmsharp rmsharp commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

@KJ5HST:

This pull request lets a project keep all of the framework's files in one directory, methodology/. Today they sit in two places: 18 at the project root, among the project's own files, and 12 under docs/methodology/. Every tool in the repository learns to find the files in either place. A project that changes nothing keeps its current locations, and a new command, bin/migrate-layout, moves a project when its owner chooses.

The numbered items I mention: #93 is my issue about the proof scripts that the ledger trimmer (methodology_trim.py) generates, which #94 fixed, and #92 added the release notes for v4.2 (both merged); #98 and #96 are my two other open pull requests; #67 was your issue about the dashboard's stale-copy warning, and #73 your pull request that fixed it. Every number below comes from a command, or is rounded from one; the scripts and their saved output are in my fork's evidence directory (the pr3, pr3b, pr4 and pr4b in their names are my own numbering, not pull request numbers). The commit hashes below are this branch's, except c8b9ddd and e7b389f, which are on my fork's main, and 65990cd, the head of #98.

What I am asking you to decide

  1. Do you want the single directory? I wanted it for my own 12 projects, to clear the project root and show which files belong to the framework; I found no issue on your repository that asks for it. The 30 rows of bin/_manifest.py are 18 files at a project's root (11 that bin/sync keeps current, and 7 "seeds", which it writes once, when the project lacks them, and the project owns afterwards) and 12 documents under docs/methodology/. With the directory, all 30 sit in one place. That is the only benefit. It costs this repository: the code that decides a project's layout is copied into 11 files; 138 lines name a file by its root path on purpose and carry a same-line comment, # layout: ok -- <reason> (the "acknowledged" count of python3 bin/check-layout-literals); 36 relative links became plain names in code spans (a relative link that is right in one layout is dead in the other); and bin/migrate-layout (1,457 lines) and its 280 tests are new. It costs projects: even a project that never moves receives 19 changed files at its next bin/sync, reads two framework files that are 244 bytes larger, and finds its framework documents naming one another by bare name (28 fewer lines name docs/methodology/), with a new paragraph, the third of SESSION_RUNNER.md, saying where to look. One known gap bears on this decision: an earlier copy of the ledger pre-commit hook passes a commit with no ledger entry once the ledger has moved (see "Known gaps"). The branch is 33 commits and adds 18,367 lines.
    • If you do not want the directory, the first commit, fbcef39, can be taken alone on your current code (271 passed, 0 failed, 0 skipped and 12/12 gates, in a clean clone). The other commits sit on top of the directory work, and I have not tested them without it.
  2. Which of the dashboard changes do you want? These come with the earlier work in fbcef39, and they are policy, not fixes. Please tell me which to remove and I will remove them. The other dashboard changes in fbcef39 (2.11.3 to 2.21.0) are not itemised here, except one that changes what it reports about your ratchet: since 2.21.0 it walks the gate manifest's history with git log --first-parent, so a merge no longer prints a loosening nobody made, and one made on a side branch is reported at the merge that carried it in. I will itemise the rest on request.
    • (a) The dashboard's --sync takes an optional directory: with one, it writes only that project; without one, every project it finds. It skips a target that git tracks, or a brand-new file the project's .gitignore does not cover, unless --force is given. Your pull request fix(dashboard): proportionate stale-copy remedy; bare --dry-run no longer writes (#67) #73 made the stale-copy warning say cp <canonical> <copy>; this branch's warning says --sync <directory> instead. Both answer check_stale_version() advertises --sync, which writes 26 files across 25 sibling repos #67, which found that the old warning advised a --sync that rewrote 26 files across 25 repositories.
    • (b) "methodology" is no longer in EXCLUDE_DIRS, so a run of the dashboard over a directory of projects scores this repository too.
    • (c) How the dashboard recognises a project's installed copy of a framework tool is now one table, and the list of names (FRAMEWORK_INSTALLED_SOURCE) is derived from it; yours keeps the list and a separate signature table, with a test that they agree. The same 7 names are recognised either way, but the trimmer loses its signature fallback: a copy with no TRIM_VERSION line is no longer recognised. Every version of the trimmer in your history (17 commits, 1.5.0 to 1.8.2) has that line.
    • (d) Five new risk rows: two for a file past the limits I measured for an agent's file-read tool (256 KiB, past which the read is refused, and 25,000 tokens, past which it is cut short with a banner, counted at 2.27 bytes per token, the densest content measured); two for a file a session is told to read whole, a ledger or a backlog, when it is past that budget (with a lower severity if the project's own trimmer can archive it); and one that repeats the trimmer's own size trigger (192 KiB). The thresholds are my choices.
    • (e) Two of your tests are removed: test_stale_warning_leads_with_the_project_scoped_remedy, because (a) replaces the cp remedy it asserts, and test_every_framework_installed_source_name_has_a_signature, because (c) derives the list of names from the signature table, so the two cannot disagree. The other two tests of TestCliRemedyProportionality assert behaviour this branch keeps and are restored as you wrote them (9848b62).
  3. In what order should this and feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98 go? feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98 (open) and this branch both rewrite starter-kit/methodology_trim.py and its tests. Against feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98's current head (65990cd), git merge-tree reports conflicts in 3 files and 5 regions (the trimmer 3, its tests 1, .quality-gates.json 1); feat(close-out): print and lint the Phase 3G close-out report (canonical-only tool; copy it) #96 (open) conflicts in 2 files and 3 regions (.quality-gates.json 2, bin/tests.sh 1). This branch carries none of feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98's three commits (SESSION_NOTES.md in the trimmer's ledger table; two messages and three exit-3 statements made true; a warning for an uncommitted front-matter edit): the trimmer here is your 1.8.2 with the layout changes on top. Both name the trimmer 1.9.0 for different changes (feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98's first commit, and this branch's trimmer commit), so whichever lands second takes a later number. Please say whether I should wait for feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98 and rebase on it, or whether you will take this first and I rebase feat(trim): SESSION_NOTES.md joins the ledger table; warn of an uncommitted front-matter edit (refs #93) #98 and feat(close-out): print and lint the Phase 3G close-out report (canonical-only tool; copy it) #96 on it. I have not resolved the conflicts.
  4. Three smaller choices.
    • 6ce88cd drops a duplicated example command (84 B) from the runner (SESSION_RUNNER.md) so that it reads under its token ceiling. The same commit also re-records the runner's bytes-per-token ratio in .context-budget.json, as the note in that file asks when the file changes, which lets the runner grow 43 B more before the budget tool (context_budget.py) reports it over. That second change can be dropped on its own; the cut alone is enough to pass.
    • Ten commits remove references that only my fork can resolve, such as backlog and session codes in comments and messages: seven (e051462 to 8c37c28) and a tail of three (1477af2 to 47637be). Please tell me whether to keep these commits or drop them; if you drop them, the references stay in the code. A merge commit or a rebase keeps them as separate commits and a squash folds them in. The tail can be dropped alone; the seven only with 9848b62 rebased. They are not exhaustive: some references of that kind remain, and 27 of the 33 commits end with a (cherry picked from commit ...) line that names a commit only my fork has.
    • No CHANGELOG.md entry and no change to README.md or CLAUDE.md (which list the files) is included; the 33 commits were made without your pre-commit hook, which would require a ledger entry in each. Please say if you want one entry for the whole pull request. I have not changed the release version; release notes would be a separate pull request, as with docs(release): v4.2 — CLAUDE.md §Versioning and README What's New #92.

The sections below give the detail behind these four items and the evidence.

Size, what reaches a project, and what it costs

Size. The branch adds 18,367 lines and removes 1,098 (git diff --shortstat d50ce29 HEAD). Most of that never reaches a project. bin/sync writes 19 of the changed files into a project, with 2,540 lines added and 526 removed in all; 3 more changed files are the sources of seeds, which only a new project receives. The other 25 files, with 15,820 of the added lines (86%), stay in this repository: tests, tools that only this repository runs, and its gate configuration. The dashboard is counted twice in that total (as starter-kit/methodology_dashboard.py and as an identical copy in tools/). About 37% of the added lines (6,883, in fbcef39 and 1d93579) are earlier work of mine that is not about the directory (pr4-distribution.py prints the split, pr4b-facts.sh the 37%).

What it costs to use. A session must read two of the framework's files in full, SESSION_RUNNER.md and SAFEGUARDS.md. Together they are 244 bytes (0.35%) larger on this branch, about 90 tokens at the runner's measured 2.81 bytes per token. The programs a session runs (the dashboard, the trimmer's check, the budget tool) took no longer than upstream's: the same on a project of 3 commits, and on one of 517 the dashboard took 0.66 s against 0.92 s (pr4-cost.sh).

What the change does

  • Paths. bin/sync writes a project that keeps the current layout (called legacy in the tools' --layout options) the same paths it writes today (measured below). bin/sync and bin/check-links take --layout (for bin/sync, auto is the default: it keeps the layout a project has, and gives an empty project the current layout); bin/status and every other tool read either layout. The manifest has a second table, NEW_LAYOUT, giving each file's place under methodology/; it is plain data, so bin/sync --source github (which clones the framework repository) can read it without running it.
  • No tool guesses where the files are. tools/layout_resolver.py is a short block of code that decides a project's layout from where an anchor file sits. The default anchor is SESSION_RUNNER.md: at the root, the current layout; under methodology/, the new one; in both places, the tool refuses and names both. A tool that reads a ledger anchors on that ledger instead, and the ratchet and the budget tool on their configuration file, so a project that moved only the framework's files (--tier 1, below) is read correctly. For a file other than the anchor that exists in both places (for example a project's own product CHANGELOG.md), the tool reads the copy under methodology/ as the framework's and leaves the other alone, but only when the runner is under methodology/ and not at the root; otherwise it refuses. The block is copied into 10 tools and into the dashboard's identical copy, because the four tools a project receives (methodology_dashboard.py, methodology_trim.py, context_budget.py, quality_ratchet.py) are single files that import only the standard library; the six tools that stay in this repository carry the same block, so one test covers all 11. python3 tools/test_layout_resolver.py fails until all 11 copies equal tools/layout_resolver.py.
  • Moving a project. bin/migrate-layout makes no change unless given --apply. --tier 1 moves the framework's files, --tier 2 the project's own state (its seed files, the files the tools generate, the archive shards the trimmer wrote, and the project-owned PROJECT_LEARNINGS.md that BOOTSTRAP.md names), all (the default) both.
    • It refuses, before writing anything, a tree that is not a git repository with a commit; has uncommitted changes; is half-migrated (a runner at the root and another under methodology/); already holds a destination file; keeps its framework files out of git (its .gitignore lists them); is not current with what bin/sync would write; or has a file to rewrite that it cannot rewrite safely (for example, a ledger with a code fence that never closes).
    • An apply is one commit. It moves the files, rewrites the moved paths in CLAUDE.md, in anchored .gitignore entries and in .context-budget.json and .quality-gates.json, and adds a ledger entry. Every move must remain a rename at 90% similarity or better, so that git log --follow still reaches the history; a ledger too small for that fails (a project with a very short ledger must add entries first), and the apply is rolled back (exit 3), as is any step that fails before the commit. The report names git revert <commit> as the way back.
    • It checks itself. Before and after the commit it runs read-only checks (bin/status, the two ledger checkers, bin/check-links, every archive shard's proof, and how far git log --follow reaches). If a result differs afterwards, it exits 4 and keeps the commit (--skip-checks turns the checks off).
    • Like bin/sync and bin/status, it is not in bin/_manifest.py; a project runs it from a checkout of this repository. Its own suite of 280 tests takes about 6 minutes (two fast classes of it also run in bin/tests.sh), so the two gates that run it each set timeout_seconds to 3600.

What the commits contain

Each commit's message describes it. A suggested order for reading: fbcef39, then 41a1e58 (the foundation: the layout resolver, test projects in both layouts, bin/check-layout-literals, which finds a tool that names a file by its root path, and NEW_LAYOUT), then the rest in order. Of the last twelve commits, ten drop references that only my fork can resolve (decision 4); fd43f70 corrects four stale statements in comments and gate reasons, and 9848b62 restores the two tests named in decision 2 (e) and raises their gate's floor by two (neither changes a code path).

  • fbcef39 (6 files, +6,187 / -552), earlier work. The dashboard 2.11.3 to 2.21.0 (both copies) and its tests. In bin/tests.sh: three blocks changed so that cmd | grep -q under pipefail cannot report a match as a failure, a lint for that pattern, a skip helper and an executable-bit check derived from the manifest. It also adds to BOOTSTRAP.md a row, in its table of files bin/sync never overwrites, that names every seed, and raises two thresholds in .quality-gates.json (the shell suite's, 261 to 271, and the dashboard's, 229 to 354). It fixes one defect: git log --reverse --format=%ai -1 applies -1 before it reverses, so first_commit_date was the newest commit and a project's age was the days since its last commit; the dashboard now reads the root commits (--max-parents=0).
  • 1d93579 (4 files, +696 / -20), earlier work. The quality ratchet's 1.4.0 and 1.5.0. A gate may set timeout_seconds; a command that outlives it is reported unmeasured (its result could not be determined), not as exit code 127, and its whole process group is stopped. Two gates that read the same command's output share one run of it. Changing timeout_seconds is a warning, not a refusal. It does not depend on the layout, but it is built on the ratchet's layout commit 7d87cb2.
  • d818ca1 (2 files, +5 / -2), a small change elsewhere. A rule in starter-kit/HANDOFFS.md and HOW_TO_USE.md for a close-out receipt that cites a gate run: a gate that read unmeasured must be repaired, or named in the receipt. Its check is in my version of bin/check-handoff, which is not carried, so the rule is prose only.
  • One of your tests is rewritten (07ec025): Test 15 now counts the status table's rows, because bin/status prints a layout: line that names the project and the old assertion counted lines naming the project (31 for 30 files).
  • 62680cd (5 files, +1,247 / -105), the trimmer. Your 1.8.2 with the layout changes on top, named 1.9.0: it finds a ledger at the root or under methodology/, writes its archive piece beside it and proves the trim. Its tests go from 227 to 265, and some of them compare against a frozen copy of the proof template 1.8.2 writes (tools/fixtures/trim-verify-template-1.8.2.sh, 483 lines).
  • The dashboard is a whole file, not hunks, because my version had diverged from yours: a three-way merge of your copy with mine, from the copy my work began with (c8b9ddd), conflicts in 17 places in each of its two copies (pr4-mergefile.sh, with my fork's main as of e7b389f). The trimmer is not (the same merge conflicts in 1 place there and 1 in its tests). For bin/check-ledger and bin/check-handoff it contains the layout hunks only.

What a project sees

A project that keeps the current layout gets the same paths. Sync two temporary test projects, one with upstream's bin/sync and one with this branch's, and compare:

git init a-up && git -C a-up commit --allow-empty -m init ; cp -R a-up a-pr
python3 <upstream checkout>/bin/sync a-up ; python3 <this branch>/bin/sync a-pr
diff -rq --exclude=.git a-up a-pr

Both write the same 30 paths and neither makes a methodology/ directory. 22 of the 30 differ in bytes, and every one is a file this pull request changes: the cost of the next sync to a project that did not ask for the change. With its 7 seeds edited and its framework files at upstream's tip, upstream's bin/sync writes 0 paths; this branch's writes 19, needs no --force, and changes 0 of the 7 seeds (pr4-fixture.sh).

A project that has moved is synced where its files are. Take a project whose 30 files are already under methodology/. Upstream's bin/sync writes 30 paths outside methodology/, a second copy of every framework file and seed; this branch's writes none (pr4-moved.sh). So once a project can move, the sync tools have to change with it. On my 7 projects that had moved, upstream's bin/sync wrote 23 framework files at the old places at each and created 41 seed files at the root across six of them; two projects' own pre-commit hooks refused the resulting commit as half-migrated.

My own 12 projects (7 under methodology/, 5 not; pr3b-adopters.py is the method) are mine, so you cannot run this on them. Without --force, this branch's bin/sync refuses 10 of them, over 52 files: 51 are versions from my fork's history that no commit of this branch carries, and one is a project's own edit of methodology_trim.py (49 lines differ from my fork's copy), which --force drops without saying so. After one --force, a plain run writes nothing at any of the 12; it changed none of their seeds.

Evidence

Each check ran in a fresh --no-local clone of the head with no modified files, serially; upstream's tip is the control. pr4b-claims.sh runs them all (about 30 minutes).

Check Command upstream d50ce29 this branch
The suite passes and has more tests bash bin/tests.sh 261 passed, 0 failed 302 passed, 0 failed, 0 skipped
Every declared gate holds python3 starter-kit/quality_ratchet.py --run 12/12 pass, 0 fail, 0 unmeasured 18/18 pass, 0 fail, 0 unmeasured
Links resolve in both layouts python3 bin/check-links --layout both usage error: it takes only --tree (exit 2) OK: 80 links across 23 documents, in each layout (116 at your tip)
One copy of the layout-deciding code python3 tools/test_layout_resolver.py not present 76 tests OK; 11 copies, each equal to tools/layout_resolver.py
No gate threshold in .quality-gates.json is lowered quality_ratchet.compare, each commit against its parent 0 refusals over 33 commits; gates 12 to 18; five thresholds raised

I ran the suite and the gates at points through the series, not at every commit.

What this does not show, and what is missing

  • The route a project takes alone from GitHub: every sync above used the local source, not bin/sync --source github.
  • Any project that is not mine: the 12 are mine, and 10 carry versions of the framework's files that are in no history here.
  • Windows, your machine, a project's own CI: this repository has no CI, so every check is local.

Known gaps

These came from the 12 projects and are open:

  • A sync refuses a project's edited framework file by name but does not say which published version is nearest or how many lines differ, and --force then drops the edit (upstream's bin/sync does the same).
  • With only the framework's files moved (--tier 1), the dashboard writes a second history file, dashboard_history.jsonl, under methodology/ while the one at the root stays, unused.
  • On a ledger in the old format (no month headings), the migration appends its entry at the end, out of order; bin/check-ledger fails on such a ledger before and after.
  • For the hook that context_budget.py install-hook writes, the migration warns that it "will refuse the migration commit". In fact the hook does not refuse it.
  • An earlier copy of the ledger pre-commit hook of SAFEGUARDS.md keeps looking for the ledger at the root, so once the ledger moves it passes a commit with no ledger entry, without saying so. The migration reports such a hook and leaves it. The hook in this branch (.githooks/pre-commit) follows the ledger.
  • A project's own tests or scripts that read a moved file by name can break. The migration lists the other files whose text mentions a moved name; the list is an upper bound, not the set that breaks.

🤖 Generated with Claude Code

rmsharp and others added 30 commits October 26, 2026 23:51
… pipeline lint, and BOOTSTRAP's never-overwrite row naming every seed

Part 1 of 2. The earlier lineage: the dashboard (both copies) 2.11.3 to 2.21.0 and its unit
suite. The ledger trimmer and its unit suite are upstream's own (1.8.2) and are not touched.

bin/tests.sh gains a skip() primitive, so an assertion that could not be built is counted and
named in the summary instead of passing; the exec-bit check is derived from the manifest
instead of naming one tool; pipelines read under pipefail become here-strings in three blocks,
and a new block (Test 36) fails the suite if an early-exiting consumer ever decides a fail arm
again; another (Test 35) pins BOOTSTRAP.md's never-overwrite row to the manifest's seed list,
with the row corrected to name .gitattributes.

Two dashboard unit tests that assert facts about this repository's own docs/planning/BACKLOG.md
are not carried, and the ledger-count test's floor becomes min(6, ledgers present).

.quality-gates.json tightens by exactly what this adds: tests-sh-passed 261 to 271, dashboard-unit-tests 229 to 354. The trimmer's floor stays at upstream's 227.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…literal scanner

Part 2, layer 1. A project keeps its methodology files either at its root (legacy) or one level
down in methodology/ (new). tools/layout_resolver.py answers which, from one anchor file, by a
four-row table, as one marked block of standard-library code that each shipped tool will embed
byte for byte in the layers that follow; this layer embeds it nowhere. tools/layout_fixtures.py
builds scratch trees in both layouts (and the tier-1, half-migrated and empty shapes) from the
manifest. bin/check-layout-literals lists every line of a shipped tool that names a methodology
file by a root path: it reads 159 sites over 9 files of the tree as it stands, and is not a gate
yet, because it reads 0 only once those tools are resolved.

bin/_manifest.py gains NEW_LAYOUT, the target layout as a table of literals beside DISTRIBUTION;
nothing but the fixtures and their test reads it yet. tools/test_layout_resolver.py (74 tests) is
wired into bin/tests.sh. The lists of tools that embed the block start empty, so two of its loops
compare nothing until the next layer fills them.

.quality-gates.json tightens by exactly what this adds: a new layout-unit-tests gate (74) and
tests-sh-passed 271 to 272.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…thodology/

Part 2, layer 2. A project keeps its methodology files at its root (legacy) or one
level down in methodology/ (new). The two gates that guard a commit now follow the
ledger and the manifest to either place, so that moving a file cannot disarm the gate
that protects it. Before this layer the hook named CHANGELOG.md at the root only: once
the ledger moved it found no tracked ledger, took its "no ledger, never block" branch,
and every later commit passed without a ledger entry. The ratchet's chain guard named
the root manifest only in the same way, so a moved manifest was never ratcheted.

.githooks/pre-commit reads the ledger from the index, at the root or under
methodology/. A ledger tracked in both places is a half-migrated tree and is refused,
naming both, unless the runner is tracked under methodology/ and not at the root: then
the methodology ledger is the ledger and the root file is the project's own changelog,
left alone. The never-edit check reads HEAD's copy from wherever HEAD kept the ledger,
so a commit that renames the ledger and rewrites an entry is refused; a trim's shard
may sit under docs/archive/ or methodology/archive/; the ratchet chain finds the tool
under starter-kit/, under methodology/ or at the root, and the manifest at the root or
under methodology/. Its selftest builds its fixtures in both layouts.

starter-kit/quality_ratchet.py (1.1.0 to 1.3.0) embeds the layout resolver's block
byte for byte (the layout suite asserts it), finds a manifest under methodology/,
writes its results file beside the manifest, and judges a manifest move: both paths
are read from the index and walked in history, so a threshold lowered inside the move
commit is compared with the old copy, and a manifest held in both places is a tie the
runner's location decides, or a refusal naming both. The ratchet's later changes to a
gate's own timeout and process group (1.4.0 and 1.5.0) do not touch the layout and are
not in this layer.

tools/test_quality_ratchet.py has 81 tests (45 before). bin/tests.sh gains Test 37, the
real hook and real git in both layouts, with a control for each assertion (a mutated
copy of the hook or the ratchet must fail), and one assertion is rewritten: the hook
chains the ratchet before the ledger gate, checked by line order, since the chain names
the tool through variables. tools/test_layout_resolver.py takes its first entries: the
ratchet is a listed copy of the block, and the hook and the ratchet are scanned and read
zero sites, so the two loops that compared nothing at layer 1 now compare something.
bin/check-layout-literals reads 122 sites (159 before); it is not a gate yet.

.quality-gates.json tightens by exactly what this adds: ratchet-unit-tests 45 to 81 and
tests-sh-passed 272 to 298 (the suite reads 298 passed, 0 failed, 0 skipped).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…measured, and its command is stopped with its whole process group

Two releases as one checkpoint, independent of the layout work before it.

1.4.0: a gate's command that outlives its budget (600 s, or the gate's own
`timeout_seconds`) is UNMEASURED with the note `timeout (N s)`. It used to
read as exit code 127, so it could pass against a floor at or under 127,
fail against a ceiling, or yield a number read out of the timeout message.
`timeout_seconds` is validated and a change to it is a warning, not a
refusal. Gates that share one command share one run, which gets the largest
budget any of them declares.

1.5.0: where the platform has process groups, a gate's command runs in a
session of its own and a timeout, an interrupt, a hangup or a SIGTERM
kills its whole group, not only the shell. A suite that outlived its
budget used to run on to its end through every later gate. A signal the
caller ignores (`nohup`) stays ignored. Elsewhere the command runs as in
1.4.0 and a timed-out one may keep running.

Carries the tool (+203 / -17), its tests (120, from 81), the seed's
`_gate_schema` line, and the `ratchet-unit-tests` floor 81 to 120. No
`bin/tests.sh` block changes: none cites a gate's budget or process group.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…t the root or under methodology/, writes its shard beside it, and proves the trim

Part 2, layer 3. The shard directory and the link prefix follow the directory of
the ledger being trimmed, so a project that moved its ledgers under methodology/
keeps trimming them. A root ledger is written as before; a ledger under
methodology/ writes methodology/archive/ and climbs one level, with ../ links
ordinary. The action ledger is found by the layout resolver the tool now embeds
(the layout suite asserts the block is the module's, byte for byte), a
half-migrated tree is refused, a ledger tracked at both places is decided by the
framework anchor, and both archive directories count as the trigger's history.

The tool was 1.8.2, so this is the next minor release: a new finding code and a
second output location. Where the two meet, `--reverify` refuses a frozen proof
whose PREFIX is not the one this tool writes; that was the constant "../../" and
is now the prefix of the proof's own ledger, since a ledger under methodology/
climbs "../".

Carries the tool (+241 / -101), its tests (265, from 227), the frozen copy of
1.8.2's proof template those tests compare against (tools/fixtures/), the
trimmer's entries in the layout suite's lists of embedding and resolved tools,
and the `trimmer-unit-tests` floor 227 to 265. No bin/tests.sh block changes:
the ones that run the trimmer use a root ledger, whose output is unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ts history file and its tool at the root or under methodology/

Part 2, layer 4. The history file lives beside the config, the pre-commit gate
reads HEAD's own declaration of the class wherever HEAD kept it (at the root,
or under methodology/), and the installed hook names the tool and its twin, so
a project that moved its framework files under methodology/ keeps its budget
gate. The project root is found by the layout resolver the tool now embeds (the
layout suite asserts the block is the module's, byte for byte); a repository
that is itself called methodology stays its own project, and a tree holding
both configs is decided by the framework anchor or refused naming both.

Carries the tool (+146 / -18), its tests (163, from 148), the tool's entries in
the layout suite's lists of embedding and resolved tools, and the
`context-budget-unit-tests` floor 148 to 163. No bin/tests.sh block changes:
none cites what this layer changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit e9c5cb86c5c70d46d0f7e23b7b1559bd1f7b022f)
…ds a project that keeps its methodology files under methodology/ as it reads one that keeps them at the root

Part 2, layer 5. The checklist items keep their names and are located through
the layout resolver the tool now embeds (the layout suite asserts the block is
the module's, byte for byte, in both twins); a project whose runner is under
methodology/ is still an adopter; a half-migrated tree (the runner at both
places, or a state file at both with nothing to decide) is a high risk that
names both paths. The file walk, the installed-source fingerprint, the ledger
locator and the trim and read-cap rows read either layout; --sync resolves each
target's layout, refuses a half-migrated project by name, and a copy inside
methodology/ finds its project and writes beside itself; the quality-gate read
finds the manifest where it lives and follows its history across the move; the
publisher's checklist follows its own moved ledgers.

Carries the two twins (+370 / -115 each), their tests (395, from 354: +595 / -4
against the candidate's file, which keeps the two removals and the relative
ledger floor it already had), the dashboard in the layout suite's lists of
embedding and resolved tools and a test that the tools/ twin carries the same
block (75, from 74), and the `dashboard-unit-tests` and `layout-unit-tests`
floors. No bin/tests.sh block changes: none cites what this layer changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit dd581fed56958b228c50f0563fda0fe37de4213e)
…es the project

The test counted lines containing the project's name. A table row starts with it; a line
above the table that merely names the project is not a row. Counting rows is what the test
means, it passes on today's bin/status unchanged (298 passed, 0 failed, 0 skipped), and it
keeps passing when the tool prints a line above the table.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 4c0bdded780dc53beb645e8b235f9d8f1231b85a)
…ader find a project's files at the root or under methodology/

bin/sync takes --layout auto|legacy|new: auto keeps a project in the layout it has and gives an
empty one the legacy layout; a legacy project asked for the new layout, a migrated one asked for
the legacy, and a half-migrated one are refused before any write (exit 2). bin/status prints a
`layout:` line per project and reads its files and seeds where that layout keeps them.
bin/check-links takes --layout legacy|new|both and simulates either tree. bin/_manifest_reader.py
reads the manifest's second table (NEW_LAYOUT) as data, so --source=github can serve either layout.

Each of the four tools is replaced whole by its next revision; nothing is merged. The layout
suite's COPIES list gains the three tools that now embed the resolver block. The shell suite
passes unchanged on this commit: 298 passed, 0 failed, 0 skipped. The tools' own suite and its
gates are the next commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 261b8d362fde8b7357dc61e5123ce936a8a54b96)
…r's scope

tools/test_sync_layouts.py (82 tests) runs bin/sync, bin/status and bin/check-links as commands in
scratch projects: a legacy tree, a migrated one, an empty one, a half-migrated one, and
--source=github against sources with and without the manifest's second table. bin/tests.sh runs
it. One assertion of the suite is left out here: it requires bin/migrate-layout to be a file, and
that tool arrives in a later commit.

Two gates are declared: sync-layout-unit-tests (82) and layout-literals (at most 0 sites).
tests-sh-passed goes 298 to 299 and layout-unit-tests 75 to 76, each measured.

bin/check-layout-literals no longer scans bin/check-handoff and bin/check-ledger, the two
canonical-only checkers adopters never run and that this change does not teach the layout; it read
10 sites in them and reads 0 over the 12 files it scans now. The layout suite's scan-set test names
the three tools this change resolves, and one new test pins the two exemptions and their reason.

The shell suite passes on this commit: 299 passed, 0 failed, 0 skipped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 0aa1897ee14f5bce115771961a372f87de5ea03f)
…'s ledger at the root or under methodology/

Both checkers embed the layout resolver block, find the ledger where the project keeps it, and
refuse a half-migrated tree (the ledger at the root and under methodology/ with no runner under
methodology/ to decide) instead of guessing: check-ledger exits 2 naming both, check-handoff
exits 1 naming both. check-ledger --all reads the archived shards beside the ledger in either
layout, and in a repository that is itself called methodology it still reads docs/archive/.

bin/check-ledger is replaced whole by its next revision: its whole difference from this tree's
copy is the layout reading. bin/check-handoff is this tree's copy plus the same reading and
nothing else: the resolver block, default_path(), the half-migrated refusal and the same-line
markers that acknowledge a conventional file name in message text. The layout suite's COPIES
list gains both tools. Their own suite, the wiring and the scanner's scope are the next commit.

The shell suite passes on this commit: 299 passed, 0 failed, 0 skipped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit a459b8bbbb4aa0bc00539d1f65dbd76b58a621d6)
…nner now reads both

tools/test_checker_layouts.py (11 tests) runs bin/check-ledger and bin/check-handoff as commands in
scratch projects: the ledger at the root, under methodology/, in a tie the runner decides, and in a
half-migrated tree; check-ledger --all over the shards beside the ledger in either layout; a
repository that is itself called methodology; and, in a half-migrated tree, a named ledger
(--file), which is the way out the refusal message offers. bin/tests.sh runs it. One gate is
declared, checker-layout-unit-tests (11); tests-sh-passed goes 299 to 300.

bin/check-layout-literals no longer exempts bin/check-handoff and bin/check-ledger: both read the
layout now, so the scanner reads them like every other shipped tool (14 files, 0 sites). The layout
suite's scan-set test names them, and the test that pinned the exemption is replaced by one that
pins what is still exempt, the manifest and the suite, so the layout-unit-tests floor (76) is
unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 505541c3b351fdd5971f0b662599667a78dee5c8)
…, and their references hold in both layouts

SESSION_RUNNER.md opens with where the files are: documents are named bare and found beside the
runner, a legacy project keeps the framework documents in docs/methodology/, a project that moved
only its framework files keeps its ledgers, notes and configs at the root, and in a migrated
project the tool and the file it takes both get methodology/ in front. BOOTSTRAP.md gains a
section, Two layouts: what each layout is, what bin/sync --layout does with each, how a project
moves between them, and that the commands in the guide are written for the legacy layout; the
steps that name a directory or a command say what changes. CLAUDE_TEMPLATE.md says where the
runner and the extracted learnings file sit in a migrated project.

References that held only in the legacy layout (a relative link out of the document, or a
docs/methodology/ path) become a bare name in a code span, or a path that holds in both. The
simulated adopter tree reads 31 dangling links in the methodology/ layout after this commit, 35
before; the legacy layout reads none, as before. The remaining references are the next commits.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit c8d437541d10029c4227cfaac4795ad2dfa9044a)
…the runner reads under its ceiling again

The runner's "Where the files are" paragraph carried an example of the trimmer's command in a migrated
project, and FRAMEWORK_APPARATUS.md already carries the same command and cites that section by name. The
runner is a whole-read file with a token ceiling, so the copy is dropped from it: 84 B, 53,184 B to 53,100 B.

Measured by the doubled read (the file twice over, so the Read tool prints a whole-file token count),
against a control that reproduced its recorded 37,599: the runner before the cut read 18,911.5 tokens,
11.5 over its 18,900 ceiling (the config's density, measured on the earlier blob, made the tool say 18,921);
after the cut it reads 18,876.5, 23.5 under. The runner's row in .context-budget.json records the new
blob's density (2.8130 B/token at 53,100 B) and a sentence saying how it was measured; its ceiling,
max_tokens 18,900, is unchanged, and `context_budget.py --status` reads ok and exits 0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit ced2c82313f548637892b88943ca33f21e512a94)
…th layouts

FRAMEWORK_APPARATUS.md gives the trim command for a project that keeps its methodology files under
methodology/. HOW_TO_USE.md says the runner may sit at the project root or in methodology/ and
where to put the framework. ITERATIVE_METHODOLOGY.md, RECOMMENDED_SKILLS.md and the CHANGELOG.md
seed named other documents by a link that only resolved in the legacy layout (../../ out of
docs/methodology/, or a docs/methodology/ path); each is now the file's bare name in a code
span, which reads the same in either layout.

The simulated adopter tree reads 8 dangling links in the methodology/ layout after this commit,
31 before; the legacy layout reads none, as before.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 04918ce3c69304e3f614984637a906902ecad2e8)
…he safeguards without a path (1 of 2)

The architecture, audit and development workstreams and two of the campaigns pointed at
RECOMMENDED_SKILLS.md, SAFEGUARDS.md or SESSION_RUNNER.md with a link three directories up, which
resolves from docs/methodology/workstreams/ and from nowhere in the methodology/ layout. Each is
now the file's bare name in a code span.

The simulated adopter tree reads 2 dangling links in the methodology/ layout after this commit,
8 before; the legacy layout reads none, as before. The other two are the next commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 23e6e66a6f26b0b4c8d786fa6b3be0776cdcab25)
…he safeguards without a path (2 of 2)

The campaign template and the workstream template pointed at SESSION_RUNNER.md and
RECOMMENDED_SKILLS.md the same way. With them, the 80 relative links across the 23 distributed
documents resolve in the simulated adopter tree in the legacy layout and in the methodology/
layout: 2 dangling before this commit, none after. The check that holds both is the next commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 0248ebf22ca6297bb68194882dc2e67d01f3c9eb)
Test 10 gains a second check beside the first: bin/check-links --layout both reads the simulated
adopter tree in the legacy layout and in the methodology/ layout and fails on a link that
resolves in only one. It reads exit 1 with 35 dangling links in the methodology/ layout on this
tree before the four commits above, and exit 0 after them, so a new link out of a document that
only holds in the legacy layout turns the suite red.

tests-sh-passed goes 300 to 301, measured: 301 passed, 0 failed, 0 skipped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 18cda0f291705ab5e25090bb8418e6d30c4b07e4)
… files under methodology/ (1 of 2: the tool)

The tool is a dry run unless --apply is given. It plans the move from the manifest's two tables,
refuses before writing a tree that is dirty, half-migrated, in ignore mode or not current, or one
whose destination exists, and applies as one commit through the project's own hooks, rolled back
on any failure. It runs bin/check-ledger and bin/check-handoff over the project before and after
and exits 4 when their verdicts differ.

The layout suite's COPIES list gains the tool, so the suite asserts it carries the resolver block
byte for byte like every other tool that embeds it. The sync suite gets back the one assertion it
could not make until the tool existed: bin/migrate-layout is a file, which the sync layer's
refusal message points at. The tool's own suite and its gates are the next commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 2942e46c0ac06d7ae6a8a3efe3c954cc5f860625)
…ll suite and its two gates (2 of 2)

tools/test_migrate_layout.py runs bin/migrate-layout as a command in scratch git projects the
real bin/sync wrote: the plan, the refusals, the one commit and its rollback, the rewrites, the
checks before and after. It is 280 tests and takes about six minutes (365 s measured here), so
bin/tests.sh runs only its two fast classes (95 tests, half a second); wired in whole it would
roughly double the shell suite and push it toward the 600 s a gate is given.

That leaves the suite's colour with no gate to carry it: a count gate whose command has an
extract reads the number and ignores the exit code, so it would pass over a suite that failed.
The suite therefore gets two gates over one command string, as tests-sh-passed and
tests-sh-failed are: migrate-layout-unit-tests (min 280, the count) and
migrate-layout-unit-tests-failed (max 0, no extract: the exit code). The ratchet runs the
command once for both. Both declare timeout_seconds 3600.

tests-sh-passed goes 301 to 302, measured: 302 passed, 0 failed, 0 skipped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit ab35e96508c10edecc1ede799318c67adb47130e)
…ed or names them

quality_ratchet.py 1.5.0 makes `unmeasured` a reading: a gate that outlives its budget prints in the
summary line as `U unmeasured`. The two documents that tell a session to cite that line did not say
what to do when U is above 0. The "Citing the gate run" paragraph of starter-kit/HANDOFFS.md and the
3E bullet of HOW_TO_USE.md now say it: repair the gate (its command, or `timeout_seconds` if it is
only slow) and run again, or name each unmeasured gate in the receipt.

The paragraph keeps its sentence about bin/check-handoff as it was. The checker lints the citation's
token, not this clause, so the clause is stated as the rule and not as something the checker enforces.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 5afc96215eeaeb6c5557dae867bf5c6d79c0017a)
…strings

Removes backlog codes, phase numbers and plan citations that name documents outside this
repository from the comments and docstrings of bin/sync, bin/status, bin/check-links,
bin/_manifest.py and bin/_manifest_reader.py. Comments and docstrings only: each file's token
stream, read without them, is equal before and after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit c933b0f90be8af436f937c2c794bec055b251967)
… the checkers' comments

Removes backlog codes, session and phase numbers and plan citations that name documents outside
this repository from the comments of bin/tests.sh, .githooks/pre-commit, bin/check-layout-literals,
bin/check-ledger and bin/check-handoff. Full-line comments only: each file, read without them, is
equal before and after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit d31c25daa431678400ecc584b506cf0809c85213)
…es' and their tests' comments

Removes backlog codes, session and phase numbers, coupling labels and plan citations that name
documents outside this repository from the comments and docstrings of tools/layout_resolver.py,
tools/layout_fixtures.py, tools/test_layout_resolver.py, tools/test_sync_layouts.py and
tools/test_checker_layouts.py. Comments and docstrings only: each file's token stream, read
without them, is equal before and after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit c1cdc2ec9bc35a8656170b9095fce882ab14cda0)
… gate's and their tests' comments

Removes backlog codes, session and phase numbers, coupling labels and plan citations that name
documents outside this repository from the comments and docstrings of starter-kit/quality_ratchet.py,
starter-kit/context_budget.py, tools/test_quality_ratchet.py and tools/test_context_budget.py.
Comments and docstrings only: each file's token stream, read without them, is equal before and
after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 71e00e89c09ca4e4cbb5573eb71a952f16e077d9)
…e's comments

Removes backlog codes, session and phase numbers, finding labels, plan citations, the names of
evidence scripts that live outside this repository and the names of private adopter projects from
the comments and docstrings of bin/migrate-layout and tools/test_migrate_layout.py. Comments and
docstrings only: each file's token stream, read without them, is equal before and after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit ea751caa6fd73dac4c42438c4aa4e0122b1eb04d)
…s' comments

Removes backlog codes, decision labels, coupling labels and plan citations that name documents
outside this repository from the comments and docstrings of starter-kit/methodology_trim.py and
tools/test_methodology_trim.py. Comments and docstrings only: each file's token stream, read
without them, is equal before and after. The trimmer's own "P1" check and every string it emits
are untouched.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…mments

Removes backlog codes, session and phase numbers, decision and option labels, learning
citations, commit hashes, plan citations that name documents outside this repository and the
names of private adopter projects from the comments and docstrings of
starter-kit/methodology_dashboard.py, its twin tools/methodology_dashboard.py and
tools/test_methodology_dashboard.py, and drops the version notes that described a lineage
this repository does not have. Comments and docstrings only: each file's token stream, read
without them, is equal before and after, and the two copies of the dashboard stay
byte-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 72e0c991be867be9d1ff8c155f71afbe99ae5241)
… a comment and a header

Each was true of an earlier tree or of upstream's and stopped being true here; none changes behaviour.

- .quality-gates.json, layout-literals: the reason said bin/check-handoff and bin/check-ledger are not
  scanned and have no layout reading. The scanner takes every file in bin/ except bin/_manifest.py and
  bin/tests.sh, and both checkers resolve their ledger through the embedded resolver. The reason now says
  what the scan covers.
- .quality-gates.json, layout-unit-tests: the reason said 74 tests are measured against a floor of 76;
  `python3 tools/test_layout_resolver.py` runs 76.
- methodology_dashboard.py (starter-kit/ and its identical tools/ twin): the comment above the stale-copy
  warning said the safe per-project remedy is one `cp`; the warning prints a `--sync` scoped to the
  project, so the comment says that.
- bin/migrate-layout: the header's exit list stopped at 3. An apply that commits and then finds its
  after-checks differ from its before-checks, or the tree dirty, returns 4 and keeps the commit.

Only the two reasons, one comment and the docstring change: the manifest's keys, thresholds and commands
are equal, the dashboard and the migration tool have the same syntax tree once the docstring is set
aside, and the two dashboard copies are still byte-identical. No version number moves.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit a62bfecf7812451cdbbd146e63c079a3a635efa3)
…ed with their class; dashboard-unit-tests 395 to 397

Upstream's TestCliRemedyProportionality (issue KJ5HST#67 / PR KJ5HST#73) has three tests. The series dropped all three
and left a note saying the `--sync [DIR]` design replaced the remedy they assert. That is true of one:
test_stale_warning_leads_with_the_project_scoped_remedy asserts a literal `cp ` in the stale-copy warning,
and this branch's warning prints a `--sync` scoped to the one project. The other two assert behaviour this
branch keeps, and pass on its code unchanged: a bare `--dry-run` exits 2 and writes neither dashboard.html
nor dashboard_history.jsonl (the existing Row 13 test asserts the same through a temp-copied script), and a
plain `--no-open` run writes dashboard.html, the presence control without which a scanner that refused
every invocation would still pass the first. For a copy kept at the project root this file had no such
positive assertion; its only one is for a copy under methodology/.

Restored as upstream wrote them (`git show f34769f:tools/test_methodology_dashboard.py`, the class header
through the second test, unchanged), with the class's setUp, tearDown and _project helper; the note now
names the one test not carried and why. The dashboard-unit-tests floor rises 395 to 397, a tightening.
No code path changes; the two tests ran green here before the commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit cfcc713b95788d6f7e1284656673a6fa8f49d3f1)
rmsharp and others added 3 commits October 29, 2026 11:08
…he layout scanner print

The text a program prints or a test asserts on, as opposed to a comment: the plan citations in
bin/migrate-layout's refusal and usage messages, the plan code in the ledger entry it writes into a
project (that entry is now free of a reference only this repository's maintainers can resolve), the
plan code in bin/check-layout-literals' explanation of a scanned file, and the finding labels in the
migration suite's assertion messages. No logic changes: the token stream of each Python file, with
its string literals and comments masked, is equal before and after.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 8ace51e8424548249f0ca7ee53164401d4c28881)
… its tests assert on

The risk text the dashboard prints for a half-migrated project no longer carries a backlog code, and
the assertion messages of tools/test_methodology_dashboard.py no longer cite session numbers, option
labels or plan sections. No logic changes: the token stream of each Python file, with its string
literals and comments masked, is equal before and after, and the two copies of the dashboard stay
byte-identical.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit ccd5620e37d08f47617b3f05871ceddbed5b66af)
…k's selftest labels and a gate's reason

The test titles and failure messages of bin/tests.sh, the selftest labels and the refusal text of
.githooks/pre-commit, and the "why" of one gate in .quality-gates.json no longer carry backlog codes,
probe labels or plan citations. The one selftest label that bin/tests.sh matches by substring is
changed in both places. No logic changes: each shell file still parses, and the gate manifest is equal
before and after with every "why" masked.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit 28f99a70e340a78bfdfb62b9847293388c1299bb)
rmsharp added a commit to rmsharp/methodology that referenced this pull request Oct 30, 2026
…ST/methodology from feat/methodology-directory (33 commits on upstream d50ce29; OPEN, MERGEABLE, CLEAN, 47 files, 0 comments); the read-back script, its output and the record; the draft's status line says OPENED

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Oct 30, 2026
…KJ5HST/methodology from rmsharp:feat/methodology-directory (33 commits on upstream d50ce29; OPEN, MERGEABLE, CLEAN, 0 comments); the fork's gates pass 24 of 24; HANDOFFS.md trimmed 4 to 3 and folded

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Oct 30, 2026
… of upstream/main plus one commit holding the candidate's tree, pr3b-adopters.py over the 12 adopters against it and against pr2b/candidate as a same-day control; CHANGELOG.md trimmed 127 to 64 records; nothing sent to KJ5HST/methodology

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
rmsharp added a commit to rmsharp/methodology that referenced this pull request Oct 30, 2026
…h of the 33 commits makes bin/sync refuse 71 files over the same 10 of 12 adopters, against 52 for a merge or a rebase (+19, four file versions); the fork's gates pass 24 of 24; CHANGELOG.md trimmed 127 to 64 records; nothing sent to KJ5HST/methodology

Co-Authored-By: Claude Sonnet 5.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.

1 participant