process: the bundle CLI judges the beta ceiling before the budget (#699)

Validate on 3dd032d7 (run 36480911145): the mutant
initial-view-ceiling-unplugged survived. With the band over the ceiling,
ceiling + band (303 000) lies above the absolute INITIAL_VIEW_GZIP_BUDGET
(301 066), so every value the CLI test could feed went red on the budget
first and the ceiling check became unobservable.

- bundle-budget.mjs CLI: the initial View ceiling is judged before
  assertBundleBudget, so a growth over the band names the ratchet that
  caught it; the budget still stops anything the band lets through.
- The CLI test feeds ceiling + band + 1 and expects the band message.
- The mutant's anchor follows the moved lines.

Issue: #699
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
Claude
2026-09-28 22:39:36 +00:00
committed by claude[bot]
parent c68d92f674
commit 2369c50607
3 changed files with 12 additions and 6 deletions
+6 -2
View File
@@ -812,11 +812,15 @@ export function assertBundleBudget(
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
try {
const manifest = JSON.parse(readFileSync(resolve('dist/houseplan-assets.json'), 'utf8'));
// #699: потолок беты с полосой судится до абсолютного бюджета. С полосой
// над потолком граница `ceiling + band` может лежать выше бюджета, и тогда
// рост краснел бы только бюджетом — а отказ обязан называть храповик,
// который его поймал, и проверка потолка — оставаться исполняемой.
const ceiling = initialViewCeilingViolation(manifest.initialViewGzipBytes);
if (ceiling) throw new Error(ceiling.text);
const result = assertBundleBudget(manifest);
assertSupportBundleOwnership(manifest);
assertNamespaceLocaleOwnership(manifest);
const ceiling = initialViewCeilingViolation(result.initialViewGzipBytes);
if (ceiling) throw new Error(ceiling.text);
const headroom = INITIAL_VIEW_GZIP_BUDGET - result.initialViewGzipBytes;
const lines = [
`initial View: ${result.initialViewGzipBytes} B gzip`
+1 -1
View File
@@ -9063,7 +9063,7 @@ const MUTANT_DEFINITIONS = [
+ 'release where it would have fired, and the growth of #438 went unnoticed for a beta)',
patches: [{
file: 'scripts/bundle-budget.mjs',
find: ' const ceiling = initialViewCeilingViolation(result.initialViewGzipBytes);\n'
find: ' const ceiling = initialViewCeilingViolation(manifest.initialViewGzipBytes);\n'
+ ' if (ceiling) throw new Error(ceiling.text);\n',
replace: '',
}],
+5 -3
View File
@@ -1029,9 +1029,11 @@ test('#438 CLI действительно применяет потолок, а
assert.match(inside.output, new RegExp(`lazy onboarding: ${LAZY_ONBOARDING_GZIP_CEILING - 1_000} B gzip`
+ ` \\(потолок ${LAZY_ONBOARDING_GZIP_CEILING} B \\+${LAZY_GRAPH_CEILING_BAND}\\)`));
// #699: полоса — над потолком беты; ниже потолка задача не краснеет.
const withinBand = runBudgetCli(INITIAL_VIEW_GZIP_CEILING + 1);
assert.equal(withinBand.status, INITIAL_VIEW_GZIP_CEILING + 1 > INITIAL_VIEW_GZIP_BUDGET ? 1 : 0, withinBand.output);
// #699: полоса — над потолком беты; выше неё CLI называет храповик, ниже
// потолка задача не краснеет.
const grew = runBudgetCli(INITIAL_VIEW_GZIP_CEILING + INITIAL_VIEW_CEILING_BAND + 1);
assert.equal(grew.status, 1, grew.output);
assert.match(grew.output, /выше потолка беты .* больше полосы/);
const shrank = runBudgetCli(INITIAL_VIEW_GZIP_CEILING - INITIAL_VIEW_CEILING_BAND - 1);
assert.equal(shrank.status, 0, shrank.output);