# tools/core/validators/gate.validator.ts

> 312 lines of code and 49 definitions.

Tree: Coordination tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-validators-gate-validator-ts
Source text: https://banes-lab.com/assets/sources/source.c9c35d6d5815b4d187f887fe9d259d4dfc53fc7f1b31c3cda5f92138ec419de5.generated.txt

## Definitions

- `pathsOf` (lexical_declaration, line 234)
- `healingOutcome` (lexical_declaration, line 185)
- `sampledOutcome` (lexical_declaration, line 319)
- `healOnlyOutcome` (lexical_declaration, line 248)
- `provenOutcome` (lexical_declaration, line 307)
- `sampledFailure` (lexical_declaration, line 266)
- `healing` (lexical_declaration, line 327)
- `rendered` (lexical_declaration, line 47)
- `exemptOutcome` (lexical_declaration, line 238)
- `astrayOutcome` (lexical_declaration, line 293)
- `judge` (lexical_declaration, line 338, exported)
- `judgeBranch` (lexical_declaration, line 88, exported)
- `contextOf` (lexical_declaration, line 117)
- `fromDisk` (lexical_declaration, line 164)
- `GATE_STATES` (lexical_declaration, line 11, exported)
- `GateState` (type_alias_declaration, line 13, exported)
- `GateOutcome` (interface_declaration, line 15, exported)
- `Exercise` (interface_declaration, line 21)
- `Counted` (interface_declaration, line 26)
- `disagreements` (lexical_declaration, line 31)
- `out` (lexical_declaration, line 32)
- `keys` (lexical_declaration, line 33)
- `seen` (lexical_declaration, line 36)
- `unsuppliedReads` (lexical_declaration, line 53, exported)
- `supplied` (lexical_declaration, line 66, exported)
- `exercise` (lexical_declaration, line 77)
- `{ error, observed }` (lexical_declaration, line 89, exported)
- `apart` (lexical_declaration, line 98, exported)
- `held` (lexical_declaration, line 123)
- `countFindings` (lexical_declaration, line 142)
- `result` (lexical_declaration, line 154)
- `findings` (lexical_declaration, line 155)
- `known` (lexical_declaration, line 170)
- `absolute` (lexical_declaration, line 177)
- `tree` (lexical_declaration, line 191)
- `declared` (lexical_declaration, line 192, exported)
- `paths` (lexical_declaration, line 193)
- `first` (lexical_declaration, line 196)
- `second` (lexical_declaration, line 208)
- `wanted` (lexical_declaration, line 209)
- `left` (lexical_declaration, line 210)
- `misdirected` (lexical_declaration, line 230)
- `error` (lexical_declaration, line 267)
- `[first]` (lexical_declaration, line 281)
- `astray` (lexical_declaration, line 294)
- `healed` (lexical_declaration, line 308)
- `fired` (lexical_declaration, line 325)
- `clean` (lexical_declaration, line 326)
- `sampled` (lexical_declaration, line 344, exported)

## Uses

- [tools/core/resolvers/taxonomy.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/taxonomy.resolver.ts.md)

## Source

```typescript
import type { BranchFixture, BranchObservation } from "../fixtures/converge.fixture.ts";
import type { GateFixture, Sample } from "../fixtures/gate.fixture.ts";

import type { RuleContext, RuleDeclaration } from "../types/rule.types.ts";
import { existsSync, readFileSync } from "node:fs";
import type { Finding } from "../types/segment.types.ts";
import { growFixtureTree } from "../generators/fixture.generator.ts";
import { loadTaxonomy } from "../resolvers/taxonomy.resolver.ts";
import { resolve } from "node:path";

export const GATE_STATES = ["exempt", "noisy", "proven", "silent", "untested"] as const;

export type GateState = (typeof GATE_STATES)[number];

export interface GateOutcome {
    readonly rule: string;
    readonly state: GateState;
    readonly detail: string;
}

interface Exercise {
    readonly observed: BranchObservation | null;
    readonly error: string;
}

interface Counted {
    readonly findings: readonly Finding[];
    readonly error: string | null;
}

const disagreements = function disagreements(observed: BranchObservation, expected: BranchObservation): string[] {
    const out: string[] = [];
    const keys = new Set([...Object.keys(expected), ...Object.keys(observed)]);

    for (const key of keys) {
        const seen = observed[key];
        const wanted = expected[key];
        if (seen === wanted) {
            continue;
        }
        out.push(`${key} ${String(seen)} where ${String(wanted)} is declared`);
    }

    return out;
};

const rendered = function rendered(observation: BranchObservation): string {
    return Object.entries(observation)
        .map(([key, value]) => `${key} ${String(value)}`)
        .join(" · ");
};

export const unsuppliedReads = function unsuppliedReads(declaration: RuleDeclaration, fixture: GateFixture): string[] {
    if (fixture.exempt !== undefined) {
        return [];
    }
    if (fixture.onDisk === true) {
        return [];
    }

    const declared = declaration.reads ?? [];
    if (declared.length === 0) {
        return [];
    }

    const supplied = new Set<string>();
    for (const sample of [...(fixture.fires ?? []), ...(fixture.passes ?? [])]) {
        supplied.add(sample.path);
    }
    if (supplied.size === 0) {
        return [];
    }

    return declared.filter((path) => !supplied.has(path));
};

const exercise = function exercise(fixture: BranchFixture): Exercise {
    const tree = growFixtureTree(fixture.seed);
    try {
        return { error: "", observed: fixture.exercise(tree.root) };
    } catch (error) {
        return { error: String(error), observed: null };
    } finally {
        tree.release();
    }
};

export const judgeBranch = function judgeBranch(fixture: BranchFixture): GateOutcome {
    const { error, observed } = exercise(fixture);
    if (observed === null) {
        return {
            detail: `the branch threw rather than returning an outcome: ${error}`,
            rule: `${fixture.subject} · ${fixture.branch}`,
            state: "noisy",
        };
    }

    const apart = disagreements(observed, fixture.expect);
    if (apart.length > 0) {
        return {
            detail:
                `the branch was exercised and its effect DISAGREES with what the fixture declares — ${apart.join(", ")}. ` +
                "A branch is proven by its effect on the tree rather than by the code it returns, because a message " +
                "reporting a refusal over a tree it already changed reads exactly like a refusal that changed nothing",
            rule: `${fixture.subject} · ${fixture.branch}`,
            state: "silent",
        };
    }

    return {
        detail: `EXERCISED in an isolated tree · ${rendered(observed)}`,
        rule: `${fixture.subject} · ${fixture.branch}`,
        state: "proven",
    };
};

const contextOf = function contextOf(
    id: string,
    repoRoot: string,
    samples: readonly Sample[],
    declared: readonly string[],
): RuleContext {
    const held = new Map(samples.map((sample): [string, string] => [sample.path, sample.text]));

    for (const wanted of declared.filter((path) => !held.has(path))) {
        const absolute = resolve(repoRoot, wanted);
        if (existsSync(absolute)) {
            held.set(wanted, readFileSync(absolute, "utf8"));
        }
    }

    return {
        exists: (path: string): boolean => held.has(path) || existsSync(resolve(repoRoot, path)),
        id,
        paths: [...held.keys()],
        read: (path: string): string => held.get(path) ?? "",
        repoRoot,
        taxonomy: loadTaxonomy(),
    };
};

const countFindings = function countFindings(
    id: string,
    declaration: RuleDeclaration,
    repoRoot: string,
    samples: readonly Sample[],
    kind: string | undefined,
    onDisk?: true,
): Counted {
    const tree = onDisk === true ? growFixtureTree(samples) : null;
    const wanted = kind === undefined ? null : `${id}/${kind}`;

    try {
        const result = declaration.check(contextOf(id, tree?.root ?? repoRoot, samples, declaration.reads ?? []), false);
        const findings = wanted === null ? result.findings : result.findings.filter((found) => found.rule === wanted);
        return { error: null, findings };
    } catch (error) {
        return { error: String(error), findings: [] };
    } finally {
        tree?.release();
    }
};

const fromDisk = function fromDisk(
    id: string,
    root: string,
    paths: readonly string[],
    declared: readonly string[],
): RuleContext {
    const known = [...new Set([...paths, ...declared])];

    return {
        exists: (path: string): boolean => existsSync(resolve(root, path)),
        id,
        paths: known,
        read: (path: string): string => {
            const absolute = resolve(root, path);
            return existsSync(absolute) ? readFileSync(absolute, "utf8") : "";
        },
        repoRoot: root,
        taxonomy: loadTaxonomy(),
    };
};

const healingOutcome = function healingOutcome(
    id: string,
    declaration: RuleDeclaration,
    fixture: GateFixture,
    samples: readonly Sample[],
): GateOutcome | null {
    const tree = growFixtureTree(samples);
    const declared = declaration.reads ?? [];
    const paths = samples.map((sample) => sample.path);

    try {
        const first = declaration.check(fromDisk(id, tree.root, paths, declared), true);
        if (first.healed.length === 0) {
            return {
                detail:
                    `the healing fixture for ${fixture.kind ?? "any"} healed NOTHING — the rule declares that it heals and ` +
                    "its healing branch produced no repair on a sample built to need one, so the branch is unproven and a " +
                    "run reporting zero healed is indistinguishable from a run whose healer cannot fire",
                rule: id,
                state: "silent",
            };
        }

        const second = declaration.check(fromDisk(id, tree.root, paths, declared), false);
        const wanted = fixture.kind === undefined ? null : `${id}/${fixture.kind}`;
        const left = wanted === null ? second.findings : second.findings.filter((found) => found.rule === wanted);
        if (left.length > 0) {
            return {
                detail:
                    `the healing fixture for ${fixture.kind ?? "any"} healed and the finding SURVIVED its own repair — ` +
                    `${String(left.length)} still stand after healing, so the fix does not converge and a fix that fails ` +
                    "its own check is not a fix",
                rule: id,
                state: "noisy",
            };
        }

        return null;
    } catch (error) {
        return { detail: `the healer threw rather than repairing: ${String(error)}`, rule: id, state: "noisy" };
    } finally {
        tree.release();
    }
};

const misdirected = function misdirected(findings: readonly Finding[]): Finding | null {
    return findings.find((found) => !found.remediation.deterministic && found.remediation.target !== found.path) ?? null;
};

const pathsOf = function pathsOf(samples: readonly Sample[]): string {
    return samples.map((sample) => sample.path).join(", ");
};

const exemptOutcome = function exemptOutcome(id: string, exempt: string, sampled: boolean): GateOutcome {
    return sampled
        ? {
              detail: "the fixture declares an exemption and also declares samples, so the exemption is untested rather than impossible",
              rule: id,
              state: "noisy",
          }
        : { detail: exempt, rule: id, state: "exempt" };
};

const healOnlyOutcome = function healOnlyOutcome(
    id: string,
    declaration: RuleDeclaration,
    fixture: GateFixture,
    heals: readonly Sample[],
): GateOutcome {
    return (
        healingOutcome(id, declaration, fixture, heals) ?? {
            detail:
                `kind ${fixture.kind ?? "any"} · HEALING-ONLY, which is the whole evidence available for a kind that ` +
                `cannot fire with healing OFF: HEALED ${pathsOf(heals)}, and the ` +
                "repair survived its own re-check — the heal is the firing member and the clean re-check is the accepting one",
            rule: id,
            state: "proven",
        }
    );
};

const sampledFailure = function sampledFailure(id: string, fixture: GateFixture, fired: Counted, clean: Counted): GateOutcome | null {
    const error = fired.error ?? clean.error;
    if (error !== null) {
        return { detail: `the rule threw on its fixture rather than reporting: ${error}`, rule: id, state: "noisy" };
    }
    if (fired.findings.length === 0) {
        return {
            detail:
                `the violating fixture for ${fixture.kind ?? "any"} produced no finding, so the rule cannot be ` +
                `shown to fire — samples: ${pathsOf(fixture.fires ?? [])}`,
            rule: id,
            state: "silent",
        };
    }

    const [first] = clean.findings;
    return first === undefined
        ? null
        : {
              detail:
                  `the clean fixture for ${fixture.kind ?? "any"} produced ${String(clean.findings.length)} findings, so the ` +
                  `rule fires on input it must accept — first: ${first.rule} at ${first.path}:${String(first.line)} — ${first.actual}`,
              rule: id,
              state: "noisy",
          };
};

const astrayOutcome = function astrayOutcome(id: string, fired: readonly Finding[]): GateOutcome | null {
    const astray = misdirected(fired);
    return astray === null
        ? null
        : {
              detail:
                  `a judgement finding targets ${astray.remediation.target} while reporting ${astray.path} — ` +
                  "a remediation naming an artifact other than the one in violation offers one branch of a " +
                  "judgement as though it were the answer, and a consumer acts on the target rather than the decide",
              rule: id,
              state: "noisy",
          };
};

const provenOutcome = function provenOutcome(id: string, fixture: GateFixture, fired: number): GateOutcome {
    const healed =
        fixture.heals === undefined ? "" : ` · HEALED ${pathsOf(fixture.heals)} and the repair survived its own re-check`;
    return {
        detail:
            `kind ${fixture.kind ?? "any"} · FIRED ${String(fired)} finding(s) on ${pathsOf(fixture.fires ?? [])}` +
            ` · ACCEPTED ${pathsOf(fixture.passes ?? [])}${healed}`,
        rule: id,
        state: "proven",
    };
};

const sampledOutcome = function sampledOutcome(
    id: string,
    declaration: RuleDeclaration,
    repoRoot: string,
    fixture: GateFixture,
): GateOutcome {
    const fired = countFindings(id, declaration, repoRoot, fixture.fires ?? [], fixture.kind, fixture.onDisk);
    const clean = countFindings(id, declaration, repoRoot, fixture.passes ?? [], fixture.kind, fixture.onDisk);
    const healing = (): GateOutcome | null =>
        fixture.heals === undefined ? null : healingOutcome(id, declaration, fixture, fixture.heals);

    return (
        sampledFailure(id, fixture, fired, clean) ??
        healing() ??
        astrayOutcome(id, fired.findings) ??
        provenOutcome(id, fixture, fired.findings.length)
    );
};

export const judge = function judge(
    id: string,
    declaration: RuleDeclaration,
    repoRoot: string,
    fixture: GateFixture,
): GateOutcome {
    const sampled = (fixture.fires ?? []).length > 0 || (fixture.passes ?? []).length > 0;

    if (fixture.exempt !== undefined) {
        return exemptOutcome(id, fixture.exempt, sampled);
    }
    if (fixture.heals !== undefined && !sampled) {
        return healOnlyOutcome(id, declaration, fixture, fixture.heals);
    }
    return sampledOutcome(id, declaration, repoRoot, fixture);
};
```
