import { currentWaiters, writeWaiters } from "../registries/board.registry.ts"; import { existsSync, readFileSync } from "node:fs"; import { isResolved, slotCount, surfacePath } from "../../../config/surface.config.ts"; import { waitAllParked, waitSolitary, watching } from "../strings/board.strings.ts"; import { activeSeats } from "../analyzers/board.analyzer.ts"; import { barrierState } from "../runners/board.runner.ts"; import { heldClaims } from "../registries/claim.registry.ts"; import { lastInteraction } from "../registries/snapshot.registry.ts"; import { resolve } from "node:path"; export interface Admission { readonly id: string; readonly message: string; readonly code: number; } const livenessWindow = function livenessWindow(): number | null { if (!isResolved("convention", "run_live_window_ms")) { return null; } return slotCount("convention", "run_live_window_ms"); }; export const writingSeats = function writingSeats( repoRoot: string, seats: readonly string[], parked: readonly string[], now: number, ): string[] { const window = livenessWindow(); if (window === null) { return [...seats]; } const held = new Set(parked); const running = new Set(heldClaims(repoRoot).map((claim) => claim.agent)); return seats.filter((seat) => { if (held.has(seat)) { return true; } if (running.has(seat)) { return true; } const stamped = lastInteraction(repoRoot, seat); return stamped > 0 && now - stamped < window; }); }; const rosterOf = function rosterOf(repoRoot: string, board: string, parked: readonly string[], now: number): number { if (!existsSync(board)) { return 0; } const index = resolve(repoRoot, surfacePath("agent_index")); const seated = activeSeats(readFileSync(board, "utf8"), existsSync(index) ? readFileSync(index, "utf8") : ""); return writingSeats(repoRoot, seated, parked, now).length; }; export const runBarrier = function runBarrier( repoRoot: string, board: string, now: number, ): { message: string; code: number } { const waiting = currentWaiters(repoRoot, now); return barrierState( rosterOf( repoRoot, board, waiting.map((entry) => entry.agent), now, ), waiting.length, ); }; export const admitWaiter = function admitWaiter( repoRoot: string, board: string, request: { agent: string; target: string; timeout: number; now: number; pid: number }, ): Admission { const waiting = currentWaiters(repoRoot, request.now); const agents = rosterOf( repoRoot, board, waiting.map((entry) => entry.agent), request.now, ); if (agents > 0 && waiting.length >= agents - 1) { const solitary = waiting.length === 0; return { code: 3, id: "", message: solitary ? waitSolitary(agents, waiting.length) : waitAllParked(agents, waiting.length), }; } const id = `${String(request.pid)}-${String(request.now)}`; writeWaiters(repoRoot, [...waiting, { agent: request.agent, expiresAt: request.now + request.timeout, id }]); return { code: 0, id, message: watching(request.target, Math.round(request.timeout / 1000), waiting.length + 1, agents), }; };