You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decide how the eager-closure gate (scripts/__tests__/eager-closure-budgets.ts) should treat a module split, so that extracting a large module inside a gated closure stops being impossible without weakening the property the gate protects.
Current behavior
Every entry that exists at the merge-base is held to NO GROWTH of its eager import closure, counted in modules. There is no approval path for growth of an existing entry (APPROVED_OVER_CEILING covers first-introduced entries only). A module that is in a gated closure therefore cannot be split: one module becoming N modules is +N−1 for every entry that evaluates it.
Measured on PR #2423 at b21efb0: extracting packages/platform-apple/src/runner/runner-cache-metadata.ts (621 lines) into runner-phase-budget.ts + runner-toolchain-probe.ts grows seven entries by two each: app-lifecycle-facade 120→122, app-resolution-facade 61→63, doctor-facade 101→103, perf-facade 60→62, physical-device-facade 47→49, runner-operations-facade 100→102, runner/index.ts 13→15. The review on #2423 asked for exactly that extraction for ownership clarity, and it had to be deferred.
What the gate protects
The ADR-0019 loading shape: a façade must not evaluate implementation it does not need at import time. The module count is a proxy for eager work. A split does not add eager work when the new modules together evaluate what the old one did, but it does add modules, so the proxy reads it as growth.
Design question
Choose a rule that admits healthy extraction without admitting new eager work. Candidates, none proven:
Count something closer to eager work than module count: total source bytes, or statements at module top level, of the closure. A pure split keeps it flat; a new static edge to real implementation raises it. Costs: a heavier walker; renames and formatting churn move the number.
Recognize a split structurally: the new modules are all new at the head, and each is imported only by modules that were in the old module's importer set at the merge-base. As the reviewer of fix(ios): budget cold toolchain probes for the first-exec signature stall #2423 noted, this does not by itself prove no new eager work (a "new" module can carry a new heavy edge).
An explicit, reviewed approval row for growth of an existing entry (APPROVED_GROWTH), naming the issue, the reason, and the expected delta, retired automatically once the merge-base carries the new shape. Same mechanism as the existing ceiling rows; costs a hand-edited row per split.
Combine 2 and 1: accept a structural split only when the closure's byte or statement total does not grow.
Deliverable
A short design note choosing one, with the walker change and the test that plants (a) a pure split and (b) a split that smuggles a new heavy edge, showing the first passes and the second fails. Then re-run the #2423 extraction as the first consumer.
Non-goals
Loosening no-growth for anything other than splits; changing category ceilings.
Purpose
Decide how the eager-closure gate (
scripts/__tests__/eager-closure-budgets.ts) should treat a module split, so that extracting a large module inside a gated closure stops being impossible without weakening the property the gate protects.Current behavior
Every entry that exists at the merge-base is held to NO GROWTH of its eager import closure, counted in modules. There is no approval path for growth of an existing entry (
APPROVED_OVER_CEILINGcovers first-introduced entries only). A module that is in a gated closure therefore cannot be split: one module becoming N modules is +N−1 for every entry that evaluates it.Measured on PR #2423 at
b21efb0: extractingpackages/platform-apple/src/runner/runner-cache-metadata.ts(621 lines) intorunner-phase-budget.ts+runner-toolchain-probe.tsgrows seven entries by two each: app-lifecycle-facade 120→122, app-resolution-facade 61→63, doctor-facade 101→103, perf-facade 60→62, physical-device-facade 47→49, runner-operations-facade 100→102,runner/index.ts13→15. The review on #2423 asked for exactly that extraction for ownership clarity, and it had to be deferred.What the gate protects
The ADR-0019 loading shape: a façade must not evaluate implementation it does not need at import time. The module count is a proxy for eager work. A split does not add eager work when the new modules together evaluate what the old one did, but it does add modules, so the proxy reads it as growth.
Design question
Choose a rule that admits healthy extraction without admitting new eager work. Candidates, none proven:
APPROVED_GROWTH), naming the issue, the reason, and the expected delta, retired automatically once the merge-base carries the new shape. Same mechanism as the existing ceiling rows; costs a hand-edited row per split.Deliverable
A short design note choosing one, with the walker change and the test that plants (a) a pure split and (b) a split that smuggles a new heavy edge, showing the first passes and the second fails. Then re-run the #2423 extraction as the first consumer.
Non-goals
Loosening no-growth for anything other than splits; changing category ceilings.