Split out of #7493. The pin is fixed; the reason nobody noticed for weeks is not.
The gap
.github/workflows/test.yml's e2e-scoped job (via scripts/ci_e2e_scope.py) runs the integration suites a diff names:
changed crates/<pkg>/tests/<suite>.rs -> cargo test -p <pkg> --test <suite>
ci_e2e_scope.py deliberately refuses the source→suite direction, and says why: there is no coverage data to map it with, and a crate-level map (perry-codegen -> all 163 perry suites) is exactly the full run the scoping exists to avoid. That reasoning is right in general and wrong for one narrow case.
#7370 changed crates/perry-codegen/src/. It named no suite. shadow_slot_hygiene went 0/12 and nothing was red until someone ran the nightly tier by hand. The per-PR cargo-test gate is --lib --bins, so it saw none of it.
Why this particular set is the exception
The six root-lowering suites are not like the 163 perry suites the general rule is protecting against. They are in-process compiles of hand-built HIR with emit_ir_only: true — no perry compile subprocess, no link, no runtime. Measured (arm64 macOS, debug, --test-threads=1):
| suite |
tests |
wall |
shadow_slot_hygiene |
12 |
0.17 s |
scalar_replaced_slot_roots |
11 |
0.18 s |
temp_root_argument_temporaries |
7 |
0.08 s |
temp_root_operand_temporaries |
19 |
0.39 s |
native_proof_buffer_views |
32 |
0.50 s |
native_proof_regressions |
255 |
5.13 s |
~6.5 s of test time for all six. The cost is the build, which e2e-scoped already pays whenever any perry-codegen suite is in scope, on a warmed sccache.
Why this is NOT being done in #7493
A new gate has never been green. Fifteen tests across these suites are red right now for three causes #7493 does not own — #7494, #7503, #7504 (plus #7505 and #7506). Adding crates/perry-codegen/src/** -> these six suites today makes e2e-scoped red on the majority of perry-codegen PRs.
e2e-scoped is not in branch protection's required contexts, so that would not block merges — which is precisely what makes it dangerous rather than safe. A job that is red on most PRs and cannot block anything is CLAUDE.md hazard 2 with extra steps: reviewers learn to ignore it, and it can never be promoted, because promoting it would then block everything. Wiring it up before the suites are green would spend the one chance to make this signal mean something.
#7493 does add the one un-rot mechanism that can be green today:
codegen::testing_feature_gate_tests::host_target_lowering_default_is_native_roots, a unit test in src/ — so inside the REQUIRED cargo-test job — that fails the moment the root-lowering default flips again, naming the suites that then need re-pinning. That catches the specific #7370 shape at merge time. It does not catch a codegen change that regresses these suites for any other reason, which is what this issue is for.
What to build
- Add an explicit
SOURCE_SUITE_MAP to scripts/ci_e2e_scope.py:
SOURCE_SUITE_MAP = {
"crates/perry-codegen/src/": [
("perry-codegen", "shadow_slot_hygiene"),
("perry-codegen", "scalar_replaced_slot_roots"),
("perry-codegen", "temp_root_argument_temporaries"),
("perry-codegen", "temp_root_operand_temporaries"),
("perry-codegen", "native_proof_regressions"),
("perry-codegen", "native_proof_buffer_views"),
],
}
Hand-maintained and narrow by design — the general refusal stands; this is one named exception with a stated cost. Six entries fits comfortably under DEFAULT_CAP = 12.
- Extend
--self-test to cover it: a crates/perry-codegen/src/codegen/helpers.rs change must select exactly these six, and a change to any other crate's src/ must still select nothing.
- Cross-check the list against
tests/ on disk, so a renamed or deleted suite fails the scope step instead of silently dropping out — the same "an entry that matches nothing FAILS" rule scripts/gc_root_dominance_allowlist.json uses.
- Run it once on a real PR, confirm green, and only then consider promotion.
Blocked on
#7494, #7503, #7504 green (and #7505, #7506 resolved or the tests they name re-pointed). Until then this mapping cannot land without normalising a red job.
Split out of #7493. The pin is fixed; the reason nobody noticed for weeks is not.
The gap
.github/workflows/test.yml'se2e-scopedjob (viascripts/ci_e2e_scope.py) runs the integration suites a diff names:ci_e2e_scope.pydeliberately refuses the source→suite direction, and says why: there is no coverage data to map it with, and a crate-level map (perry-codegen-> all 163perrysuites) is exactly the full run the scoping exists to avoid. That reasoning is right in general and wrong for one narrow case.#7370 changed
crates/perry-codegen/src/. It named no suite.shadow_slot_hygienewent 0/12 and nothing was red until someone ran the nightly tier by hand. The per-PRcargo-testgate is--lib --bins, so it saw none of it.Why this particular set is the exception
The six root-lowering suites are not like the 163
perrysuites the general rule is protecting against. They are in-process compiles of hand-built HIR withemit_ir_only: true— noperry compilesubprocess, no link, no runtime. Measured (arm64 macOS, debug,--test-threads=1):shadow_slot_hygienescalar_replaced_slot_rootstemp_root_argument_temporariestemp_root_operand_temporariesnative_proof_buffer_viewsnative_proof_regressions~6.5 s of test time for all six. The cost is the build, which
e2e-scopedalready pays whenever any perry-codegen suite is in scope, on a warmed sccache.Why this is NOT being done in #7493
A new gate has never been green. Fifteen tests across these suites are red right now for three causes #7493 does not own — #7494, #7503, #7504 (plus #7505 and #7506). Adding
crates/perry-codegen/src/** -> these six suitestoday makese2e-scopedred on the majority of perry-codegen PRs.e2e-scopedis not in branch protection's required contexts, so that would not block merges — which is precisely what makes it dangerous rather than safe. A job that is red on most PRs and cannot block anything is CLAUDE.md hazard 2 with extra steps: reviewers learn to ignore it, and it can never be promoted, because promoting it would then block everything. Wiring it up before the suites are green would spend the one chance to make this signal mean something.#7493 does add the one un-rot mechanism that can be green today:
codegen::testing_feature_gate_tests::host_target_lowering_default_is_native_roots, a unit test insrc/— so inside the REQUIREDcargo-testjob — that fails the moment the root-lowering default flips again, naming the suites that then need re-pinning. That catches the specific #7370 shape at merge time. It does not catch a codegen change that regresses these suites for any other reason, which is what this issue is for.What to build
SOURCE_SUITE_MAPtoscripts/ci_e2e_scope.py:DEFAULT_CAP = 12.--self-testto cover it: acrates/perry-codegen/src/codegen/helpers.rschange must select exactly these six, and a change to any other crate'ssrc/must still select nothing.tests/on disk, so a renamed or deleted suite fails the scope step instead of silently dropping out — the same "an entry that matches nothing FAILS" rulescripts/gc_root_dominance_allowlist.jsonuses.Blocked on
#7494, #7503, #7504 green (and #7505, #7506 resolved or the tests they name re-pointed). Until then this mapping cannot land without normalising a red job.