Files
msd-core/tests/trim-safety.test.cjs
Tom Boucher 628648d63a chore(#2931): cap emitted per-runtime bytes and single-source windsurf (#2984)
* fix(#2931): preserve protected regions and cap emitted per-runtime bytes

Route every runtime brand swap through applyClaudeCodeBrandSwap so
"Claude Code" survives verbatim inside <runtime_compatibility> regions
(#2284b). The fix existed only in bin/install.js's local copies; the
src/*.cts exports still used a naive replace, so binding install.js to
the single source -- as this phase does for the Windsurf family --
would have silently regressed those runtimes. A table-driven parity
guard now covers all nine brand-swapping converters.

De-duplicate the Windsurf converter family: delete the six local copies
in bin/install.js and bind the four exported ones by reference, guarded
by reference-identity assertions (the ADR-1508/#1675 pattern). The two
unexported helpers and an unused tool table go with them.

Replace the Windsurf 12,000-byte throw with description truncation,
matching the bound its sibling skill converter already applied. The
throw could only fire on an ~11.7 KB frontmatter description: the
largest emitted workflow is 311 bytes. Truncation makes the cap
unreachable by construction and leaves 12,000 in exactly one place,
eliminating the dual-surface duplication rather than testing for it.

Add the emitted-byte cap gate: buildEmittedSizes captures LF- and
<HOME>-normalized bytes from the walk buildParityManifest already
performs, and evaluateEmittedCaps asserts them against a per-runtime
cap table with dead-rule detection. buildParityManifest's return shape
is deliberately unchanged -- diffEmitted compares its values with
===, so making them objects would report all 8,529 emitted paths as
moved. A regression test pins the values as strings.

Add a deterministic trim-safety gate over composeWithinBudget's
omitted/shrunk/floored/isolatePrefix metadata, with an anti-vacuity
rule, replacing the model-graded eval gate the issue described.

* docs(#2931): correct ADR-1671 windsurf premise and trim-safety contract

* fix(#2931): bound the windsurf command name and single-source the brand swap

Review findings from the orthogonal passes, all fixed inline.

The claim that removing the 12,000-byte throw left total emission
"bounded by construction" was false. The #1615 regex constrains the
character class but not the length, and commandName is interpolated
three times into the emitted workflow: a 20,000-character name emitted
60,162 bytes silently. Add WINDSURF_COMMAND_NAME_MAX=128 as a separate,
clearly-labelled size control that THROWS -- commandName is the @-ref
path target, so truncating it would point the workflow at a file that
does not exist (DEFECT.WORKFLOW-DELEGATION-TARGET-NOT-INSTALLED). The
#1615 security regex is untouched and still runs first. 128 is generous:
the longest shipped name is gsd-plan-review-convergence at 27.

Harmonize convertClaudeCommandToWindsurfSkill onto the code-point-safe
truncation helper. It still used a UTF-16 slice(0,177) -- the exact
surrogate-splitting bug the helper was written to avoid, in the very
sibling the helper's comment cites as its model. Bounds are unchanged,
so output is byte-identical for every shipped command (descriptions max
out at 99 chars).

Export applyClaudeCodeBrandSwap and bind it in bin/install.js, deleting
the local copy. Adding it to the .cts left two unlinked implementations
of identical logic -- the drift class this change exists to remove.
Verified byte-identical across eight fixtures and five sequential calls
before merging, and guarded by a reference-identity assertion.

Convert three try/finally test bodies to t.after (CONTRIBUTING.md:344),
add fast-check property coverage for the trim-safety contract, and use
fc.pre instead of a bare return in a property callback.

* test(#2931): fix three test-authoring bugs the remote matrix caught

The remote runner returned 8 unique failures on 6f15cdeb8. All three
causes were in the test files, not the modules under test -- local
harnesses exercise the modules directly, so nothing executed the test
bodies until the matrix did.

`{ __proto__: [...] }` in an object literal sets the prototype instead
of an own key, so the JSON round-trip erased it and the cap table never
saw a reserved runtime key. The production rejection was already
correct; the test could not reach it. Use a computed key.

Two cap fixtures tripped orthogonal error paths rather than the paths
they name: one declared windsurf in the cap table but omitted it from
sizes (UNKNOWN_RUNTIME), the other left the sole windsurf pattern
matching nothing (a genuine dead rule). Both now include a compliant
artifact so the intended branch is what is asserted. The dead-rule and
unknown-runtime contracts are deliberate and unchanged.

`const { root } = makeSyntheticConfig({ ... `${root}` })` referenced
`root` from inside its own initializer -- a temporal dead zone error.
makeSyntheticConfig now optionally takes a (root) => files factory.

Also raise the npm pack --dry-run bound 60s -> 120s in the shipped-
scripts packaging test. That failure is NOT from this branch: the file
is byte-identical to next, a fresh tsc measures 1.98s there vs 2.14s
here, and the run recorded 60,637ms against a 60,000ms bound -- a
timeout under 28,948-test parallel contention, not a slowdown. Fixed
rather than deferred because a bound that tight is fragile regardless
of which branch trips it.

* chore(#2931): backfill changeset pr number to 2984

---------

Co-authored-by: sim <sim@local>
2026-08-01 16:00:14 -04:00

225 lines
8.0 KiB
JavaScript

'use strict';
/**
* trim-safety.test.cjs — the trim-safety contract gate over `ComposeMetadata`
* (issue #2931, epic #1671, Phase 4). Exercises
* `tests/helpers/trim-safety.cjs` per
* `.gsd/phase/chore-2931-emitted-byte-caps/50-test-matrix.md` section E.
*
* Assertion discipline: every check compares typed structured values
* (`REASON` enum members, ids) — never rendered prose.
*/
const test = require('node:test');
const assert = require('node:assert/strict');
const fc = require('./helpers/fast-check-setup.cjs');
const { REASON, evaluateTrimSafety } = require('./helpers/trim-safety.cjs');
/** A fully "nothing happened" ComposeMetadata, per src/context-composer.cts's
* ComposeMetadata shape — every field a real compose result always carries. */
function baseMetadata(overrides = {}) {
return {
budget: 1000,
effectiveBudget: 1000,
contentBudget: 1000,
underPressure: false,
omitted: [],
shrunk: [],
floored: [],
truncationPct: 0,
hardFailed: false,
hardFailReason: null,
isolatePrefix: '',
...overrides,
};
}
test('passesWhenNothingTrimmed', () => {
const r = evaluateTrimSafety({ metadata: baseMetadata(), loadBearingIds: ['a', 'b'] });
assert.deepEqual(r.findings, []);
assert.deepEqual(r.errors, []);
assert.ok(r.ok);
});
test('passesWhenOnlyNonLoadBearingDropped', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ omitted: ['c'] }),
loadBearingIds: ['a', 'b'],
});
assert.deepEqual(r.findings, []);
assert.ok(r.ok);
});
test('failsWhenLoadBearingFragmentOmitted', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ omitted: ['a'] }),
loadBearingIds: ['a', 'b'],
});
assert.equal(r.findings.length, 1);
assert.equal(r.findings[0].reason, REASON.LOAD_BEARING_OMITTED);
assert.equal(r.findings[0].id, 'a');
assert.ok(!r.ok);
});
test('failsWhenLoadBearingFragmentShrunk', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ shrunk: ['b'] }),
loadBearingIds: ['a', 'b'],
});
assert.equal(r.findings.length, 1);
assert.equal(r.findings[0].reason, REASON.LOAD_BEARING_SHRUNK);
assert.equal(r.findings[0].id, 'b');
assert.ok(!r.ok);
});
test('passesWhenIsolatePrefixByteIdentical', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ isolatePrefix: 'ABC' }),
loadBearingIds: ['a'],
expectedIsolatePrefix: 'ABC',
});
assert.deepEqual(r.findings, []);
assert.ok(r.ok);
});
test('failsWhenIsolatePrefixDriftsByOneByte', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ isolatePrefix: 'ABD' }),
loadBearingIds: ['a'],
expectedIsolatePrefix: 'ABC',
});
assert.equal(r.findings.length, 1);
assert.equal(r.findings[0].reason, REASON.ISOLATE_PREFIX_DRIFT);
assert.equal(r.findings[0].expected, 'ABC');
assert.equal(r.findings[0].actual, 'ABD');
assert.ok(!r.ok);
});
test('failsWhenIsolatePrefixDiffersOnlyByWhitespace', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ isolatePrefix: 'ABC ' }),
loadBearingIds: ['a'],
expectedIsolatePrefix: 'ABC',
});
assert.equal(r.findings.length, 1, 'byte-identical means byte-identical — trailing whitespace IS drift');
assert.equal(r.findings[0].reason, REASON.ISOLATE_PREFIX_DRIFT);
assert.ok(!r.ok);
});
test('failsOnMinimumSetHardFail', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ hardFailed: true, hardFailReason: 'minimum-set' }),
loadBearingIds: ['a'],
});
assert.equal(r.errors.length, 1);
assert.equal(r.errors[0].reason, REASON.MINIMUM_SET_HARD_FAIL);
assert.equal(r.errors[0].hardFailReason, 'minimum-set');
assert.ok(!r.ok, 'a hard-failed compose must never be reported as a silent empty pass');
});
test('failsWhenNoFragmentIsMarkedLoadBearing', () => {
for (const loadBearingIds of [[], undefined, null]) {
const r = evaluateTrimSafety({ metadata: baseMetadata(), loadBearingIds });
assert.equal(r.errors.length, 1, `${JSON.stringify(loadBearingIds)} must be rejected`);
assert.equal(r.errors[0].reason, REASON.NO_LOAD_BEARING_DECLARED);
assert.deepEqual(r.findings, [], 'an empty assertion set must compute no findings at all');
assert.ok(!r.ok, 'an empty assertion set proves nothing and must never read as a pass');
}
});
test('passesWhenLoadBearingFragmentWasFloored', () => {
const r = evaluateTrimSafety({
metadata: baseMetadata({ floored: ['a'] }),
loadBearingIds: ['a'],
});
assert.deepEqual(r.findings, [], 'the floor did its job — never a finding');
assert.ok(r.ok);
});
test('isIdempotentOverRepeatedEvaluation', () => {
const metadata = baseMetadata({ omitted: ['a'], shrunk: ['b'], floored: ['c'], isolatePrefix: 'XYZ' });
const loadBearingIds = ['a', 'b', 'c'];
const metadataBefore = JSON.stringify(metadata);
const idsBefore = JSON.stringify(loadBearingIds);
const r1 = evaluateTrimSafety({ metadata, loadBearingIds, expectedIsolatePrefix: 'XYZ' });
const r2 = evaluateTrimSafety({ metadata, loadBearingIds, expectedIsolatePrefix: 'XYZ' });
assert.deepEqual(r1, r2);
assert.equal(JSON.stringify(metadata), metadataBefore, 'metadata must not be mutated');
assert.equal(JSON.stringify(loadBearingIds), idsBefore, 'loadBearingIds must not be mutated');
});
// ─── property tests ───────────────────────────────────────────────────────
const idArb = fc.constantFrom('a', 'b', 'c', 'd', 'e');
const idSetArb = fc.uniqueArray(idArb, { maxLength: 5 });
const nonEmptyIdSetArb = fc.uniqueArray(idArb, { minLength: 1, maxLength: 5 });
const prefixArb = fc.string({ maxLength: 6 });
test('propertyOkIffNoLoadBearingIdOmittedOrShrunkAndPrefixMatchesAndNoHardFail', () => {
fc.assert(
fc.property(
nonEmptyIdSetArb,
idSetArb,
idSetArb,
idSetArb,
fc.boolean(),
prefixArb,
prefixArb,
(loadBearingIds, omitted, shrunk, floored, hardFailed, isolatePrefix, expectedIsolatePrefix) => {
const metadata = baseMetadata({ omitted, shrunk, floored, hardFailed, isolatePrefix });
const r = evaluateTrimSafety({ metadata, loadBearingIds, expectedIsolatePrefix });
const noneOmittedOrShrunk = loadBearingIds.every((id) => !omitted.includes(id) && !shrunk.includes(id));
const prefixMatches = isolatePrefix === expectedIsolatePrefix;
const expectedOk = noneOmittedOrShrunk && prefixMatches && hardFailed === false;
assert.equal(r.ok, expectedOk);
},
),
);
});
test('propertyIdInOnlyFlooredNeverProducesAFinding', () => {
fc.assert(
fc.property(nonEmptyIdSetArb, (loadBearingIds) => {
const flooredOnlyId = loadBearingIds[0];
const metadata = baseMetadata({ omitted: [], shrunk: [], floored: [flooredOnlyId] });
const r = evaluateTrimSafety({ metadata, loadBearingIds });
assert.ok(
!r.findings.some((f) => f.id === flooredOnlyId),
`${flooredOnlyId} appears only in floored and must never produce a finding`,
);
}),
);
});
test('propertyEvaluationIsIdempotentAndNeverMutatesInputs', () => {
fc.assert(
fc.property(
nonEmptyIdSetArb,
idSetArb,
idSetArb,
idSetArb,
fc.boolean(),
prefixArb,
prefixArb,
(loadBearingIds, omitted, shrunk, floored, hardFailed, isolatePrefix, expectedIsolatePrefix) => {
const metadata = baseMetadata({ omitted, shrunk, floored, hardFailed, isolatePrefix });
const metadataBefore = JSON.stringify(metadata);
const idsBefore = JSON.stringify(loadBearingIds);
const r1 = evaluateTrimSafety({ metadata, loadBearingIds, expectedIsolatePrefix });
const r2 = evaluateTrimSafety({ metadata, loadBearingIds, expectedIsolatePrefix });
assert.deepEqual(r1, r2);
assert.equal(JSON.stringify(metadata), metadataBefore, 'metadata must not be mutated');
assert.equal(JSON.stringify(loadBearingIds), idsBefore, 'loadBearingIds must not be mutated');
},
),
);
});