wip(rm-02): round-4 remediation held at RM-60 boundary

This commit is contained in:
2026-08-01 14:39:36 -05:00
parent fbb6191298
commit 9b7005d59b
23 changed files with 851 additions and 1442 deletions
+76 -10
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
import { chmod, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
@@ -27,7 +27,6 @@ async function rejectedForEveryGate(mutate, diagnostic) {
const result = await verifyRegistry({
root,
manifest: manifestPath,
skipHistory: true,
structureOnly: true,
fixtureProfile: false,
});
@@ -41,14 +40,81 @@ async function rejectedForEveryGate(mutate, diagnostic) {
let rejected;
if (mode === 'evidence-subject') {
rejected = await rejectedForEveryGate(
(gate) => {
gate.evidenceSubject = 'different-gate-subject';
},
(failure, gateId) =>
failure.includes(`gate ${gateId}: evidence subject`) &&
failure.includes('does not match gate id'),
);
rejected = true;
for (const gateId of expectedGateIds) {
const directory = await mkdtemp(path.join(os.tmpdir(), 'gate-evidence-consumption-'));
try {
await mkdir(path.join(directory, 'gates'), { recursive: true });
const probe = path.join(directory, 'gates', 'probe.sh');
await writeFile(probe, '#!/bin/sh\necho EVIDENCE_PROBE >&2\nexit 7\n');
await chmod(probe, 0o755);
const manifest = {
schemaVersion: 1,
gateRoots: ['gates'],
governingClaimFiles: [],
coverageBoundary: { included: ['evidence fixture'], excluded: [], trackedBy: 'RM-02' },
criteria: [
{
id: 'EVIDENCE-CONSUMPTION',
originalText: 'Consumed evidence stays bound to its gate.',
currentText: 'Consumed evidence stays bound to its gate.',
claimType: 'integrity',
source: 'gate-population-control',
meaningChanges: [],
caseRefs: [`${gateId}/probe`],
},
],
proseClaims: [],
compatibilityScenarios: [],
gates: [
{
id: gateId,
source: 'gates/probe.sh',
invocation: ['gates/probe.sh'],
deployment: { kind: 'none', reason: 'population fixture' },
inertMutation: {
file: 'gates/probe.sh',
find: 'exit 7',
replace: 'exit 0',
caseId: 'probe',
expected: { exitCode: 0 },
},
cases: [
{
id: 'probe',
criterionIds: ['EVIDENCE-CONSUMPTION'],
mustFail: true,
required: { exitCode: 7 },
actual: { exitCode: 7 },
evidence: { subject: 'different-gate-subject' },
reasonPattern: 'EVIDENCE_PROBE',
},
],
},
],
};
const manifestPath = path.join(directory, 'gates', 'gates.manifest.json');
await writeFile(manifestPath, `${JSON.stringify(manifest)}\n`);
const result = await verifyRegistry({
root: directory,
manifest: manifestPath,
structureOnly: false,
fixtureProfile: true,
});
if (
!result.failures.some(
(failure) =>
failure.includes(`gate ${gateId}: consumed evidence subject`) &&
failure.includes('does not match gate definition'),
)
) {
rejected = false;
break;
}
} finally {
await rm(directory, { recursive: true, force: true });
}
}
} else if (mode === 'type-strict') {
rejected = await rejectedForEveryGate(
(gate) => {