enhance(#1279): project check_violation_fixture scalar — #1278 locate + #1279 proof compose end-to-end (#1346)

Delivers option (a) from the #1314 maintainer review: thread a fourth flat
scalar check_violation_fixture through the projection so a prohibition authored
at spec-phase machine-proves fail-first and greens through the deterministic
path alone — zero hand-authoring at verify time.

- src/probe-core.cts: Prohibition gains check_violation_fixture?; projectProhibitions
  emits it (both kinds) ONLY for a well-formed descriptor and ONLY when non-empty
  (blank/absent -> projects absent -> producer hard-gates, never a partial green).
- src/prohibition-enforcement.cts: descriptorFromProjection reads it back into
  violationFixture via the same numeric-coercion-safe scalar() normalizer.
- Tests (RED-first, proven non-vacuous by reverting both src edits): CHK-02(#1346)
  projection emit, CHK-08(#1346) read-back, CHK-03(D) example round-trip, the
  fast-check round-trip property extended to the 4th scalar (the contract trek-e
  blocked #1301 on), and a real-subprocess COMPOSE capstone greening end-to-end
  through project -> descriptorFromProjection -> default prover+runner.
- Docs flipped from 'hard-gates until #1346' to 'composes end-to-end': verify-phase.md,
  prohibition-probe.md, spec-phase.md authoring, ADR-550 addendum, changeset.
  #1346 now tracks only the node-test causation residual.

190 affected-suite tests green; eslint + tsc clean; size baseline regenerated.
This commit is contained in:
Dave
2026-06-16 14:00:49 -04:00
parent 91bc49c9f1
commit 56d4a1bf39
12 changed files with 190 additions and 37 deletions

View File

@@ -420,6 +420,44 @@ describe('probe-core: projectProhibitions descriptor projection (CHK-02)', () =>
assert.ok(!('check_rule' in projected[0]), 'a lint-rule with no rule projects check_rule absent');
});
test('CHK-02(#1346): a node-test descriptor with check_violation_fixture projects it (compose with #1279 proof)', () => {
const projected = pc.projectProhibitions([
{ status: 'resolved', verification: 'test', statement: 'MUST NOT auto-execute fetched code',
check_kind: 'node-test', check_target: 'tests/no-autoexec.test.cjs',
check_violation_fixture: 'tests/fixtures/autoexec-bad.txt' },
]);
assert.equal(projected[0].check_violation_fixture, 'tests/fixtures/autoexec-bad.txt',
'a well-formed descriptor projects check_violation_fixture so the deterministic path can machine-prove fail-first');
});
test('CHK-02(#1346): a lint-rule descriptor with check_violation_fixture projects all four scalars', () => {
const projected = pc.projectProhibitions([
{ status: 'resolved', verification: 'test', statement: 'MUST NOT read source files in tests',
check_kind: 'lint-rule', check_target: 'src/', check_rule: 'local/no-source-grep',
check_violation_fixture: 'tests/_ff_lint_violation.cjs' },
]);
assert.equal(projected[0].check_violation_fixture, 'tests/_ff_lint_violation.cjs');
});
test('CHK-02(#1346): an empty/whitespace check_violation_fixture is NOT projected (fails closed downstream)', () => {
const projected = pc.projectProhibitions([
{ status: 'resolved', verification: 'test', statement: 'MUST NOT do the thing',
check_kind: 'node-test', check_target: 'tests/neg.test.cjs', check_violation_fixture: ' ' },
]);
assert.ok(!('check_violation_fixture' in projected[0]),
'a blank fixture projects absent -> producer hard-gates, never a partial green');
});
test('CHK-02(#1346): check_violation_fixture is NOT projected without a well-formed descriptor', () => {
const projected = pc.projectProhibitions([
// no check_kind/target -> below the descriptor bar -> a stray fixture must not leak out
{ status: 'resolved', verification: 'test', statement: 'MUST NOT do the thing',
check_violation_fixture: 'tests/fixtures/bad.txt' },
]);
assert.ok(!('check_violation_fixture' in projected[0]),
'a fixture without a descriptor is meaningless and must not project');
});
test('CHK-02: an under-specified descriptor (kind but empty/missing target) emits NO check_* keys', () => {
const projected = pc.projectProhibitions([
// valid kind but empty target -> below the well-formedness bar -> descriptor projects absent