tools/rules/governance.rule.ts
tools/rules/governance.rule.ts is a file in Coordination Surface. 140 lines of code and 22 definitions.
import type { RuleContext, RuleDeclaration, RuleResult } from "../core/types/rule.types.ts";
import { contentIsUnrepairable, lifetimeOf, surfacePath } from "../../config/surface.config.ts";
import {
deleteReport,
orphanReports,
selfAuditedReports,
unaccountedScopeGaps,
unevaluableScopes,
withdrawnStandings,
} from "../core/validators/governance.validator.ts";
import { orphanFinding, staleChannelFinding, writerFinding } from "../core/factories/governance.factory.ts";
import { removeChannel, staleChannels } from "../core/validators/channel.validator.ts";
import { scopeGapFinding, unevaluableFinding, unrepairableFinding } from "../core/factories/report.factory.ts";
import { shapeFindings, sourceFindings } from "../core/validators/rule.validator.ts";
import type { Finding } from "../core/types/segment.types.ts";
import { RULE_ROOT } from "../core/constants/layer.constants.ts";
import { STAGES } from "../core/types/rule.types.ts";
import { claimedReportIds } from "../core/validators/emission.validator.ts";
import { contains } from "../core/predicates/text.predicate.ts";
import { existsSync } from "node:fs";
import { isItemId } from "../core/formatters/board.formatter.ts";
import { resolve } from "node:path";
import { unrepairableLoci } from "../core/validators/repair.validator.ts";
import { unsanctionedWriters } from "../core/validators/writer.validator.ts";
const CORE = surfacePath("core");
const RUN_ENTRIES = [`${surfacePath("entrypoints")}/pipeline.entrypoint.ts`];
const SANCTIONED_WRITERS = [
`${CORE}/writers/repair.writer.ts`,
`${CORE}/reporters/rule.reporter.ts`,
`${CORE}/reporters/segment.reporter.ts`,
`${CORE}/registries/claim.registry.ts`,
`${CORE}/registries/snapshot.registry.ts`,
`${CORE}/validators/channel.validator.ts`,
`${CORE}/validators/governance.validator.ts`,
];
const RULE_SELECTOR = "rule=";
const STAGE_SELECTOR = "stage=";
interface Healing {
readonly findings: Finding[];
readonly healed: string[];
}
const permanentSpan = function permanentSpan(reported: string, locus: string): boolean {
if (!isItemId(locus)) {
return false;
}
return lifetimeOf(reported)?.retention === "accumulating";
};
const channelScopeResolver = function channelScopeResolver(
repoRoot: string,
claimed: ReadonlySet<string>,
): (scope: string) => boolean {
return (scope: string): boolean => {
if (scope.startsWith(RULE_SELECTOR)) {
return claimed.has(scope.slice(RULE_SELECTOR.length));
}
if (scope.startsWith(STAGE_SELECTOR)) {
return STAGES.some((stage) => stage === scope.slice(STAGE_SELECTOR.length));
}
return existsSync(resolve(repoRoot, scope));
};
};
const healOrphans = function healOrphans(repoRoot: string, claimed: ReadonlySet<string>): Healing {
const orphans = orphanReports(repoRoot, claimed);
for (const name of orphans) {
deleteReport(repoRoot, name);
}
return { findings: orphans.map(orphanFinding), healed: [...orphans] };
};
const writerFindings = function writerFindings(context: RuleContext): Finding[] {
const known = new Set(context.paths.filter((path) => path.endsWith(".ts")));
return unsanctionedWriters(RUN_ENTRIES, known, context.read, SANCTIONED_WRITERS).map(writerFinding);
};
const healChannels = function healChannels(repoRoot: string, claimed: ReadonlySet<string>): Healing {
const stale = staleChannels(repoRoot, channelScopeResolver(repoRoot, claimed));
for (const channel of stale) {
removeChannel(repoRoot, channel.name);
}
return { findings: stale.map(staleChannelFinding), healed: stale.map((channel) => channel.name) };
};
export const rule: RuleDeclaration = {
check(context: RuleContext): RuleResult {
const { repoRoot } = context;
const claimed = claimedReportIds(repoRoot);
const orphans = healOrphans(repoRoot, claimed);
const writers = writerFindings(context);
const channels = healChannels(repoRoot, claimed);
const sources = context.paths.filter((path) => contains(path, RULE_ROOT));
const findings = [
...orphans.findings,
...writers,
...channels.findings,
...unaccountedScopeGaps(repoRoot).map(scopeGapFinding),
...unevaluableScopes(repoRoot).map(unevaluableFinding),
...unrepairableLoci(repoRoot, contentIsUnrepairable, permanentSpan).map(unrepairableFinding),
...sources.flatMap((path) => sourceFindings(repoRoot, path, context.read(path))),
...shapeFindings(context),
];
return {
derivations: {
identityContract:
"a check's identity is DERIVED from its filename subject and is declared nowhere, so the two-name divergence this walk once compared is unconstructible rather than absent. The comparison is not reported as passing, because a check whose members cannot exist is dead rather than green — what replaces it is the registry refusing any declaration that carries an id at all, which is the collapse the join was a substitute for",
reportsAudited: [...claimed].toSorted((left, right) => left.localeCompare(right, "en")),
ruleSourcesWalked: sources,
selfAuditStanding:
"this check reads reports its own run writes, so the verdict on any report listed under selfAudited describes the PREVIOUS run of it — a first verdict after repairing this check is one run behind, and the second run is the one authoritative for that member. The lag is stated rather than excluded, because excluding a check from its own audit installs a blind spot shaped exactly like the thing being hidden",
selfAudited: selfAuditedReports(repoRoot, context.id),
skippedAsNotARuleSource: context.paths.filter((path) => !contains(path, RULE_ROOT)),
standingContract:
"a verdict carries a STANDING beside its value, and a report listed under withdrawnStandings read a surface that has CHANGED since the report was written — so that verdict describes a tree that has moved and is not authoritative to quote, while the verdict itself is untouched because declaring it a failure would assert a defect nothing observed. This is published as a DERIVATION rather than emitted as a finding, deliberately: on a surface several parties write continuously every report is stale within moments of any write, so a finding here would be red between every run and a permanent red teaches every reader to discount the color — the cost landing on the findings beside it rather than on itself. The reader who needs this is the one about to QUOTE a verdict, and the honest mechanism hands them the standing rather than failing a build over a transient",
withdrawnStandings: withdrawnStandings(repoRoot),
},
findings,
healed: [...orphans.healed, ...channels.healed],
};
},
extensions: [".ts"],
heals: true,
invariant:
"every rule source declares the full contract and emits findings in the machine-actionable shape, and every report on disk is claimed by something that emits it",
jurisdiction: "taxonomy",
kinds: [
"ruleContract",
"declarationContract",
"orphanReport",
"unsanctionedWriter",
"staleChannel",
"unevaluableScope",
"unrepairableLocus",
"matching",
],
readsTree:
"a channel names the SCOPE its run declared, and whether that scope still resolves is a question about " +
"the TREE rather than about any file's contents — a scope naming a subtree is answered by whether the " +
"subtree is there, which no set of scanned file contents can decide. The reports this walk reads are " +
"generated output and sit outside the governed path set by construction, so a rule reading only that " +
"set would report a clean green over every report and every channel in the directory the pipeline " +
"writes",
stage: "meta",
wholeScopeOnly: true,
};