tools/core/runners/blocking.runner.ts
tools/core/runners/blocking.runner.ts is a file in Coordination Surface. 153 lines of code and 27 definitions.
import { AGENDA, BLOCKING_SUFFIX, LIST_MARKER, RECORD_ABSENT } from "../constants/blocking.constants.ts";
import {
CLAUSE_IS_RECEIVER,
DEFER_NOT_VENUE,
RETRACT_NOT_VENUE,
clauseDeferred,
clauseRetracted,
clauseTaken,
deferVenueMissing,
deferredSectionMissing,
defersAlready,
defersNothing,
markerContended,
receiverUnknown,
retractClauseMissing,
retractSectionMissing,
retractVenueMissing,
} from "../strings/venue.strings.ts";
import { DEFERRAL_ARROW, DEFERRED_SECTION, clauseLines, sectionBound } from "../analyzers/converge.analyzer.ts";
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
import type { RaiseOutcome } from "../types/venue.types.ts";
import { dirname } from "node:path";
import { plannedInvariants } from "../readers/agenda.reader.ts";
import { receiverResolves } from "../resolvers/venue.resolver.ts";
import { surfacePath } from "../../../config/surface.config.ts";
import { surfaceText } from "../readers/venue.reader.ts";
import { venueRefusal } from "../factories/venue.factory.ts";
interface DeferRequest {
readonly repoRoot: string;
readonly target: string;
readonly absolute: string;
readonly clause: string;
readonly receiver: string;
}
const deferNothing = function deferNothing(options: DeferRequest): RaiseOutcome {
const held = readFileSync(options.absolute, "utf8");
const section = sectionBound(held, DEFERRED_SECTION);
if (section === null) {
return venueRefusal(deferredSectionMissing(options.target, DEFERRED_SECTION));
}
const standing = clauseLines(held, DEFERRED_SECTION);
if (standing.length > 0) {
return venueRefusal(defersAlready(options.target, standing.length));
}
const lines = held.split("\n");
const marked = [...lines.slice(0, section.to), `${LIST_MARKER}${RECORD_ABSENT}`, ...lines.slice(section.to)].join(
"\n",
);
const witnessed = readFileSync(options.absolute, "utf8");
if (witnessed !== held) {
return venueRefusal(markerContended(options.target));
}
writeFileSync(options.absolute, marked, "utf8");
return { code: 0, message: defersNothing(options.target), raised: null };
};
const receiverKnown = function receiverKnown(options: DeferRequest): boolean {
const venueNames = readdirSync(dirname(options.absolute), { withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name.endsWith(BLOCKING_SUFFIX))
.map((entry) => entry.name);
const board = surfaceText(options.repoRoot, surfacePath("board"));
const index = surfaceText(options.repoRoot, surfacePath("agent_index"));
const planned = plannedInvariants(surfaceText(options.repoRoot, AGENDA));
return receiverResolves(options.receiver, board, index, venueNames, planned);
};
const deferRefusal = function deferRefusal(options: DeferRequest): RaiseOutcome | null {
if (!options.target.endsWith(BLOCKING_SUFFIX)) {
return venueRefusal(DEFER_NOT_VENUE);
}
if (!existsSync(options.absolute)) {
return venueRefusal(deferVenueMissing(options.target));
}
return null;
};
export const runDefer = function runDefer(options: DeferRequest): RaiseOutcome {
const refused = deferRefusal(options);
if (refused !== null) {
return refused;
}
if (options.clause === RECORD_ABSENT) {
return deferNothing(options);
}
if (options.receiver === options.clause) {
return venueRefusal(CLAUSE_IS_RECEIVER);
}
if (!receiverKnown(options)) {
return venueRefusal(receiverUnknown(options.receiver));
}
const before = readFileSync(options.absolute, "utf8");
const bound = sectionBound(before, DEFERRED_SECTION);
if (bound === null) {
return venueRefusal(deferredSectionMissing(options.target, DEFERRED_SECTION));
}
if (clauseLines(before, DEFERRED_SECTION).some(({ clause }) => clause === options.clause)) {
return venueRefusal(clauseTaken(options.target, options.clause));
}
const lines = before.split("\n");
const listed = lines
.slice(bound.from + 1, Math.min(bound.to, lines.length))
.findLastIndex((line) => line.trim().startsWith(LIST_MARKER));
const at = listed === -1 ? bound.to - 1 : bound.from + 1 + listed;
const deferral = `- ${options.clause} ${DEFERRAL_ARROW} ${options.receiver}`;
const written = [...lines.slice(0, at + 1), deferral, ...lines.slice(at + 1)].join("\n");
const witness = readFileSync(options.absolute, "utf8");
if (witness !== before) {
return venueRefusal(markerContended(options.target));
}
writeFileSync(options.absolute, written, "utf8");
return {
code: 0,
message: clauseDeferred(options.clause, options.receiver, options.target),
raised: options.clause,
};
};
const deferredClauseOf = function deferredClauseOf(line: string): string | null {
const trimmed = line.trim();
if (!trimmed.startsWith(LIST_MARKER)) {
return null;
}
const arrow = trimmed.indexOf(DEFERRAL_ARROW);
return (arrow === -1 ? trimmed.slice(2) : trimmed.slice(2, arrow)).trim();
};
export const runRetract = function runRetract(options: {
readonly target: string;
readonly absolute: string;
readonly clause: string;
}): RaiseOutcome {
if (!options.target.endsWith(BLOCKING_SUFFIX)) {
return venueRefusal(RETRACT_NOT_VENUE);
}
if (!existsSync(options.absolute)) {
return venueRefusal(retractVenueMissing(options.target));
}
const before = readFileSync(options.absolute, "utf8");
const bound = sectionBound(before, DEFERRED_SECTION);
if (bound === null) {
return venueRefusal(retractSectionMissing(options.target, DEFERRED_SECTION));
}
const lines = before.split("\n");
const listed = lines
.slice(bound.from + 1, Math.min(bound.to, lines.length))
.findLastIndex((line) => deferredClauseOf(line) === options.clause);
if (listed === -1) {
return venueRefusal(retractClauseMissing(options.target, options.clause));
}
const at = bound.from + 1 + listed;
const written = [...lines.slice(0, at), ...lines.slice(at + 1)].join("\n");
const witness = readFileSync(options.absolute, "utf8");
if (witness !== before) {
return venueRefusal(markerContended(options.target));
}
writeFileSync(options.absolute, written, "utf8");
return { code: 0, message: clauseRetracted(options.clause, options.target), raised: options.clause };
};