Files
Michał Pierzchała d4cf02a889 chore(gates): classify #2278 daemon-platform-runtime edges and ratchet handler session authority (#2354)
* chore(gates): classify #2278 daemon-platform-runtime edges (R74) and ratchet handler session authority (R75)

* chore(gates): discover the R75 shape target from the SessionState declaration

* chore(gates): capture dynamic-import bindings in R74 so symbol drift cannot hide

* chore(gates): reject dynamic-import destructure residue in R74

* chore(gates): R74 rejects open-ended dynamic imports beside named bindings

* chore(gates): renumber daemon-platform-runtime-inventory to R76 (R74 taken on main)
2026-09-08 13:21:29 +02:00

82 lines
2.9 KiB
TypeScript

import assert from 'node:assert/strict';
import { test } from 'node:test';
import { policyLead, policyViolation, ZONE_POLICIES } from './zone-policy.ts';
// The folder policies originally had no unit test: the only thing exercising them was a clean real
// tree, so a rule that silently stopped matching looked like one being obeyed. These tests keep the
// remaining R2 policy from becoming decoration.
type Kind = { typeOnly?: boolean; dynamic?: boolean };
function edge(file: string, fromZone: string, toZone: string, kind: Kind = {}) {
return {
file,
fromZone,
toZone,
imp: {
spec: `../${toZone}/thing.ts`,
line: 1,
dynamic: kind.dynamic ?? false,
typeOnly: kind.typeOnly ?? false,
symbols: [],
bindingResidue: false,
},
};
}
/** Every policy that fires for an edge, by rule id. */
function firing(e: ReturnType<typeof edge>): string[] {
return ZONE_POLICIES.filter((policy) => policyViolation(policy, e) !== null).map((p) => p.rule);
}
test('R2 commands-floor closes the remaining zones below the command surface, whatever the kind', () => {
for (const zone of ['core', 'daemon']) {
for (const kind of [{}, { typeOnly: true }, { dynamic: true }]) {
assert.ok(
firing(edge(`src/${zone}/thing.ts`, zone, 'commands', kind)).includes('R2 commands-floor'),
`${zone} -> commands ${JSON.stringify(kind)} must violate R2`,
);
}
}
// Zones at or above the command surface are not governed by R2.
assert.deepEqual(firing(edge('src/cli/run.ts', 'cli', 'commands')), []);
assert.deepEqual(firing(edge('src/mcp/tools.ts', 'mcp', 'commands')), []);
});
test('the retired R3 platforms seam has no zone-policy declaration', () => {
assert.equal(
ZONE_POLICIES.some(({ rule }) => rule === 'R3 platforms-seam'),
false,
);
});
test('every policy carries a hint, and the lead names the kind it rejected', () => {
// ADR 0010: an error that does not say what to do instead is a rule nobody can act on.
for (const policy of ZONE_POLICIES) {
assert.ok(policy.hint.length > 20, `${policy.rule} needs an actionable hint`);
}
assert.match(policyLead(edge('a', 'core', 'commands')), /core\/ must not import commands\//);
assert.match(
policyLead(edge('a', 'core', 'commands', { typeOnly: true })),
/must not type-only import commands\//,
);
assert.match(
policyLead(edge('a', 'core', 'commands', { dynamic: true })),
/must not dynamic import commands\//,
);
});
test('a policy states its scope with exactly one of `to` or `exceptTo`', () => {
// Both would make the target set ambiguous; neither would silently govern every target, which is
// never what a boundary means.
for (const policy of ZONE_POLICIES) {
assert.notEqual(
Boolean(policy.to) === Boolean(policy.exceptTo),
true,
`${policy.rule} must set exactly one of to/exceptTo`,
);
}
});