Fifteen non-allowlisted files are within 10 lines of the 2,000-line cap, three of them at exactly 2,000 with zero headroom. This has stopped being a run of bad luck and become a structural condition: the next unrelated change to any of them fails check_file_size.sh for a reason that has nothing to do with what that change is doing, and the failure lands on whoever happens to be passing.
Measured against origin/main (053b9ccac4, v0.5.1604), excluding the 30 allowlisted paths:
| lines |
headroom |
file |
| 2000 |
0 |
crates/perry-runtime/src/gc/tests/copying.rs |
| 2000 |
0 |
crates/perry-hir/src/lower/stmt_loops.rs |
| 2000 |
0 |
crates/perry-codegen/src/stmt/let_stmt.rs |
| 1998 |
2 |
crates/perry/src/commands/publish/mod.rs |
| 1998 |
2 |
crates/perry-runtime/src/json_tape.rs |
| 1997 |
3 |
crates/perry-runtime/src/error.rs |
| 1997 |
3 |
crates/perry-codegen/src/dialect/mod.rs |
| 1995 |
5 |
crates/perry-runtime/src/object/descriptors.rs |
| 1994 |
6 |
crates/perry-runtime/src/object/tests.rs |
| 1994 |
6 |
crates/perry-hir/src/lower/const_fold_fn.rs |
| 1993 |
7 |
crates/perry-ext-http/src/agent.rs |
| 1993 |
7 |
crates/perry-codegen/src/rooting/mod.rs |
| 1992 |
8 |
crates/perry-runtime/src/object/native_module/module_keys.rs |
| 1991 |
9 |
crates/perry/src/commands/compile/cjs_wrap/tests.rs |
| 1991 |
9 |
crates/perry-runtime/src/webassembly.rs |
★ Read this before attempting any split: a pure relocation is not a no-op to the ratchets
Several gates key their baselines per path, so moving code between files — changing nothing semantically — reads as new debt at the destination and an unexplained drop at the source:
scripts/raw_handle_debt_files.txt — per-path, with per-module ceilings.
scripts/unrooted_local_shape_baseline.json — per-file counts.
scripts/string_payload_access_baseline.txt and scripts/gc_runtime_root_holders.json — check before moving anything they name.
PR #10721 added a relocation annotation to the raw-handle ledger for exactly this case. Use it rather than rediscovering the need, and check the other baselines for an equivalent before hand-editing them.
Also from prior cap-split experience here: mkdir the new module directory before moving files, update the mod registration lists in the same commit, and expect the split to break things beyond compiling.
Why this is worth acting on rather than absorbing
The cost lands on the wrong change. A PR that adds one line of test coverage to object/tests.rs (6 left) now owes a file split, as a separate pure-relocation commit, before it can land. That split is unrelated to its actual subject, has to be reviewed on its own, and — per the known aftermath of cap splits in this repo — breaks several things beyond compiling (module registration lists, mod declarations, ratchet baselines keyed by path).
It is already happening, with a concrete cost attached. PR #10749 (require.main) had to trim comments out of two files purely to stay under the cap, and still lands collect_modules.rs at exactly 2000 (1988 → 2000), codegen/entry.rs at 1997, and cjs_wrap/tests.rs at 1993. So once train 226 lands there will be four zero-headroom files — and collect_modules.rs is one that any CJS or module-collection work touches, meaning the next such change is blocked on a split before it can begin. That is the cost of absorbing this rather than relieving it, stated as a prediction rather than a worry.
Three of the zero-headroom files have been at exactly 2000 all day, across six merge trains, which means nothing is naturally relieving the pressure.
Suggested shape
A batch of pure-relocation splits for the zero-headroom and ≤3-headroom files, landed as their own PR(s) with no behavioural change, so the relief is reviewed once as relocation rather than repeatedly as collateral in unrelated PRs. Worth doing topically — stmt_loops.rs, let_stmt.rs and copying.rs are all natural split candidates by statement kind / test group.
Two things to get right, from prior experience with cap splits here:
mkdir the new module directory before moving files, and update the mod registration lists in the same commit.
- Check whether any ratchet baseline keys on the moved paths (
unrooted_local_shape_baseline.json, string_payload_access_baseline.txt, the raw-handle ledger, gc_runtime_root_holders.json) — a relocation that silently changes a keyed path reads as a new finding.
An alternative worth considering explicitly and rejecting or accepting on the record: allowlisting some of these instead. The allowlist requires a one-line rationale per entry and currently holds 30 files, each for a real structural reason (a lone pub enum, a single 5,650-line function, vendored snapshots). "It happens to be near the limit" is not that kind of reason, so splitting is probably right — but if a file genuinely cannot be split, the allowlist is the honest place for it rather than a permanent trap.
Fifteen non-allowlisted files are within 10 lines of the 2,000-line cap, three of them at exactly 2,000 with zero headroom. This has stopped being a run of bad luck and become a structural condition: the next unrelated change to any of them fails
check_file_size.shfor a reason that has nothing to do with what that change is doing, and the failure lands on whoever happens to be passing.Measured against
origin/main(053b9ccac4, v0.5.1604), excluding the 30 allowlisted paths:crates/perry-runtime/src/gc/tests/copying.rscrates/perry-hir/src/lower/stmt_loops.rscrates/perry-codegen/src/stmt/let_stmt.rscrates/perry/src/commands/publish/mod.rscrates/perry-runtime/src/json_tape.rscrates/perry-runtime/src/error.rscrates/perry-codegen/src/dialect/mod.rscrates/perry-runtime/src/object/descriptors.rscrates/perry-runtime/src/object/tests.rscrates/perry-hir/src/lower/const_fold_fn.rscrates/perry-ext-http/src/agent.rscrates/perry-codegen/src/rooting/mod.rscrates/perry-runtime/src/object/native_module/module_keys.rscrates/perry/src/commands/compile/cjs_wrap/tests.rscrates/perry-runtime/src/webassembly.rs★ Read this before attempting any split: a pure relocation is not a no-op to the ratchets
Several gates key their baselines per path, so moving code between files — changing nothing semantically — reads as new debt at the destination and an unexplained drop at the source:
scripts/raw_handle_debt_files.txt— per-path, with per-module ceilings.scripts/unrooted_local_shape_baseline.json— per-file counts.scripts/string_payload_access_baseline.txtandscripts/gc_runtime_root_holders.json— check before moving anything they name.PR #10721 added a relocation annotation to the raw-handle ledger for exactly this case. Use it rather than rediscovering the need, and check the other baselines for an equivalent before hand-editing them.
Also from prior cap-split experience here:
mkdirthe new module directory before moving files, update themodregistration lists in the same commit, and expect the split to break things beyond compiling.Why this is worth acting on rather than absorbing
The cost lands on the wrong change. A PR that adds one line of test coverage to
object/tests.rs(6 left) now owes a file split, as a separate pure-relocation commit, before it can land. That split is unrelated to its actual subject, has to be reviewed on its own, and — per the known aftermath of cap splits in this repo — breaks several things beyond compiling (module registration lists,moddeclarations, ratchet baselines keyed by path).It is already happening, with a concrete cost attached. PR #10749 (
require.main) had to trim comments out of two files purely to stay under the cap, and still landscollect_modules.rsat exactly 2000 (1988 → 2000),codegen/entry.rsat 1997, andcjs_wrap/tests.rsat 1993. So once train 226 lands there will be four zero-headroom files — andcollect_modules.rsis one that any CJS or module-collection work touches, meaning the next such change is blocked on a split before it can begin. That is the cost of absorbing this rather than relieving it, stated as a prediction rather than a worry.Three of the zero-headroom files have been at exactly 2000 all day, across six merge trains, which means nothing is naturally relieving the pressure.
Suggested shape
A batch of pure-relocation splits for the zero-headroom and ≤3-headroom files, landed as their own PR(s) with no behavioural change, so the relief is reviewed once as relocation rather than repeatedly as collateral in unrelated PRs. Worth doing topically —
stmt_loops.rs,let_stmt.rsandcopying.rsare all natural split candidates by statement kind / test group.Two things to get right, from prior experience with cap splits here:
mkdirthe new module directory before moving files, and update themodregistration lists in the same commit.unrooted_local_shape_baseline.json,string_payload_access_baseline.txt, the raw-handle ledger,gc_runtime_root_holders.json) — a relocation that silently changes a keyed path reads as a new finding.An alternative worth considering explicitly and rejecting or accepting on the record: allowlisting some of these instead. The allowlist requires a one-line rationale per entry and currently holds 30 files, each for a real structural reason (a lone
pub enum, a single 5,650-line function, vendored snapshots). "It happens to be near the limit" is not that kind of reason, so splitting is probably right — but if a file genuinely cannot be split, the allowlist is the honest place for it rather than a permanent trap.