harness-everything 0.36.3 → 0.36.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +10 -0
  4. package/ci/fixtures/doc-obligations/read-boundary/boundary-controls.json +211 -0
  5. package/ci/fixtures/doc-obligations/read-boundary/boundary-policy.json +325 -0
  6. package/ci/fixtures/doc-obligations/read-boundary/cases.json +14058 -0
  7. package/ci/fixtures/doc-obligations/read-boundary/expected.json +1 -0
  8. package/ci/fixtures/doc-obligations/read-boundary/identity-cases.json +119 -0
  9. package/ci/fixtures/doc-obligations/read-boundary/identity-expected.json +1 -0
  10. package/ci/fixtures/doc-obligations/read-boundary/scope-cases.json +208 -0
  11. package/ci/fixtures/doc-obligations/read-boundary/scope-expected.json +1 -0
  12. package/ci/fixtures/doc-obligations/reconciliation-prep/cases.json +2751 -0
  13. package/ci/fixtures/doc-obligations/reconciliation-prep/flood-entrypoint.js +5 -0
  14. package/ci/fixtures/doc-obligations/reconciliation-prep/hang-entrypoint.js +5 -0
  15. package/ci/fixtures/doc-obligations/reconciliation-prep/pending-red.json +648 -0
  16. package/ci/fixtures/doc-obligations/reconciliation-prep/provider-contract.json +100 -0
  17. package/ci/fixtures/doc-obligations/reconciliation-prep/trust-contract.json +188 -0
  18. package/ci/lib/doc-evidence-boundary-check.js +1240 -0
  19. package/ci/lib/doc-evidence-fixtures.js +459 -0
  20. package/ci/lib/doc-evidence-trace.js +171 -0
  21. package/ci/lib/doc-reconciliation-prep-fixtures.js +502 -0
  22. package/ci/lib/snapshot-stdin.js +27 -0
  23. package/ci/mechanism-325-3b-preparation.test.js +382 -0
  24. package/ci/mechanism-341-boundary-enforcement.test.js +660 -0
  25. package/ci/mechanism-341-capture-module.test.js +357 -0
  26. package/ci/mechanism-341-mutation-runner.test.js +413 -0
  27. package/ci/mechanism-341-read-boundary.test.js +388 -0
  28. package/ci/mechanism-341-snapshot-stdin.test.js +40 -0
  29. package/ci/mutation-check.js +805 -45
  30. package/ci/mutation-loader.js +544 -57
  31. package/ci/prep/doc-reconciliation-red.js +407 -0
  32. package/ci/stress-341-boundary-control.js +85 -0
  33. package/docs/doc-evidence-baseline-binding.md +105 -19
  34. package/docs/doc-evidence-boundary.md +135 -0
  35. package/docs/doc-workflow-reconciliation.md +224 -0
  36. package/docs/document-lifecycle.md +8 -1
  37. package/harness-everything/SKILL.md +1 -1
  38. package/harness-everything/scripts/doc-evidence-capture.js +331 -0
  39. package/harness-everything/scripts/doc-evidence.js +72 -223
  40. package/opencode-plugin/plugin.json +1 -1
  41. package/package.json +5 -3
  42. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  43. package/plugins/harness-everything/plugin.json +1 -1
  44. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  45. package/plugins/harness-everything/skills/harness-everything/scripts/doc-evidence-capture.js +331 -0
  46. package/plugins/harness-everything/skills/harness-everything/scripts/doc-evidence.js +72 -223
  47. package/sbom.cdx.json +43 -7
@@ -0,0 +1,413 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { CHECKS, LEGACY_ASSERTIONS, addLoaderPreload, isPrivateContract, runChecks, stripLoaderPreload } = require('./mutation-check');
8
+ const { MUTATIONS, prepareMutation } = require('./mutation-loader');
9
+
10
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-341-mutation-runner-'));
11
+
12
+ function write(relative, contents) {
13
+ const file = path.join(root, relative);
14
+ fs.mkdirSync(path.dirname(file), { recursive: true });
15
+ fs.writeFileSync(file, contents, 'utf8');
16
+ return file;
17
+ }
18
+
19
+ function checkTuple({ mutantId, target = 'synthetic-target.js', mode = 'assert', caseId = 'RB00', assertionId = 'RB00.synthetic.target-is-true', timeoutMs = 10000 } = {}) {
20
+ const [result] = runChecks({
21
+ root,
22
+ allowTestMutations: true,
23
+ timeoutMs,
24
+ testEnv: {
25
+ HARNESS_SYNTHETIC_MODE: mode,
26
+ HARNESS_SYNTHETIC_TARGET: path.join(root, 'synthetic-target.js'),
27
+ },
28
+ checks: [{
29
+ label: `${mutantId || 'control'} / ${mode}`,
30
+ target,
31
+ mutantId: mutantId || 'test-kill',
32
+ test: 'synthetic-test.js',
33
+ ...(caseId ? { caseId } : {}),
34
+ assertionId,
35
+ }],
36
+ });
37
+ assert.ok(result, 'runner returns one report per selected tuple');
38
+ return result;
39
+ }
40
+
41
+ function checkLegacyTuple({ test, caseId, assertionId, signature }) {
42
+ const [result] = runChecks({
43
+ root,
44
+ allowTestMutations: true,
45
+ timeoutMs: 10000,
46
+ testEnv: { HARNESS_SYNTHETIC_TARGET: path.join(root, 'synthetic-target.js') },
47
+ checks: [{
48
+ label: assertionId,
49
+ target: 'synthetic-target.js',
50
+ mutantId: 'test-kill',
51
+ test,
52
+ caseId,
53
+ assertionId,
54
+ }],
55
+ legacyAssertions: { [assertionId]: signature },
56
+ });
57
+ return result;
58
+ }
59
+
60
+ try {
61
+ const targetPath = write('synthetic-target.js', 'module.exports = true;\n');
62
+ write('synthetic-other.js', 'module.exports = true;\n');
63
+ write('ci/test-helper.js', [
64
+ "'use strict';",
65
+ 'module.exports.check = function check(name, condition) { if (!condition) process.exitCode = 1; };',
66
+ '',
67
+ ].join('\n'));
68
+ write('synthetic-test.js', String.raw`
69
+ const assert = require('assert');
70
+ const fs = require('fs');
71
+ const selectedCase = process.env.HARNESS_CASE_ID || 'RB00';
72
+ const selectedAssertion = process.env.HARNESS_ASSERTION_ID || 'RB00.synthetic.target-is-true';
73
+ const eventFile = process.env.HARNESS_ASSERTION_EVENT_FILE;
74
+ function emit(event, caseId = selectedCase, assertionId = selectedAssertion) {
75
+ const record = { schemaVersion: 1, event, caseId, assertionId };
76
+ if (event === 'assertion-failure') { record.errorCode = 'ERR_ASSERTION'; record.message = 'synthetic control assertion failed'; }
77
+ fs.appendFileSync(eventFile, JSON.stringify(record) + '\n');
78
+ }
79
+ const mode = process.env.HARNESS_SYNTHETIC_MODE;
80
+ if (mode === 'control-unscoped-crash') {
81
+ emit('assertion-pass');
82
+ throw new Error('synthetic unscoped control crash');
83
+ } else if (mode === 'control-failure') {
84
+ emit('assertion-failure');
85
+ process.exitCode = 1;
86
+ } else if ((mode === 'generic-failure' || mode === 'parity-only-failure') && process.env.HARNESS_MUTATION) {
87
+ require(process.env.HARNESS_SYNTHETIC_TARGET);
88
+ console.error(mode === 'generic-failure' ? '❌ synthetic suite failed' : 'FAIL source/package parity');
89
+ process.exitCode = 1;
90
+ } else if (mode === 'unrelated-assertion' && process.env.HARNESS_MUTATION) {
91
+ require(process.env.HARNESS_SYNTHETIC_TARGET);
92
+ emit('assertion-failure', selectedCase, selectedAssertion + '.different');
93
+ process.exitCode = 1;
94
+ } else if (mode === 'selected-and-unrelated' && process.env.HARNESS_MUTATION) {
95
+ require(process.env.HARNESS_SYNTHETIC_TARGET);
96
+ emit('assertion-failure');
97
+ emit('assertion-failure', selectedCase, selectedAssertion + '.different');
98
+ process.exitCode = 1;
99
+ } else if (mode === 'selected-then-crash' && process.env.HARNESS_MUTATION) {
100
+ require(process.env.HARNESS_SYNTHETIC_TARGET);
101
+ emit('assertion-failure');
102
+ throw new Error('synthetic infrastructure crash after assertion event');
103
+ } else if (mode === 'does-not-load-target' && process.env.HARNESS_MUTATION) {
104
+ emit('assertion-pass');
105
+ } else if (mode === 'timeout' && process.env.HARNESS_MUTATION) {
106
+ require(process.env.HARNESS_SYNTHETIC_TARGET);
107
+ setInterval(() => {}, 1000);
108
+ } else if (mode === 'nested-process') {
109
+ const { spawnSync } = require('child_process');
110
+ const target = process.env.HARNESS_SYNTHETIC_TARGET;
111
+ const child = spawnSync(process.execPath, ['-e', 'process.stdout.write(String(require(' + JSON.stringify(target) + ')))'], { encoding: 'utf8' });
112
+ if (child.error || child.signal || child.status !== 0) throw new Error('nested target process failed before its assertion');
113
+ try {
114
+ assert.strictEqual(child.stdout, 'true');
115
+ emit('assertion-pass');
116
+ } catch (error) {
117
+ if (error && error.code === 'ERR_ASSERTION') {
118
+ emit('assertion-failure');
119
+ process.exitCode = 1;
120
+ } else {
121
+ throw error;
122
+ }
123
+ }
124
+ } else {
125
+ const value = require(process.env.HARNESS_SYNTHETIC_TARGET);
126
+ try {
127
+ assert.strictEqual(value, true);
128
+ emit('assertion-pass');
129
+ } catch (error) {
130
+ if (error && error.code === 'ERR_ASSERTION') {
131
+ emit('assertion-failure');
132
+ process.exitCode = 1;
133
+ } else {
134
+ throw error;
135
+ }
136
+ }
137
+ }
138
+ `);
139
+ write('synthetic-legacy-helper-test.js', [
140
+ "'use strict';",
141
+ "const helper = require('./ci/test-helper');",
142
+ "helper.check('legacy helper assertion', require(process.env.HARNESS_SYNTHETIC_TARGET) === true);",
143
+ '',
144
+ ].join('\n'));
145
+ write('synthetic-legacy-assert-test.js', [
146
+ "'use strict';",
147
+ "const assert = require('assert');",
148
+ "assert.strictEqual(require(process.env.HARNESS_SYNTHETIC_TARGET), true, 'legacy assert assertion');",
149
+ '',
150
+ ].join('\n'));
151
+ write('synthetic-legacy-callsite-test.js', [
152
+ "'use strict';",
153
+ "const assert = require('assert');",
154
+ 'assert.strictEqual(require(process.env.HARNESS_SYNTHETIC_TARGET), true);',
155
+ '',
156
+ ].join('\n'));
157
+ write('synthetic-legacy-output-test.js', [
158
+ "'use strict';",
159
+ "const value = require(process.env.HARNESS_SYNTHETIC_TARGET);",
160
+ "if (value === true) console.log('PASS legacy output assertion');",
161
+ "else { console.error('FAIL legacy output assertion'); process.exitCode = 1; }",
162
+ '',
163
+ ].join('\n'));
164
+
165
+ write('synthetic-legacy-helper-crash-test.js', [
166
+ "'use strict';",
167
+ "const helper = require('./ci/test-helper');",
168
+ "helper.check('legacy helper assertion', require(process.env.HARNESS_SYNTHETIC_TARGET) === true);",
169
+ "if (process.env.HARNESS_MUTATION) throw new Error('synthetic unrelated crash after the selected helper failure');",
170
+ '',
171
+ ].join('\n'));
172
+ write('synthetic-legacy-output-crash-test.js', [
173
+ "'use strict';",
174
+ "const value = require(process.env.HARNESS_SYNTHETIC_TARGET);",
175
+ "if (value === true) console.log('PASS legacy output assertion');",
176
+ "else { console.error('FAIL legacy output assertion'); if (process.env.HARNESS_MUTATION) throw new Error('synthetic unrelated crash after the selected output failure'); }",
177
+ '',
178
+ ].join('\n'));
179
+
180
+ const original = fs.readFileSync(targetPath, 'utf8');
181
+ const tupleKeys = new Set();
182
+ for (const tuple of CHECKS) {
183
+ assert.ok(tuple.label && tuple.target && tuple.mutantId && tuple.test && tuple.assertionId, 'production tuple declares target, mutant, test, and assertion');
184
+ assert.ok(MUTATIONS[tuple.mutantId], `production tuple has a registered transform: ${tuple.mutantId}`);
185
+ assert.ok(tuple.assertionId.startsWith(`${tuple.caseId}.`), 'legacy assertion ID is scoped to its stable legacy case ID');
186
+ if (!/^RB\d{2,}$/.test(tuple.caseId) && !isPrivateContract(tuple)) {
187
+ assert.ok(LEGACY_ASSERTIONS[tuple.assertionId], `legacy tuple has an anchored intended assertion: ${tuple.assertionId}`);
188
+ }
189
+ const key = `${tuple.target}\0${tuple.mutantId}\0${tuple.test}\0${tuple.assertionId}`;
190
+ assert.ok(!tupleKeys.has(key), 'mutation tuples are explicit and unique');
191
+ tupleKeys.add(key);
192
+ }
193
+ const loaderPath = require.resolve('./mutation-loader');
194
+ const inheritedOptions = `--trace-warnings --import="${loaderPath}" --max-old-space-size=2048`;
195
+ assert.strictEqual(
196
+ stripLoaderPreload(inheritedOptions, loaderPath),
197
+ '--trace-warnings --max-old-space-size=2048',
198
+ 'the inherited mutation-loader import is removed from NODE_OPTIONS'
199
+ );
200
+ assert.strictEqual(
201
+ stripLoaderPreload(`--trace-warnings --require="${loaderPath}" --max-old-space-size=2048`, loaderPath),
202
+ '--trace-warnings --max-old-space-size=2048',
203
+ 'a legacy mutation-loader require is also removed from NODE_OPTIONS'
204
+ );
205
+ const addedPreload = addLoaderPreload('--trace-warnings', loaderPath);
206
+ assert.match(addedPreload, /--import="?file:/, 'the loader import is a file: URL so Windows drive paths load under ESM');
207
+ assert.strictEqual(stripLoaderPreload(addedPreload, loaderPath), '--trace-warnings', 'a file: URL loader import is removed from NODE_OPTIONS');
208
+ const invalidPackageCwd = path.join(root, 'invalid-package-cwd');
209
+ fs.mkdirSync(invalidPackageCwd, { recursive: true });
210
+ fs.writeFileSync(path.join(invalidPackageCwd, 'package.json'), '{ invalid');
211
+ const preloadProbe = require('child_process').spawnSync(process.execPath, ['-e', "process.stdout.write('preload-ok')"], {
212
+ cwd: invalidPackageCwd,
213
+ env: { ...process.env, NODE_OPTIONS: addLoaderPreload('', loaderPath) },
214
+ encoding: 'utf8',
215
+ });
216
+ assert.strictEqual(preloadProbe.status, 0, `loader import must tolerate an invalid package.json cwd: ${preloadProbe.stderr}`);
217
+ assert.strictEqual(preloadProbe.stdout, 'preload-ok');
218
+ const noOp = prepareMutation({ root, target: 'synthetic-target.js', mutantId: 'test-noop', allowTestMutations: true });
219
+ assert.strictEqual(noOp.applied, false, 'no-op transform is not applied');
220
+ assert.strictEqual(noOp.parses, true, 'no-op source still parses');
221
+ assert.throws(() => prepareMutation({ root, target: 'synthetic-target.js', mutantId: 'not-known', allowTestMutations: true }), /unknown mutant/i);
222
+ assert.throws(() => prepareMutation({ root, target: 'synthetic-other.js', mutantId: 'test-kill', allowTestMutations: true }), /wrong target/i);
223
+
224
+ const invalidSyntax = prepareMutation({ root, target: 'synthetic-target.js', mutantId: 'test-syntax', allowTestMutations: true });
225
+ assert.strictEqual(invalidSyntax.applied, true, 'syntax mutant changes bytes');
226
+ assert.strictEqual(invalidSyntax.parses, false, 'syntax mutant is rejected by parser preflight');
227
+
228
+ const killed = checkTuple({ mutantId: 'test-kill' });
229
+ assert.strictEqual(killed.verdict, 'KILLED', `only the selected typed assertion qualifies the synthetic mutant: ${JSON.stringify(killed)}`);
230
+ assert.deepStrictEqual({ control: killed.control, applied: killed.applied, parses: killed.parses, loaded: killed.loaded, intendedAssertion: killed.intendedAssertion }, {
231
+ control: 'PASS', applied: true, parses: true, loaded: true, intendedAssertion: 'FAIL'
232
+ });
233
+
234
+ const savedEnv = new Map(['HARNESS_MUTATION', 'HARNESS_MUTATION_TARGET', 'HARNESS_MUTATION_LOADER_PRELOAD', 'NODE_OPTIONS']
235
+ .map(key => [key, process.env[key]]));
236
+ try {
237
+ process.env.HARNESS_MUTATION = 'stale-inherited-mutant';
238
+ process.env.HARNESS_MUTATION_TARGET = targetPath;
239
+ process.env.HARNESS_MUTATION_LOADER_PRELOAD = '1';
240
+ process.env.NODE_OPTIONS = inheritedOptions;
241
+ const isolated = checkTuple({ mutantId: 'test-kill' });
242
+ assert.strictEqual(isolated.verdict, 'KILLED', 'control and mutant runs clear inherited selection before setting their own');
243
+ } finally {
244
+ for (const [key, value] of savedEnv) {
245
+ if (value === undefined) delete process.env[key];
246
+ else process.env[key] = value;
247
+ }
248
+ }
249
+
250
+ const noOpResult = checkTuple({ mutantId: 'test-noop' });
251
+ assert.strictEqual(noOpResult.verdict, 'INVALID_MUTANT', 'no-op mutation cannot receive kill credit');
252
+ assert.strictEqual(noOpResult.applied, false);
253
+
254
+ const unknown = checkTuple({ mutantId: 'not-known' });
255
+ assert.strictEqual(unknown.verdict, 'INVALID_MUTANT', 'unknown mutation IDs fail closed');
256
+
257
+ const wrongTarget = checkTuple({ mutantId: 'test-kill', target: 'synthetic-other.js' });
258
+ assert.strictEqual(wrongTarget.verdict, 'INVALID_MUTANT', 'a mutation registered for another target fails closed');
259
+
260
+ const syntax = checkTuple({ mutantId: 'test-syntax' });
261
+ assert.strictEqual(syntax.verdict, 'INVALID_MUTANT', 'unparseable transformed source cannot be a kill');
262
+ assert.strictEqual(syntax.applied, true);
263
+ assert.strictEqual(syntax.parses, false);
264
+
265
+ const survived = checkTuple({ mutantId: 'test-survive' });
266
+ assert.strictEqual(survived.verdict, 'SURVIVED', 'a valid loaded mutation that preserves the asserted behavior survives');
267
+ assert.strictEqual(survived.loaded, true);
268
+ assert.strictEqual(survived.intendedAssertion, 'PASS');
269
+
270
+ const controlFailure = checkTuple({ mutantId: 'test-kill', mode: 'control-failure' });
271
+ assert.strictEqual(controlFailure.verdict, 'CONTROL_FAILED', 'a red unmutated control is infrastructure failure');
272
+ assert.strictEqual(controlFailure.applied, false, 'runner stops before mutant preflight after a red control');
273
+ assert.ok(controlFailure.reason.includes('RB00.synthetic.target-is-true')
274
+ && controlFailure.reason.includes('synthetic control assertion failed'),
275
+ `CONTROL_FAILED preserves the failing control assertion and message: ${controlFailure.reason}`);
276
+
277
+ const unscopedControl = checkTuple({ mutantId: 'test-kill', mode: 'control-unscoped-crash' });
278
+ assert.strictEqual(unscopedControl.verdict, 'CONTROL_FAILED', 'a crash after the selected PASS is still a red control');
279
+ assert.ok(unscopedControl.reason.includes('Error: synthetic unscoped control crash')
280
+ && unscopedControl.reason.includes('synthetic-test.js:'),
281
+ `an unscoped control crash retains its message and source callsite: ${unscopedControl.reason}`);
282
+
283
+ const crash = checkTuple({ mutantId: 'test-crash' });
284
+ assert.notStrictEqual(crash.verdict, 'KILLED', 'an import/runtime crash cannot be credited as a kill');
285
+ assert.strictEqual(crash.loaded, false, 'a module that throws during load has no loaded evidence');
286
+
287
+ const exitsDuringLoad = checkTuple({ mutantId: 'test-exit' });
288
+ assert.strictEqual(exitsDuringLoad.verdict, 'INFRA_MUTATED', 'process.exit during module evaluation cannot count as an assertion kill');
289
+ assert.strictEqual(exitsDuringLoad.loaded, true, 'a transformed module that exits during evaluation still emits its load evidence');
290
+ assert.strictEqual(exitsDuringLoad.intendedAssertion, 'MISSING', 'exit without the selected assertion remains unqualified');
291
+
292
+ const unrelated = checkTuple({ mutantId: 'test-kill', mode: 'unrelated-assertion' });
293
+ assert.strictEqual(unrelated.verdict, 'INFRA_MUTATED', 'a different assertion ID cannot kill the selected mutant');
294
+
295
+ const selectedAndUnrelated = checkTuple({ mutantId: 'test-kill', mode: 'selected-and-unrelated' });
296
+ assert.strictEqual(selectedAndUnrelated.verdict, 'KILLED', 'the exact selected assertion still qualifies when other typed assertions also fail');
297
+
298
+ const selectedThenCrash = checkTuple({ mutantId: 'test-kill', mode: 'selected-then-crash' });
299
+ assert.strictEqual(selectedThenCrash.verdict, 'INFRA_MUTATED', 'an uncaught infrastructure exception after an assertion event cannot count as a kill');
300
+
301
+ const genericFailure = checkTuple({ mutantId: 'test-kill', mode: 'generic-failure' });
302
+ assert.strictEqual(genericFailure.verdict, 'INFRA_MUTATED', 'generic failure text cannot kill a mutant');
303
+ assert.strictEqual(genericFailure.loaded, true);
304
+
305
+ const parityFailure = checkTuple({ mutantId: 'test-kill', mode: 'parity-only-failure' });
306
+ assert.strictEqual(parityFailure.verdict, 'INFRA_MUTATED', 'source/package parity output cannot kill a mutant');
307
+ assert.strictEqual(parityFailure.loaded, true);
308
+
309
+ const unloaded = checkTuple({ mutantId: 'test-kill', mode: 'does-not-load-target' });
310
+ assert.strictEqual(unloaded.verdict, 'UNLOADED', 'a matching test event without transformed-module load evidence is unqualified');
311
+ assert.strictEqual(unloaded.loaded, false);
312
+
313
+ const timeout = checkTuple({ mutantId: 'test-kill', mode: 'timeout', timeoutMs: 2000 });
314
+ assert.strictEqual(timeout.verdict, 'INFRA_MUTATED', 'a timed-out child cannot count as an intended assertion kill');
315
+ assert.strictEqual(timeout.loaded, true, 'the timeout occurs after the transformed module loaded');
316
+
317
+ const nested = checkTuple({ mutantId: 'test-kill', mode: 'nested-process' });
318
+ assert.strictEqual(nested.verdict, 'KILLED', 'mutation preload and load evidence propagate into exact Node child processes');
319
+ assert.strictEqual(nested.loaded, true);
320
+
321
+ const legacyHelperCase = 'LEGACY.synthetic-legacy-helper-test';
322
+ const legacyHelper = checkLegacyTuple({
323
+ test: 'synthetic-legacy-helper-test.js',
324
+ caseId: legacyHelperCase,
325
+ assertionId: `${legacyHelperCase}.selected-check`,
326
+ signature: { kind: 'helper', label: 'legacy helper assertion' },
327
+ });
328
+ assert.strictEqual(legacyHelper.verdict, 'KILLED', `legacy helper checks emit a typed selected assertion event: ${JSON.stringify(legacyHelper)}`);
329
+
330
+ const legacyAssertCase = 'LEGACY.synthetic-legacy-assert-test';
331
+ const legacyAssert = checkLegacyTuple({
332
+ test: 'synthetic-legacy-assert-test.js',
333
+ caseId: legacyAssertCase,
334
+ assertionId: `${legacyAssertCase}.selected-assert`,
335
+ signature: { kind: 'assert', method: 'strictEqual', messageIndex: 2, message: 'legacy assert assertion' },
336
+ });
337
+ assert.strictEqual(legacyAssert.verdict, 'KILLED', 'legacy Node assert failures emit the exact selected assertion event');
338
+
339
+ const legacyCallsiteCase = 'LEGACY.synthetic-legacy-callsite-test';
340
+ const legacyCallsite = checkLegacyTuple({
341
+ test: 'synthetic-legacy-callsite-test.js',
342
+ caseId: legacyCallsiteCase,
343
+ assertionId: `${legacyCallsiteCase}.selected-callsite`,
344
+ signature: { kind: 'assert', method: 'strictEqual', callSite: { file: 'synthetic-legacy-callsite-test.js', line: 3 } },
345
+ });
346
+ assert.strictEqual(legacyCallsite.verdict, 'KILLED', 'legacy assert signatures can qualify an exact source callsite without matching generic failures');
347
+
348
+ const legacyOutputCase = 'LEGACY.synthetic-legacy-output-test';
349
+ const legacyOutput = checkLegacyTuple({
350
+ test: 'synthetic-legacy-output-test.js',
351
+ caseId: legacyOutputCase,
352
+ assertionId: `${legacyOutputCase}.selected-output`,
353
+ signature: {
354
+ kind: 'output',
355
+ pass: /^PASS legacy output assertion$/,
356
+ fail: /^FAIL legacy output assertion$/,
357
+ },
358
+ });
359
+ assert.strictEqual(legacyOutput.verdict, 'KILLED', 'anchored legacy output signatures qualify only their selected failure');
360
+
361
+ // Negative controls (owner review P2-2): an unrelated uncaught exception after the selected failure is never a kill.
362
+ const legacyHelperCrashCase = 'LEGACY.synthetic-legacy-helper-crash-test';
363
+ const legacyHelperCrash = checkLegacyTuple({
364
+ test: 'synthetic-legacy-helper-crash-test.js',
365
+ caseId: legacyHelperCrashCase,
366
+ assertionId: `${legacyHelperCrashCase}.selected-check`,
367
+ signature: { kind: 'helper', label: 'legacy helper assertion' },
368
+ });
369
+ assert.strictEqual(legacyHelperCrash.verdict, 'INFRA_MUTATED',
370
+ `legacy selected-then-crash: an unrelated uncaught exception after a selected helper failure cannot count as a kill: ${JSON.stringify(legacyHelperCrash)}`);
371
+
372
+ const legacyOutputCrashCase = 'LEGACY.synthetic-legacy-output-crash-test';
373
+ const legacyOutputCrash = checkLegacyTuple({
374
+ test: 'synthetic-legacy-output-crash-test.js',
375
+ caseId: legacyOutputCrashCase,
376
+ assertionId: `${legacyOutputCrashCase}.selected-output`,
377
+ signature: {
378
+ kind: 'output',
379
+ pass: /^PASS legacy output assertion$/,
380
+ fail: /^FAIL legacy output assertion$/,
381
+ },
382
+ });
383
+ assert.strictEqual(legacyOutputCrash.verdict, 'INFRA_MUTATED',
384
+ `legacy output-then-crash: a matching FAIL line followed by an unrelated uncaught exception cannot count as a kill: ${JSON.stringify(legacyOutputCrash)}`);
385
+
386
+ // C3 boundary qualification (plan §3): a no-op checker transform must survive (never KILLED), and a real checker-off
387
+ // transform must be killed through its selected enforcement assertion. Both run through the real runner against the
388
+ // real checker and suite; no verdict is written by hand.
389
+ const boundaryRoot = path.resolve(__dirname, '..');
390
+ const boundaryTuple = ({ mutantId, caseId, assertionId }) => runChecks({
391
+ root: boundaryRoot,
392
+ timeoutMs: 120000,
393
+ testEnv: {},
394
+ checks: [{
395
+ label: `${mutantId} boundary qualification`,
396
+ target: 'ci/lib/doc-evidence-boundary-check.js',
397
+ mutantId,
398
+ test: 'ci/mechanism-341-boundary-enforcement.test.js',
399
+ caseId,
400
+ assertionId,
401
+ }],
402
+ legacyAssertions: {},
403
+ })[0];
404
+ const noopBoundary = boundaryTuple({ mutantId: 'C00-noop-boundary', caseId: 'C1-N01d-canonical', assertionId: 'C1-N01d-canonical.boundary.intended-code-CONTEXT_ALIAS_OR_COMPUTED_USE' });
405
+ assert.strictEqual(noopBoundary.verdict, 'SURVIVED', `a no-op checker transform must survive, never be credited as a kill: ${JSON.stringify(noopBoundary)}`);
406
+ const realBoundary = boundaryTuple({ mutantId: 'C01-alias-rule-off', caseId: 'C1-N01d-canonical', assertionId: 'C1-N01d-canonical.boundary.intended-code-CONTEXT_ALIAS_OR_COMPUTED_USE' });
407
+ assert.strictEqual(realBoundary.verdict, 'KILLED', `the alias-rule-off checker mutant must be killed by its selected assertion: ${JSON.stringify(realBoundary)}`);
408
+
409
+ assert.strictEqual(fs.readFileSync(targetPath, 'utf8'), original, 'mutation qualification never overwrites a synthetic target');
410
+ console.log('Phase 0A mutation runner qualification passed: control, tuple, transform, parse, load, intended assertion, and negative controls.');
411
+ } finally {
412
+ fs.rmSync(root, { recursive: true, force: true });
413
+ }