# tools/rules/board.rule.ts

> 283 lines of code and 48 definitions.

Tree: Coordination tree
Language: typescript
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-rules-board-rule-ts
Source text: https://banes-lab.com/assets/sources/source.282c8f0b307febc833b5346500610d0af14f3f4588f8b2312d87c2fa20c8e191.generated.txt

## Definitions

- `surfaceFindings` (lexical_declaration, line 225)
- `recordFindings` (lexical_declaration, line 211)
- `checkDuplicateFields` (lexical_declaration, line 81)
- `checkMarkers` (lexical_declaration, line 109)
- `delimiterFindings` (lexical_declaration, line 147)
- `checkDelimiters` (lexical_declaration, line 179)
- `fieldCounts` (lexical_declaration, line 70)
- `check` (method_definition, line 244, exported)
- `driftOutcome` (lexical_declaration, line 184)
- `projectionFindings` (lexical_declaration, line 203)
- `NO_DRIFT` (lexical_declaration, line 39)
- `DRIFT_HEALED` (lexical_declaration, line 41)
- `DRIFT_STANDING` (lexical_declaration, line 47)
- `PROJECTION_ABSENT` (lexical_declaration, line 51)
- `Fence` (interface_declaration, line 54)
- `DriftOutcome` (interface_declaration, line 59)
- `indexOf` (lexical_declaration, line 66)
- `seen` (lexical_declaration, line 71)
- `field` (lexical_declaration, line 73)
- `lines` (lexical_declaration, line 82)
- `required` (lexical_declaration, line 85)
- `end` (lexical_declaration, line 86)
- `leadingValue` (lexical_declaration, line 103)
- `colon` (lexical_declaration, line 104)
- `value` (lexical_declaration, line 105)
- `first` (lexical_declaration, line 111)
- `fenceOf` (lexical_declaration, line 126)
- `opens` (lexical_declaration, line 127)
- `closes` (lexical_declaration, line 128)
- `[open]` (lexical_declaration, line 129)
- `[close]` (lexical_declaration, line 130)
- `intruderIn` (lexical_declaration, line 138)
- `foreign` (lexical_declaration, line 143)
- `agent` (lexical_declaration, line 148)
- `fence` (lexical_declaration, line 149)
- `intruder` (lexical_declaration, line 164)
- `markers` (lexical_declaration, line 180)
- `drifts` (lexical_declaration, line 190)
- `applied` (lexical_declaration, line 195)
- `host` (lexical_declaration, line 207)
- `index` (lexical_declaration, line 216)
- `peers` (lexical_declaration, line 217)
- `rule` (lexical_declaration, line 243, exported)
- `source` (lexical_declaration, line 253, exported)
- `records` (lexical_declaration, line 254, exported)
- `drift` (lexical_declaration, line 255, exported)
- `venues` (lexical_declaration, line 256, exported)
- `projection` (lexical_declaration, line 259, exported)

## Uses

- [tools/core/analyzers/marker.analyzer.ts](https://banes-lab.com/source/coordination/tools/core/analyzers/marker.analyzer.ts.md)
- [tools/core/inspectors/board.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/board.inspector.ts.md)
- [tools/core/inspectors/projection.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/projection.inspector.ts.md)
- [tools/core/inspectors/report.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/report.inspector.ts.md)
- [tools/core/validators/board.validator.ts](https://banes-lab.com/source/coordination/tools/core/validators/board.validator.ts.md)

## Source

```typescript
import {
    AGENT_FIELDS,
    AGENT_INDEX,
    BOARD_PATH,
    COMMS_TEMPLATE,
    GATE_FIELDS,
    PROJECTION_HOST,
    STALE_MARKERS,
} from "../core/constants/board.constants.ts";
import { BLOCKING_SUFFIX, VENUE_ARCHIVE } from "../core/constants/blocking.constants.ts";
import type { BoardRecord, Delimiter } from "../core/analyzers/board.analyzer.ts";
import type { RuleContext, RuleDeclaration, RuleResult } from "../core/types/rule.types.ts";
import {
    boardFinding,
    checkAddressees,
    checkRecord,
    checkStateDrift,
    healStateDrift,
    peerSet,
    stateDrift,
} from "../core/validators/board.validator.ts";
import { boardRecords, delimitersIn } from "../core/analyzers/board.analyzer.ts";
import {
    checkIndex,
    checkItemAddressing,
    checkItemFences,
    checkItemLetters,
    checkReadable,
    checkTemplateDrift,
    letterOfLabel,
} from "../core/inspectors/board.inspector.ts";
import type { Finding } from "../core/types/segment.types.ts";
import type { StateDrift } from "../core/validators/board.validator.ts";
import { carriesMarker } from "../core/analyzers/marker.analyzer.ts";
import { checkGateState } from "../core/inspectors/report.inspector.ts";
import { checkProjection } from "../core/inspectors/projection.inspector.ts";
import { writeBoardIfUnmoved } from "../core/generators/board.generator.ts";

const NO_DRIFT = "none — no record's marker disagrees with its binding";

const DRIFT_HEALED =
    "HEALED IN THIS RUN — the markers below are what the walk MEASURED before it wrote, retained because " +
    "the heal is a comparison and the earlier state is its operand. They are not a live disagreement, " +
    "and reading them as current state is the reading a derivation invites, which is why the " +
    "disposition sits beside them rather than being inferred from an empty findings list";

const DRIFT_STANDING =
    "STANDING — the markers below disagree with their bindings and this run did not write, so each is " +
    "reported as a finding";

const PROJECTION_ABSENT =
    "ABSENT — no governance document is declared, so the branch that checks the projection does not run";

interface Fence {
    readonly open: number;
    readonly close: number;
}

interface DriftOutcome {
    readonly disposition: string;
    readonly drifts: readonly StateDrift[];
    readonly findings: readonly Finding[];
    readonly healed: readonly string[];
}

const indexOf = function indexOf(context: RuleContext): string {
    return context.exists(AGENT_INDEX) ? context.read(AGENT_INDEX) : "";
};

const fieldCounts = function fieldCounts(lines: readonly string[], required: readonly string[]): Map<string, number> {
    const seen = new Map<string, number>();
    for (const line of lines) {
        const field = required.find((each) => line.startsWith(`  ${each}:`));
        if (field !== undefined) {
            seen.set(field, (seen.get(field) ?? 0) + 1);
        }
    }
    return seen;
};

const checkDuplicateFields = function checkDuplicateFields(source: string, records: readonly BoardRecord[]): Finding[] {
    const lines = source.split("\n");

    return records.flatMap((record, index) => {
        const required = record.kind === "agent" ? AGENT_FIELDS : GATE_FIELDS;
        const end = records[index + 1]?.line ?? lines.length + 1;

        return [...fieldCounts(lines.slice(record.line, end - 1), required)]
            .filter(([, count]) => count > 1)
            .map(([field, count]) =>
                boardFinding(
                    "duplicateField",
                    record.line,
                    record.label,
                    `${record.label} declares ${field} ${String(count)} times`,
                    `${record.label} declares ${field} once`,
                    "a record carries exactly its fixed schema, and a field parsed into a map collapses its duplicates into one entry — so a second declaration of the same field is invisible to every check that reads the parsed record, while a reader sees two fields disagreeing about one thing",
                ),
            );
    });
};

const leadingValue = function leadingValue(line: string): string {
    const colon = line.indexOf(":");
    const value = colon === -1 ? line.trim() : line.slice(colon + 1).trim();
    return value.split(" ")[0] ?? "";
};

const checkMarkers = function checkMarkers(source: string): Finding[] {
    return source.split("\n").flatMap((line, index) => {
        const first = leadingValue(line);

        return STALE_MARKERS.filter((marker) => first === marker && carriesMarker(line, marker)).map((marker) =>
            boardFinding(
                "staleMarker",
                index + 1,
                marker,
                `the board carries the marker ${marker}`,
                "current truth only",
                "the board is overwritten in place; a resolved flag or completed unit is deleted outright, because a stale record manufactures a false belief in every agent that reads it",
            ),
        );
    });
};

const fenceOf = function fenceOf(markers: readonly Delimiter[], agent: string, line: number): Fence | null {
    const opens = markers.filter((mark) => mark.open && mark.agent === agent);
    const closes = markers.filter((mark) => !mark.open && mark.agent === agent);
    const [open] = opens;
    const [close] = closes;

    if (opens.length !== 1 || closes.length !== 1 || open === undefined || close === undefined) {
        return null;
    }
    return open.line < line && close.line > line ? { close: close.line, open: open.line } : null;
};

const intruderIn = function intruderIn(
    markers: readonly Delimiter[],
    agent: string,
    fence: Fence,
): Delimiter | undefined {
    const foreign = markers.filter((mark) => mark.agent !== agent && !mark.agent.startsWith(`${agent}-`));
    return foreign.find((mark) => mark.line > fence.open && mark.line < fence.close);
};

const delimiterFindings = function delimiterFindings(record: BoardRecord, markers: readonly Delimiter[]): Finding[] {
    const agent = letterOfLabel(record.label);
    const fence = fenceOf(markers, agent, record.line);

    if (fence === null) {
        return [
            boardFinding(
                "undelimitedRecord",
                record.line,
                record.label,
                `${record.label} is not enclosed by a matched delimiter pair`,
                `┌─── AGENT ${agent} above the record and └─── END AGENT ${agent} below it`,
                "an undelimited record has no anchor unique to its own writer, so a neighbor revising their block has nothing to edit against and reaches for a whole-file write instead — which succeeds, reports success to the one who overwrote, and says nothing to the one overwritten",
            ),
        ];
    }

    const intruder = intruderIn(markers, agent, fence);
    return intruder === undefined
        ? []
        : [
              boardFinding(
                  "interleavedRecord",
                  intruder.line,
                  record.label,
                  `a delimiter for ${intruder.agent} falls inside the fence of ${record.label}`,
                  `every marker between lines ${String(fence.open)} and ${String(fence.close)} belongs to ${agent}`,
                  "a fence that encloses another agent's fence passes the pair check while defeating its purpose: an edit anchored on the outer fence spans the inner agent's content, which is exactly the destruction the fence exists to prevent, and both records read as correctly delimited while one sits inside the other",
              ),
          ];
};

const checkDelimiters = function checkDelimiters(source: string, records: readonly BoardRecord[]): Finding[] {
    const markers = delimitersIn(source);
    return records.filter((record) => record.kind === "agent").flatMap((record) => delimiterFindings(record, markers));
};

const driftOutcome = function driftOutcome(
    context: RuleContext,
    fix: boolean,
    source: string,
    records: readonly BoardRecord[],
): DriftOutcome {
    const drifts = stateDrift(records, indexOf(context));
    if (drifts.length === 0) {
        return { disposition: NO_DRIFT, drifts, findings: [], healed: [] };
    }

    const applied = fix && writeBoardIfUnmoved(context.repoRoot, source, healStateDrift(source, drifts));
    if (applied) {
        return { disposition: DRIFT_HEALED, drifts, findings: [], healed: [BOARD_PATH] };
    }

    return { disposition: DRIFT_STANDING, drifts, findings: checkStateDrift(drifts), healed: [] };
};

const projectionFindings = function projectionFindings(
    context: RuleContext,
    venues: readonly string[],
): Finding[] | null {
    const host = PROJECTION_HOST;
    return host === null || !context.exists(host) ? null : checkProjection(context.read(host), venues);
};

const recordFindings = function recordFindings(
    context: RuleContext,
    source: string,
    records: readonly BoardRecord[],
): Finding[] {
    const index = indexOf(context);
    const peers = peerSet(records, index);
    return [
        ...records.flatMap((record) => checkRecord(record, peers)),
        ...checkAddressees(source, index),
        ...checkGateState(source, context.repoRoot),
    ];
};

const surfaceFindings = function surfaceFindings(
    context: RuleContext,
    source: string,
    records: readonly BoardRecord[],
): Finding[] {
    return [
        ...checkDelimiters(source, records),
        ...checkMarkers(source),
        ...checkReadable(source),
        ...checkDuplicateFields(source, records),
        ...checkItemFences(source),
        ...checkItemLetters(source),
        ...checkItemAddressing(source),
        ...(context.exists(AGENT_INDEX) ? checkIndex(records, context.read(AGENT_INDEX)) : []),
        ...(context.exists(COMMS_TEMPLATE) ? checkTemplateDrift(context.read(COMMS_TEMPLATE)) : []),
    ];
};

export const rule: RuleDeclaration = {
    check(context: RuleContext, fix: boolean): RuleResult {
        if (!context.paths.includes(BOARD_PATH)) {
            return {
                derivations: { board: "absent from this run's path set", skippedAsOutOfScope: [BOARD_PATH] },
                findings: [],
                healed: [],
            };
        }

        const source = context.read(BOARD_PATH);
        const records = boardRecords(source);
        const drift = driftOutcome(context, fix, source, records);
        const venues = context.paths
            .filter((path) => path.endsWith(BLOCKING_SUFFIX))
            .filter((path) => !path.startsWith(VENUE_ARCHIVE));
        const projection = projectionFindings(context, venues);

        return {
            derivations: {
                board: "present",
                projection: projection === null ? PROJECTION_ABSENT : "checked",
                recordsWalked: records.map((record) => record.label),
                stateDrift: drift.drifts.map((each) => `${each.letter}: ${each.marker} here, ${each.bound} bound`),
                stateDriftDisposition: drift.disposition,
                venuesSeen: venues,
            },
            findings: [
                ...drift.findings,
                ...(projection ?? []),
                ...recordFindings(context, source, records),
                ...surfaceFindings(context, source, records),
            ],
            healed: [...drift.healed],
        };
    },
    extensions: [],
    heals: true,
    invariant: "the coordination board carries current truth in exactly its declared schema",
    jurisdiction: "all",
    kinds: [
        "badState",
        "danglingAddressee",
        "danglingAnswer",
        "derivedStateDrift",
        "duplicateField",
        "duplicateIndexBinding",
        "extraField",
        "foreignItemLetter",
        "interleavedRecord",
        "malformedItemFence",
        "missingField",
        "oversizedProjection",
        "phantomProjection",
        "repeatedClaim",
        "selfAnswer",
        "staleGateState",
        "staleMarker",
        "templateDrift",
        "undelimitedRecord",
        "unindexedAgent",
        "unreadableField",
        "unresolvedAddressing",
        "unstampedItem",
    ],

    reads:
        PROJECTION_HOST === null
            ? [BOARD_PATH, AGENT_INDEX, COMMS_TEMPLATE]
            : [BOARD_PATH, PROJECTION_HOST, AGENT_INDEX, COMMS_TEMPLATE],

    stage: "content",
};
```
