From 2369c50607d87288e818dc678b12cdf370e55a30 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 23:59:06 +0300 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd --- scripts/bundle-budget.mjs | 8 ++++++-- scripts/mutation-registry.mjs | 2 +- test/bundle-assets.test.mjs | 8 +++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/scripts/bundle-budget.mjs b/scripts/bundle-budget.mjs index 41eeb91d..ae1c8821 100644 --- a/scripts/bundle-budget.mjs +++ b/scripts/bundle-budget.mjs @@ -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` diff --git a/scripts/mutation-registry.mjs b/scripts/mutation-registry.mjs index 479ecb9c..016c90e6 100644 --- a/scripts/mutation-registry.mjs +++ b/scripts/mutation-registry.mjs @@ -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: '', }], diff --git a/test/bundle-assets.test.mjs b/test/bundle-assets.test.mjs index 5602c87a..3da097e0 100644 --- a/test/bundle-assets.test.mjs +++ b/test/bundle-assets.test.mjs @@ -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);