tools/core/resolvers/venue.resolver.ts

tools/core/resolvers/venue.resolver.ts is a file in Coordination Surface. 153 lines of code and 35 definitions.

import type { ClauseLine, SuccessorView } from "../types/converge.types.ts";
import { DEFERRED_SECTION, clauseLines, declaredSuccessor, deferredClauses } from "../analyzers/converge.analyzer.ts";
import { basename, resolve } from "node:path";
import { existsSync, readFileSync } from "node:fs";
import { isResolved, slotText, surfacePath } from "../../../config/surface.config.ts";
import { AGENT_INDEX } from "../constants/board.constants.ts";
import { BLOCKING_SUFFIX } from "../constants/blocking.constants.ts";
import { activeSeats } from "../analyzers/board.analyzer.ts";
import { authorityHeld } from "../strings/venue.strings.ts";
import { textIfPresent } from "../readers/venue.reader.ts";

const INHERITED_HEADING = "INHERITED";

const ROW_MARK = "|";

export const boundAuthority = function boundAuthority(repoRoot: string): string | null {
    if (!isResolved("convention", "venue_authority_concern")) {
        return null;
    }

    const concern = slotText("convention", "venue_authority_concern");
    const index = resolve(repoRoot, AGENT_INDEX);
    if (!existsSync(index)) {
        return null;
    }

    const letter = readFileSync(index, "utf8")
        .split("\n")
        .map((line) => line.trim())
        .filter((trimmed) => trimmed.startsWith(ROW_MARK) && trimmed.includes(concern))
        .map((trimmed) => trimmed.slice(1, trimmed.indexOf(ROW_MARK, 1)).trim())
        .find((cell) => cell.length > 0);
    return letter ?? null;
};

export const seatedLetters = function seatedLetters(repoRoot: string): string[] {
    const board = textIfPresent(resolve(repoRoot, surfacePath("board")));
    const index = textIfPresent(resolve(repoRoot, AGENT_INDEX));
    return [...activeSeats(board, index)].toSorted((left, right) => left.localeCompare(right));
};

export const venueAuthority = function venueAuthority(repoRoot: string): string | null {
    const bound = boundAuthority(repoRoot);
    if (bound === null) {
        return null;
    }

    const seated = seatedLetters(repoRoot);
    if (seated.includes(bound)) {
        return bound;
    }

    return seated[0] ?? bound;
};

export const authorityRefusal = function authorityRefusal(
    repoRoot: string,
    caller: string,
    act: string,
): string | null {
    const holder = venueAuthority(repoRoot);
    if (holder === null || holder === caller) {
        return null;
    }

    const bound = boundAuthority(repoRoot);
    const succeeded = bound !== null && bound !== holder;

    return authorityHeld(act, holder, caller, succeeded ? bound : null);
};

interface StrandedDeferral {
    readonly clause: string;
    readonly receiver: string;
}

export const venueInvariant = function venueInvariant(name: string): string {
    const base = basename(name);
    const stem = base.endsWith(BLOCKING_SUFFIX) ? base.slice(0, base.length - BLOCKING_SUFFIX.length) : base;
    const dot = stem.lastIndexOf(".");
    return dot === -1 ? stem : stem.slice(0, dot);
};

export const addressesSuccessor = function addressesSuccessor(receiver: string, successorName: string): boolean {
    return receiver.length > 0 && successorName.length > 0 && venueInvariant(successorName) === receiver;
};

export const unarrivedDeferrals = function unarrivedDeferrals(
    venue: string,
    successorText: string,
    successorName = "",
): readonly ClauseLine[] {
    return clauseLines(venue, DEFERRED_SECTION)
        .filter((entry) => addressesSuccessor(entry.receiver, successorName))
        .filter((entry) => !successorText.includes(entry.clause));
};

export const unoriginatedInheritance = function unoriginatedInheritance(
    venue: string,
    successorText: string,
): string[] {
    const deferred = clauseLines(venue, DEFERRED_SECTION).map((entry) => entry.clause);
    return clauseLines(successorText, INHERITED_HEADING)
        .map((entry) => entry.clause)
        .filter((clause) => !deferred.some((name) => name.includes(clause) || clause.includes(name)));
};

export const receiverResolves = function receiverResolves(
    receiver: string,
    board: string,
    index: string,
    venueNames: readonly string[],
    planned: readonly string[] = [],
): boolean {
    if (receiver.length === 0) {
        return false;
    }
    if (new Set(activeSeats(board, index)).has(receiver)) {
        return true;
    }
    return venueNames.some((name) => venueInvariant(name) === receiver) || planned.includes(receiver);
};

export const strandedDeferrals = function strandedDeferrals(
    venue: string,
    board: string,
    index: string,
    venueNames: readonly string[],
    planned: readonly string[] = [],
): StrandedDeferral[] {
    return clauseLines(venue, DEFERRED_SECTION)
        .filter(
            (entry) =>
                entry.receiver === entry.clause || !receiverResolves(entry.receiver, board, index, venueNames, planned),
        )
        .map((entry) => ({ clause: entry.clause, receiver: entry.receiver }));
};

const successorOf = function successorOf(target: string): string {
    const stem = target.slice(0, target.length - BLOCKING_SUFFIX.length);
    const dot = stem.lastIndexOf(".");
    const ordinal = dot === -1 ? Number.NaN : Number(stem.slice(dot + 1));
    return Number.isFinite(ordinal) ? `${String(ordinal + 1)}${BLOCKING_SUFFIX}` : "";
};

const successorName = function successorName(target: string, declared: string, siblings: readonly string[]): string {
    const wanted = successorOf(target);
    const matches = (name: string): boolean =>
        declared.length > 0 ? basename(name).startsWith(declared) : name.endsWith(wanted);
    return siblings.find((name) => matches(name) && name !== target) ?? "";
};

export const successorView = function successorView(
    repoRoot: string,
    target: string,
    venue: string,
    siblings: readonly string[],
    planned: readonly string[],
): SuccessorView {
    const declared = declaredSuccessor(venue);
    const successor = successorName(target, declared, siblings);
    const absolute = successor.length === 0 ? "" : resolve(repoRoot, successor);
    const successorText = absolute.length > 0 && existsSync(absolute) ? readFileSync(absolute, "utf8") : "";

    return {
        declared,
        deferred: deferredClauses(venue),
        elsewhere: clauseLines(venue, DEFERRED_SECTION)
            .filter((entry) => successor.length > 0 && !addressesSuccessor(entry.receiver, successor))
            .map((entry) => `${entry.clause} → ${entry.receiver}`),
        scheduled: declared.length > 0 && planned.includes(declared),
        successor,
        successorText,
        unarrived: unarrivedDeferrals(venue, successorText, successor).map((entry) => entry.clause),
    };
};