/** * artifact has to PROVE. * * The three layers used to be checked with `text.includes()` over the * whole file. A substring test cannot tell "the rule is registered" from "a * comment saying the rule is absent", so a refusal tree passed every layer: * * - layer A: a `.peaks/sops/registry.json` that is not valid JSON, with the id * still somewhere in its bytes; * - layer B: a settings template whose only mention of the rule reads * "do NOT add a matcher for "; * - layer C: a `mode-gate.ts` whose only mention reads * "// TODO: is DELIBERATELY NOT a hard-floor category". * * All three are the same defect facing the other way: an unreadable artifact is * treated as a permitted one. Each check below therefore parses its evidence and * asserts the SHAPE, and every failure is a finding — never a warning that * permits. Nothing here throws: an unparseable file is reported, not swallowed. * * R8 (same rid) — the same defect survived inside R2's repair, in two places: * * - layer C matched a member's `doc` by name MENTION, so an adverse line * sitting between two vocabulary members became the following member's doc * and the verdict flipped on where the comment sat. The predicate is now this * repo's own citation form — the memory cited by PATH, * `.peaks/memory/.md`, exactly as `mode-gate.ts:41` does — rather than * the memory merely named. That citation requirement is what closes the * placement dependence; the doc is also read from the comment SPANS attached * to the member rather than from the raw slice, which states "code is not a * doc" as an invariant rather than relying on the raw slice to honour it; * - layer B kept `matcher.includes(id)` / `command.includes(id)` over free * text, so `command: "echo 'do NOT add a matcher for rule-x'"` registered a * rule by writing a sentence about it. Both fields are now parsed: a matcher * is a tool selector, a command is argv. * * R10 (same rid) — layer C read the `HardFloorCategory` union and the * `HARD_FLOOR_CATEGORIES` array as ONE flattened member list, so a member of the * union alone satisfied the check. Measured on the R8 bytes: a union-only literal * — and a union-only member whose doc cited `.peaks/memory/.md` — were both * reported BACKED, while `isHardFloorCategory` (which reads the array) returned * false and `shouldPauseAtGate` returned `shouldPause: false`. The gate certified * a hard floor that paused nothing, contradicting its own message. Only the array * enforces, so only the array is now evidence — for the name and for the citation * alike. The union is still READ, for one reason only: a category's doc belongs * to the category, and this repo documents `commit-boundary-side-effect` beside * the union member while the array enforces it. */ import { type PromotionArtifactCheck } from './promotion-artifact-json-evidence.js'; export type { PromotionArtifactCheck, PromotionEvidence } from './promotion-artifact-json-evidence.js'; /** * The reason `check` is unsatisfied by `text`, or `null` when it is satisfied. * Never throws: a file that cannot be parsed yields the reason it could not be. */ export declare function artifactEvidenceFailure(check: PromotionArtifactCheck, text: string): string | null;