tools/core/steps/gate.step.ts
tools/core/steps/gate.step.ts is a file in Coordination Surface. 167 lines of code and 22 definitions.
import type { StepOptions, StepOutcome } from "../types/rule.types.ts";
import { existsSync, readFileSync } from "node:fs";
import { surfacePath, surfaceRoot } from "../../../config/surface.config.ts";
import type { Finding } from "../types/segment.types.ts";
import { GENERATED_DIR } from "../constants/path.constants.ts";
import { isObject } from "../predicates/schema.predicate.ts";
import { isUnreadableJson } from "../predicates/file.predicate.ts";
import { proofRunEmpty } from "../strings/gate.strings.ts";
import { resolve } from "node:path";
import { runTool } from "../runners/process.runner.ts";
import { writeRuleReport } from "../reporters/rule.reporter.ts";
const COMMAND = "npm";
const ARGS = ["run", "--silent", "gates"];
const REPORT = "gate.report.generated.json";
const INVARIANT = "every registered rule is proven to fire on a violation and to accept a clean input";
const DECIDE =
"a rule nobody has watched fail is indistinguishable from one that cannot fail, and a gate that scans " +
"nothing passes; declare a fixture pair — one sample " +
"the rule must report and one it must accept — so the proof is an artifact rather than a ritual repeated " +
"from memory each time the rule is touched";
interface Outcome {
readonly rule: string;
readonly state: string;
readonly detail: string;
}
const gateReportList = function gateReportList(repoRoot: string, key: string): unknown[] {
const path = resolve(repoRoot, GENERATED_DIR, REPORT);
if (!existsSync(path)) {
return [];
}
try {
const parsed: unknown = JSON.parse(readFileSync(path, "utf8"));
const held = isObject(parsed) ? parsed[key] : null;
return Array.isArray(held) ? held : [];
} catch (error) {
if (isUnreadableJson(error)) {
return [];
}
throw error;
}
};
const unfixturedFrom = function unfixturedFrom(repoRoot: string): string[] {
return gateReportList(repoRoot, "unfixturedKinds").filter((kind): kind is string => typeof kind === "string");
};
const unfixturedFinding = function unfixturedFinding(kind: string): Finding {
const rule = kind.slice(0, kind.indexOf("/"));
return {
actual: `${kind} is emitted and no fixture pair declares it`,
expected: "a sample the kind must report and one it must accept, or a written exemption",
healed: false,
line: 0,
locus: kind,
path: `${surfacePath("rules")}/${rule}.rule.ts`,
remediation: {
action: "declare",
decide:
"a rule proven at RULE granularity says nothing about the kinds it can emit — a pair covering one " +
"kind leaves every other kind of that rule unobserved, which is how a detector ships having only " +
"ever been seen to stay quiet. Declare the pair, or declare the exemption with the reason a " +
"synthetic sample cannot hold the construct",
deterministic: false,
from: kind,
target: `${surfacePath("core")}/fixtures/gate.fixture.ts`,
to: null,
},
rule: "gate/unfixturedKind",
stack: [
{ check: "emitted", resolved: kind },
{ check: "fixturePair", resolved: "none declares this kind" },
],
};
};
const isOutcome = function isOutcome(value: unknown): value is Outcome {
if (typeof value !== "object" || value === null) {
return false;
}
const candidate = value as { rule?: unknown; state?: unknown; detail?: unknown };
return (
typeof candidate.rule === "string" &&
typeof candidate.state === "string" &&
typeof candidate.detail === "string"
);
};
const outcomesFrom = function outcomesFrom(repoRoot: string): Outcome[] {
return gateReportList(repoRoot, "outcomes").filter(isOutcome);
};
const gateFinding = function gateFinding(outcome: Outcome): Finding {
return {
actual: outcome.detail,
expected: "a fixture pair the rule fires on and accepts",
healed: false,
line: 0,
locus: outcome.rule,
path: `${surfacePath("rules")}/${outcome.rule}.rule.ts`,
remediation: {
action: "declare",
decide: DECIDE,
deterministic: false,
from: outcome.rule,
target: `${surfacePath("core")}/fixtures/gate.fixture.ts`,
to: null,
},
rule: `gate/${outcome.state}`,
stack: [
{ check: "fixturePair", resolved: outcome.state },
{ check: "detail", resolved: outcome.detail },
],
};
};
export const KINDS: readonly string[] = ["gate/unfixturedKind", "gate/silent", "gate/noisy", "gate/untested"];
export const gateStage = function gateStage(options: StepOptions): StepOutcome {
if (options.bypass.includes("gates")) {
return {
findings: [],
stage: { bypassed: true, findings: 0, healed: 0, invariant: INVARIANT, rule: "gates", stage: "meta" },
};
}
const run = runTool(surfaceRoot(), "gates", COMMAND, INVARIANT, ARGS);
const outcomes = outcomesFrom(options.repoRoot);
const findings =
outcomes.length === 0
? [
gateFinding({
detail: proofRunEmpty(run.output.trim().slice(0, 300)),
rule: "gates",
state: "unproven",
}),
]
: [
...outcomes
.filter((outcome) => outcome.state !== "proven" && outcome.state !== "exempt")
.map(gateFinding),
...unfixturedFrom(options.repoRoot).map(unfixturedFinding),
];
writeRuleReport(options.repoRoot, "gates", {
authoritative: options.authoritative,
derivations: {
provenKinds: outcomes
.filter((outcome) => outcome.state === "proven")
.map((outcome) => `${outcome.rule}: ${outcome.detail}`),
reached: outcomes.map((outcome) => outcome.rule),
skippedAsExemptByDerivation: outcomes
.filter((outcome) => outcome.state === "exempt")
.map((outcome) => `${outcome.rule}: ${outcome.detail}`),
unfixturedKinds: unfixturedFrom(options.repoRoot),
},
findings,
healed: [],
invariant: INVARIANT,
rule: "gates",
scanned: outcomes.length,
scope: options.scope,
stage: "meta",
verdict: findings.length === 0 ? "pass" : "fail",
});
return {
findings,
stage: {
bypassed: false,
findings: findings.length,
healed: 0,
invariant: INVARIANT,
rule: "gates",
stage: "meta",
},
};
};