import { ACKNOWLEDGED, EMPTY_EXTRACTION, EXTRACTION_KIND } from "../validators/archive.validator.ts"; import { AGENDA_NEEDS_ESTABLISHES, ANOTHER_EXCLUSIVE, APPEND_NEEDS_LEAD, DEFER_NEEDS_RECEIVER, DISCHARGE_NEEDS_REF, EXTRACT_NEEDS_BODY, FIELD_NEEDS_VALUE, FIXTURE_NEEDS_BODY, MEMBER_NEEDS_BODY, POST_LANDED, REHEARSED, argumentsUnknown, awaitingMark, bodyFileMissing, bodyInline, claimEcho, claimFieldAbsent, claimNoRecord, closableByYou, closureSettled, compressSettled, dischargeContended, dischargeEcho, dischargeNotVenue, dischargeRefUnresolved, dischargeRefUntyped, dischargeSettled, discharged as dischargedMessage, emptyExtractionCheck, exclusiveCombined, fixedTarget, forgedBoundary, kindRequired, openVenuesEcho, operandsMissing, readersOutstanding, stdinEmpty, twinAdmitted, venueFieldAbsent, venueFieldEmpty, venueFieldList, venueNoRecord, venueNoRemoval, venueNoSweep, venueRecordEcho, venueRosterRow, venueTemplateFieldless, venueTemplateUnreadable, venueWritingTo, watchAbsent, watchChanged, watchQuiet, watchRemoved, } from "../strings/board.strings.ts"; import { AGENDA_PLAN, BLOCKING_SUFFIX, VENUE_ARCHIVE, VENUE_TEMPLATE } from "../constants/blocking.constants.ts"; import { AGENT_REQUIRED, waitHelp } from "../strings/invocation.strings.ts"; import { ITEM_KINDS, READ_FIELD, isItemId, stampOf } from "../formatters/board.formatter.ts"; import { type ItemSpan, duplicateTwinOf, itemSpans, openVenues, surfaceEntries } from "../resolvers/sweep.resolver.ts"; import { NOT_READ_FIELD, authorityRefusal, runArrive, runDefer, runInherit, runRaise, runRecord, runRelocate, runRetire, runRetract, runRoster, runSuccessor, } from "../runners/venue.runner.ts"; import { activeSeats, boardRecords } from "../analyzers/board.analyzer.ts"; import { admitWaiter, runBarrier } from "../coordinators/board.coordinator.ts"; import { authorOf, healRequested, runMark, unmarkedReaders } from "../runners/mark.runner.ts"; import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs"; import { filedNotice, runClosure, runEntry, runExtend, runRepair } from "../runners/archive.runner.ts"; import { historyPath, projectRoot, surfacePath, surfacePrefix } from "../../../config/surface.config.ts"; import { letters, runReadMark, runSignature } from "../runners/converge.runner.ts"; import { readFieldMark, readSnapshot, writeFieldMark } from "../registries/snapshot.registry.ts"; import { releaseAgent, releaseWaiter } from "../registries/board.registry.ts"; import { runCompression, runField, runItem } from "../runners/board.runner.ts"; import { runIndex, runTransition } from "../runners/index.runner.ts"; import { unknownArguments, unshareableOperations, unsuppliedOperands, writesNothing, } from "../validators/entrypoint.validator.ts"; import { unreadEcho, unreadSince } from "../resolvers/snapshot.resolver.ts"; import { NO_FIX_FLAG } from "../constants/path.constants.ts"; import { WAIT_COMMAND } from "../constants/board.constants.ts"; import { changesSince } from "../reporters/board.reporter.ts"; import { declaredDistributions } from "../validators/converge.validator.ts"; import { discoverRules } from "../registries/rule.registry.ts"; import { forgedBoundaries } from "../predicates/marker.predicate.ts"; import { resolve } from "node:path"; import { runAgendaRow } from "../runners/agenda.runner.ts"; import { runFixture } from "../runners/fixture.runner.ts"; import { runHalf } from "../runners/conduct.runner.ts"; import { runMember } from "../runners/member.runner.ts"; import { runRole } from "../runners/role.runner.ts"; const RAISE_FORMS: readonly [string, { template: string; root: string; concern: string }][] = [ ["--model", { concern: "model", root: "models", template: "model_template" }], ["--finding", { concern: "finding", root: "findings", template: "finding_template" }], ["--distribute", { concern: "checklist", root: "planning", template: "planning_template" }], ]; export const RESTATES: readonly string[] = [ "a_venue_accumulates_and_the_board_is_swept", "the_handler_removes_the_item", "removal_declares_its_extraction", "a_position_is_posted_through_the_tool", "board_is_current_truth_only", "template_is_the_contract_not_a_copy_of_it", ]; import { runSurfaceRaise } from "../runners/surface.runner.ts"; import { runSweep } from "../runners/sweep.runner.ts"; const EXCLUSIVE_OPERATIONS: readonly string[] = [ "--raise", "--relocate", "--retire", "--inherit", "--roster", "--agenda", "--append", "--repair", "--extract", "--fixture", "--member", "--role", "--half", "--task", "--mark", "--transition", "--index", "--record", "--retract", "--successor", "--defer", "--arrive", "--model", "--finding", "--distribute", "--barrier", ]; const COMPOSABLE_OPERATIONS: readonly string[] = ["--item", "--field", "--read", "--sign", "--closes", "--compress"]; const SELF_REHEARSING: Readonly> = { "--closes": "runs the closure's own refusals, computes the outcome, and reports what WOULD BE removed rather than removing it — so a dry run of this act shows what it would refuse as well as what it would write", "--compress": "resolves the field, takes a witness read, and reports which field WOULD go before any extraction happens, which is the whole reason a party looks before compressing", "--distribute": "reaches its own act and returns rehearsed from inside it, having run every refusal the raise runs", "--finding": "reaches its own act and returns rehearsed from inside it, having run every refusal the raise runs", "--model": "reaches its own act and returns rehearsed from inside it, having run every refusal the raise runs", "--retire": "computes the retirement, its citations and its live set, and reports the outcome under a would-be label rather than moving anything", }; const OPERANDS: readonly string[] = [ "--agent", "--because", "--body", "--body-file", "--discharge", "--establishes", "--establishes-file", "--extracted", "--file", "--help", "--item-file", "--kind", "--lead", "--no-wait", "--observer", "--planned", "--ref", "--seat", "--seats", "--statement", "--to", "--value", ]; const KNOWN_ARGUMENTS: readonly string[] = [ ...EXCLUSIVE_OPERATIONS, ...COMPOSABLE_OPERATIONS, ...OPERANDS, NO_FIX_FLAG, ]; const VENUE_ACTS: readonly (readonly [string, string])[] = [ ["--raise", "raising a successor venue"], ["--relocate", "relocating a venue to the venue root"], ["--retire", "retiring a spent distribution into the planning archive"], ["--inherit", "recomputing a venue's inherited section"], ["--roster", "resolving a venue's roster from the active seats"], ["--defer", "deferring a question out of a venue"], ["--retract", "retracting a deferred question"], ["--arrive", "carrying deferred clauses into a successor"], ["--agenda", "writing a row into the agenda"], ]; import { runTask } from "../runners/task.runner.ts"; import { venueFieldsFrom } from "../validators/venue.validator.ts"; const REPO_ROOT = projectRoot(); const CHANGELOG = historyPath(); const AGENDA = surfacePath("agenda"); const NO_WAIT_FLAG = "--no-wait"; const DEFAULT_TARGET = surfacePath("board"); const SLOT_EXPIRY_MS = 3_600_000; const POLL_MS = 1000; const FLAG_LEAD = "--"; const argumentValue = function argumentValue(flag: string): string | null { const at = process.argv.indexOf(flag); if (at === -1) { return null; } const value = process.argv[at + 1]; if (value === undefined || value.startsWith(FLAG_LEAD)) { return null; } return value; }; const joinedValue = function joinedValue(flag: string): string | null { const at = process.argv.indexOf(flag); if (at === -1) { return null; } const held: string[] = []; for (let index = at + 1; index < process.argv.length; index += 1) { const token = process.argv[index] ?? ""; if (token.startsWith(FLAG_LEAD)) { break; } held.push(token); } return held.length === 0 ? null : held.join(" "); }; const operandTokens = function operandTokens(flag: string): number { const at = process.argv.indexOf(flag); if (at === -1) { return 0; } let held = 0; for (let index = at + 1; index < process.argv.length; index += 1) { if ((process.argv[index] ?? "").startsWith(FLAG_LEAD)) { break; } held += 1; } return held; }; const modifiedAt = function modifiedAt(path: string): number | null { if (!existsSync(path)) { return null; } return statSync(path).mtimeMs; }; const release = function release(id: string): void { releaseWaiter(REPO_ROOT, id, Date.now()); }; const sleep = async function sleep(ms: number): Promise { await new Promise((done) => { setTimeout(done, ms); }); }; const emit = function emit( outcome: { message: string; code: number; excised: readonly string[] }, label: string, ): number { process.stdout.write(outcome.message); for (const excerpt of outcome.excised) { process.stdout.write(` ${label} ${excerpt}\n`); } return outcome.code; }; const siblingSurfaces = function siblingSurfaces(excluding: string): string[] { const out: string[] = []; const board = resolve(REPO_ROOT, DEFAULT_TARGET); if (board !== excluding && existsSync(board)) { out.push(readFileSync(board, "utf8")); } const root = resolve(REPO_ROOT, surfacePrefix()); if (!existsSync(root)) { return out; } for (const entry of readdirSync(root, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith(BLOCKING_SUFFIX)) { continue; } const venue = resolve(root, entry.name); if (venue === excluding) { continue; } out.push(readFileSync(venue, "utf8")); } for (const source of archivedSurfaces()) { out.push(source); } return out; }; const selfRehearsingForms = function selfRehearsingForms(): string[] { return Object.keys(SELF_REHEARSING); }; function archivedSurfaces(): string[] { const out: string[] = []; const root = resolve(REPO_ROOT, surfacePath("venue_archive")); if (!existsSync(root)) { return out; } for (const entry of readdirSync(root, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith(BLOCKING_SUFFIX)) { continue; } out.push(readFileSync(resolve(root, entry.name), "utf8")); } return out; } const resolveTarget = function resolveTarget(named: string): string { if (existsSync(resolve(REPO_ROOT, named))) { return named; } const prefix = surfacePrefix(); const prefixed = prefix.length === 0 ? named : `${prefix}/${named}`; return existsSync(resolve(REPO_ROOT, prefixed)) ? prefixed : named; }; const alreadyGone = function alreadyGone(absolute: string, marker: string): boolean { if (!isItemId(marker)) { return false; } if (!existsSync(absolute)) { return true; } const spans = itemSpans(readFileSync(absolute, "utf8")); return !spans.some((span) => span.key === marker); }; const heldReaders = function heldReaders(absolute: string, closes: string): string[] { if (!existsSync(absolute)) { return []; } const source = readFileSync(absolute, "utf8"); const span = itemSpans(source).find((entry) => entry.key === closes); if (span === undefined) { return []; } const marker = source.split("\n")[span.from] ?? ""; if (!marker.includes(READ_FIELD)) { return []; } const board = resolve(REPO_ROOT, DEFAULT_TARGET); const index = resolve(REPO_ROOT, surfacePath("agent_index")); const bound = existsSync(index) ? readFileSync(index, "utf8") : ""; const active = existsSync(board) ? activeSeats(readFileSync(board, "utf8"), bound) : []; return unmarkedReaders(marker, span.to, active, authorOf(closes)); }; const closure = function closure(target: string, absolute: string, closes: string): number { if (alreadyGone(absolute, closes)) { process.stdout.write(closureSettled(closes, target)); return 0; } const held = heldReaders(absolute, closes); if (held.length > 0) { process.stdout.write(readersOutstanding(closes, held)); return 2; } const ref = argumentValue("--ref"); const outcome = runClosure({ absolute, agent: argumentValue("--agent"), archive: resolve(REPO_ROOT, CHANGELOG), closes, index: resolve(REPO_ROOT, surfacePath("agent_index")), ref, }); if (outcome.refusal !== null) { process.stdout.write(outcome.refusal); return 2; } const heal = healRequested(process.argv, NO_FIX_FLAG); const label = heal ? outcome.label : `would be ${outcome.label}`; if (ref === EMPTY_EXTRACTION) { const archive = resolve(REPO_ROOT, CHANGELOG); process.stdout.write( emptyExtractionCheck(existsSync(archive) ? filedNotice(readFileSync(archive, "utf8")) : ""), ); } if (outcome.acknowledged) { return removal(target, absolute, closes, outcome.author, ACKNOWLEDGED, heal, label); } return removal(target, absolute, closes, outcome.author, ref, heal, label); }; const DIRECTIVES_SECTION = "DIRECTIVES"; const isBoundaryLine = function isBoundaryLine(trimmed: string): boolean { return trimmed.startsWith("#") || trimmed.startsWith("═"); }; const discharge = function discharge(target: string, absolute: string, clause: string): number { if (!target.endsWith(BLOCKING_SUFFIX)) { process.stdout.write(dischargeNotVenue(target)); return 2; } const ref = argumentValue("--ref"); if (ref === null || ref.length === 0) { process.stdout.write(DISCHARGE_NEEDS_REF); return 2; } const separator = ref.indexOf(":"); const kind = separator === -1 ? "" : ref.slice(0, separator).trim(); const member = separator === -1 ? "" : ref.slice(separator + 1).trim(); if (kind !== EXTRACTION_KIND || member.length === 0) { process.stdout.write(dischargeRefUntyped(ref)); return 2; } const archive = resolve(REPO_ROOT, CHANGELOG); if (!existsSync(archive) || !readFileSync(archive, "utf8").includes(member)) { process.stdout.write(dischargeRefUnresolved(ref)); return 2; } const before = readFileSync(absolute, "utf8"); const lines = before.split("\n"); const kept: string[] = []; let inside = false; let removed = 0; let dropping = false; for (const line of lines) { const trimmed = line.trim(); if (isBoundaryLine(trimmed) && trimmed.includes(DIRECTIVES_SECTION)) { inside = true; kept.push(line); continue; } if (inside && isBoundaryLine(trimmed)) { inside = false; } if (inside && trimmed.startsWith("- ") && trimmed.includes(clause)) { removed += 1; dropping = true; continue; } if (dropping) { const continues = line.startsWith(" ") && trimmed.length > 0 && !trimmed.startsWith("- "); if (continues) { continue; } dropping = false; } kept.push(line); } if (removed === 0) { process.stdout.write(dischargeSettled(target, clause)); return 0; } const witness = readFileSync(absolute, "utf8"); if (witness !== before) { process.stdout.write(dischargeContended(target)); return 2; } writeFileSync(absolute, kept.join("\n")); process.stdout.write(dischargedMessage(clause, target, ref)); return 0; }; function removal( target: string, absolute: string, marker: string, agent: string | null, extracted: string | null, heal: boolean, label: string, ): number { return emit( runCompression({ absolute, agent, archive: resolve(REPO_ROOT, CHANGELOG), changelog: CHANGELOG, extracted, heal, marker, target, }), label, ); } const compress = function compress(target: string, absolute: string, marker: string): number { if (alreadyGone(absolute, marker)) { process.stdout.write(compressSettled(marker, target)); return 0; } const heal = healRequested(process.argv, NO_FIX_FLAG); return removal( target, absolute, marker, argumentValue("--agent"), argumentValue("--extracted"), heal, heal ? "removed" : "would remove", ); }; const barrier = function barrier(): void { const outcome = runBarrier(REPO_ROOT, resolve(REPO_ROOT, DEFAULT_TARGET), Date.now()); process.stdout.write(outcome.message); process.exit(outcome.code); }; const deliverSince = function deliverSince(absolute: string, named: string): void { process.stdout.write(changesSince(REPO_ROOT, absolute, argumentValue("--agent") ?? "", named)); }; const ECHOED_FIELDS = ["Status", "Flags"]; const workMovedPast = function workMovedPast(caller: string): boolean { const since = readFieldMark(REPO_ROOT, caller); for (const surface of [DEFAULT_TARGET, ...openVenues(surfaceEntries(REPO_ROOT), VENUE_ARCHIVE, BLOCKING_SUFFIX)]) { const absolute = resolve(REPO_ROOT, surface); if (!existsSync(absolute)) { continue; } const source = readFileSync(absolute, "utf8"); for (const span of itemSpans(source)) { if (authorOf(span.key) !== caller) { continue; } if (stampOf(source.split("\n")[span.from] ?? "") > since) { return true; } } } return false; }; const ownClaimEcho = function ownClaimEcho(caller: string): string { if (!workMovedPast(caller)) { return ""; } const board = resolve(REPO_ROOT, DEFAULT_TARGET); if (!existsSync(board)) { return ""; } const record = boardRecords(readFileSync(board, "utf8")).find( (held) => held.kind === "agent" && held.label.endsWith(` ${caller}`), ); if (record === undefined) { return claimNoRecord(DEFAULT_TARGET, caller); } const lines = ECHOED_FIELDS.map((field) => { const value = record.fields.get(field); if (value === undefined) { return claimFieldAbsent(field); } return ` ${field}: ${value.length > 200 ? `${value.slice(0, 200)}…` : value}`; }); return claimEcho(DEFAULT_TARGET, lines); }; const heldOn = function heldOn(source: string, active: readonly string[], span: ItemSpan): string[] { const marker = source.split("\n")[span.from] ?? ""; if (!marker.includes(READ_FIELD)) { return []; } return unmarkedReaders(marker, span.to, active, authorOf(span.key)); }; const ownDischargeEcho = function ownDischargeEcho(caller: string): string { const board = resolve(REPO_ROOT, DEFAULT_TARGET); if (!existsSync(board)) { return ""; } const source = readFileSync(board, "utf8"); const index = resolve(REPO_ROOT, surfacePath("agent_index")); const bound = existsSync(index) ? readFileSync(index, "utf8") : ""; const active = activeSeats(source, bound); const owed: string[] = []; const closable: string[] = []; for (const span of itemSpans(source)) { if (authorOf(span.key) === caller) { continue; } const named = span.to.length === 0 ? active : span.to; if (!named.includes(caller)) { continue; } const held = heldOn(source, active, span); if (held.includes(caller)) { owed.push(span.key); } else if (held.length === 0) { closable.push(span.key); } } if (owed.length === 0 && closable.length === 0) { return ""; } const lines = [ owed.length === 0 ? "" : awaitingMark(owed), closable.length === 0 ? "" : closableByYou(closable), ].filter((line) => line.length > 0); return dischargeEcho(lines); }; const openVenueEcho = function openVenueEcho(caller: string, target: string): string { const open = openVenues(surfaceEntries(REPO_ROOT), VENUE_ARCHIVE, BLOCKING_SUFFIX); if (open.length === 0) { return ""; } const lines = open.map((venue) => { if (venue === target) { return venueWritingTo(venue); } const source = readFileSync(resolve(REPO_ROOT, venue), "utf8"); const unread = source.split("\n").find((line) => line.trim().startsWith(NOT_READ_FIELD)); const held = unread === undefined ? [] : letters(unread, NOT_READ_FIELD); return venueRosterRow(venue, held.includes(caller)); }); return openVenuesEcho(lines); }; const GATING_FIELDS = ["Needs", "Durable"]; const ownVenueEcho = function ownVenueEcho(caller: string, absolute: string, target: string): string { if (!existsSync(absolute)) { return ""; } const record = boardRecords(readFileSync(absolute, "utf8")).find( (held) => held.kind === "agent" && held.label.endsWith(` ${caller}`), ); if (record === undefined) { return venueNoRecord(target, caller); } const lines = GATING_FIELDS.map((field) => { const value = record.fields.get(field); if (value === undefined) { return venueFieldAbsent(field); } if (value.trim().length === 0) { return venueFieldEmpty(field); } return ` ${field}: ${value.length > 160 ? `${value.slice(0, 160)}…` : value}`; }); return venueRecordEcho(target, lines); }; const venueFieldLine = function venueFieldLine(): string { const template = resolve(REPO_ROOT, VENUE_TEMPLATE); if (!existsSync(template)) { return venueTemplateUnreadable(VENUE_TEMPLATE); } const fields = venueFieldsFrom(readFileSync(template, "utf8")); if (fields.length === 0) { return venueTemplateFieldless(VENUE_TEMPLATE); } return venueFieldList(VENUE_TEMPLATE, fields); }; const help = function help(): void { process.stdout.write(waitHelp(WAIT_COMMAND)); process.stdout.write(venueFieldLine()); process.exit(0); }; const TRAILING = new Set([" ", "\t", "\n", "\r"]); const refuseFixedTarget = function refuseFixedTarget(form: string, surface: string): void { if (!process.argv.includes("--file")) { return; } process.stdout.write(fixedTarget(form, surface)); process.exit(2); }; const STDIN_OPERAND = "-"; const refuseForgedBoundary = function refuseForgedBoundary(body: string, flag: string): void { const forged = forgedBoundaries(body); if (forged.length === 0) { return; } const named = forged.map((entry) => `line ${String(entry.line)}: ${entry.text}`).join("; "); process.stdout.write(forgedBoundary(flag, forged.length, named)); process.exit(2); }; const textOperand = function textOperand(inlineFlag: string, fileFlag: string): string | null { const path = argumentValue(fileFlag); if (path === null) { const inline = joinedValue(inlineFlag); if (inline === null) { return null; } if (inline === STDIN_OPERAND) { const piped = readFileSync(0, "utf8"); if (piped.trim().length === 0) { process.stdout.write(stdinEmpty(inlineFlag, STDIN_OPERAND)); return null; } refuseForgedBoundary(piped, `${inlineFlag} ${STDIN_OPERAND}`); return piped; } process.stdout.write(bodyInline(inlineFlag, fileFlag, STDIN_OPERAND, operandTokens(inlineFlag))); process.exit(2); } const from = resolve(REPO_ROOT, path); if (!existsSync(from)) { process.stdout.write(bodyFileMissing(fileFlag, path)); process.exit(2); } const raw = readFileSync(from, "utf8"); let end = raw.length; while (end > 0 && TRAILING.has(raw.charAt(end - 1))) { end -= 1; } const body = raw.slice(0, end); refuseForgedBoundary(body, fileFlag); return body; }; const main = async function main(): Promise { const named = argumentValue("--file") ?? DEFAULT_TARGET; const target = resolveTarget(named); const absolute = resolve(REPO_ROOT, target); if (process.argv.includes("--help")) { help(); } const caller = argumentValue("--agent"); if (caller === null) { process.stdout.write(AGENT_REQUIRED); process.exit(2); } const unknown = unknownArguments(process.argv.slice(2), KNOWN_ARGUMENTS); if (unknown.length > 0) { process.stdout.write(argumentsUnknown(unknown, KNOWN_ARGUMENTS)); process.exit(2); } releaseAgent(REPO_ROOT, caller, Date.now()); const requestedFlags = [...EXCLUSIVE_OPERATIONS, ...COMPOSABLE_OPERATIONS].filter((flag) => process.argv.includes(flag), ); const exclusive = unshareableOperations(requestedFlags, EXCLUSIVE_OPERATIONS); if (exclusive.length > 0) { process.stdout.write( exclusiveCombined( exclusive, requestedFlags.filter((flag) => !exclusive.includes(flag)).join(", ") || ANOTHER_EXCLUSIVE, ), ); process.exit(2); } if (process.argv.includes("--barrier")) { barrier(); } for (const [flag, act] of VENUE_ACTS) { if (!process.argv.includes(flag)) { continue; } const refused = authorityRefusal(REPO_ROOT, caller, act); if (refused === null) { break; } process.stdout.write(refused); process.exit(2); } if (writesNothing(process.argv, NO_FIX_FLAG, selfRehearsingForms())) { process.stdout.write(REHEARSED); process.exit(0); } if (process.argv.includes("--raise")) { const named = joinedValue("--seats") ?? ""; const seats = named .split(",") .flatMap((part) => part.split(" ")) .map((part) => part.trim()) .filter((part) => part.length > 0); const outcome = runRaise({ declared: argumentValue("--raise"), repoRoot: REPO_ROOT, seats }); process.stdout.write(outcome.message); process.exit(outcome.code); } const relocated = argumentValue("--relocate"); if (relocated !== null) { const outcome = runRelocate({ name: relocated, repoRoot: REPO_ROOT }); process.stdout.write(outcome.message); process.exit(outcome.code); } const retired = argumentValue("--retire"); if (retired !== null) { const planning = surfacePath("planning"); const declared = declaredDistributions([`${planning}/${retired}`], (target) => existsSync(resolve(REPO_ROOT, target)) ? readFileSync(resolve(REPO_ROOT, target), "utf8") : "", ); const frozen = resolve(REPO_ROOT, surfacePath("archive")); const citedBy = existsSync(frozen) ? readdirSync(frozen, { encoding: "utf8", recursive: true }) .map((entry) => resolve(frozen, entry)) .filter((entry) => statSync(entry).isFile()) .filter((entry) => readFileSync(entry, "utf8").includes(`${planning}/${retired}`)) : []; const outcome = runRetire({ citedBy, declares: declared[0]?.declares ?? "", heal: healRequested(process.argv, NO_FIX_FLAG), live: openVenues(surfaceEntries(REPO_ROOT), VENUE_ARCHIVE, BLOCKING_SUFFIX), name: retired, repoRoot: REPO_ROOT, }); process.stdout.write(outcome.message); process.exit(outcome.code); } const roster = argumentValue("--roster"); if (roster !== null) { const outcome = runRoster({ name: roster, repoRoot: REPO_ROOT }); process.stdout.write(outcome.message); process.exit(outcome.code); } const inherits = argumentValue("--inherit"); if (inherits !== null) { const outcome = runInherit({ name: inherits, repoRoot: REPO_ROOT }); process.stdout.write(outcome.message); process.exit(outcome.code); } const invariant = argumentValue("--agenda"); if (invariant !== null) { refuseFixedTarget("--agenda", AGENDA); const establishes = textOperand("--establishes", "--establishes-file"); if (establishes === null) { process.stdout.write(AGENDA_NEEDS_ESTABLISHES); process.exit(2); } const outcome = runAgendaRow({ establishes, invariant, note: joinedValue("--because") ?? "", ordinal: argumentValue("--planned") ?? "—", plan: resolve(REPO_ROOT, AGENDA_PLAN), }); process.stdout.write(outcome.message); process.exit(outcome.code); } const extend = argumentValue("--append"); if (extend !== null) { refuseFixedTarget("--append", CHANGELOG); const lead = argumentValue("--lead"); const body = textOperand("--body", "--body-file"); if (lead === null || body === null) { process.stdout.write(APPEND_NEEDS_LEAD); process.exit(2); } const outcome = runExtend({ archive: resolve(REPO_ROOT, CHANGELOG), body, heading: extend, lead }); process.stdout.write(outcome.message); process.exit(outcome.code); } const repaired = argumentValue("--repair"); if (repaired !== null) { refuseFixedTarget("--repair", CHANGELOG); const outcome = runRepair({ archive: resolve(REPO_ROOT, CHANGELOG), heading: repaired }); process.stdout.write(outcome.message); process.exit(outcome.code); } const heading = argumentValue("--extract"); if (heading !== null) { refuseFixedTarget("--extract", CHANGELOG); const body = textOperand("--body", "--body-file"); if (body === null) { process.stdout.write(EXTRACT_NEEDS_BODY); process.exit(2); } const outcome = runEntry({ archive: resolve(REPO_ROOT, CHANGELOG), body, heading }); process.stdout.write(outcome.message); process.exit(outcome.code); } const pair = argumentValue("--fixture"); if (pair !== null) { const body = textOperand("--body", "--body-file"); if (body === null) { process.stdout.write(FIXTURE_NEEDS_BODY); process.exit(2); } const outcome = runFixture({ absolute, body, pair, target, witness: existsSync(absolute) ? readFileSync(absolute, "utf8") : "", }); process.stdout.write(outcome.message); process.exit(outcome.code); } const member = argumentValue("--member"); if (member !== null) { const body = textOperand("--body", "--body-file"); if (body === null) { process.stdout.write(MEMBER_NEEDS_BODY); process.exit(2); } const outcome = runMember({ absolute, body, heading: member, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const concern = joinedValue("--role"); if (concern !== null) { refuseFixedTarget("--role", surfacePath("roles")); const outcome = runRole({ absolute: resolve(REPO_ROOT, `${surfacePath("roles")}/${concern.trim()}.${caller.toLowerCase()}.role.md`), concern: concern.trim(), letter: caller, template: resolve(REPO_ROOT, surfacePath("role_template")), }); process.stdout.write(outcome.message); process.exit(outcome.code); } for (const [flag, slots] of RAISE_FORMS) { const subject = joinedValue(flag); if (subject === null) { continue; } refuseFixedTarget(flag, surfacePath(slots.root)); const outcome = runSurfaceRaise({ concern: slots.concern, rehearse: !healRequested(process.argv, NO_FIX_FLAG), repoRoot: REPO_ROOT, rootSlot: slots.root, subject, templateSlot: slots.template, }); process.stdout.write(outcome.message); process.exit(outcome.code); } const half = argumentValue("--half"); if (half !== null) { refuseFixedTarget("--half", surfacePath("conduct_roster")); const registry = await discoverRules(REPO_ROOT); const outcome = runHalf({ registered: registry.rules.map((entry) => entry.id), repoRoot: REPO_ROOT, slug: half, target: surfacePath("conduct_roster"), value: argumentValue("--observer") ?? "", }); process.stdout.write(outcome.message); process.exit(outcome.code); } const task = argumentValue("--task"); if (task !== null) { const outcome = runTask({ id: task, owner: caller, repoRoot: REPO_ROOT, statement: joinedValue("--statement") ?? "", target, }); process.stdout.write(outcome.message); process.exit(outcome.code); } const marked = argumentValue("--mark"); if (marked !== null) { const outcome = runMark({ absolute, agent: caller, item: marked, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const transition = argumentValue("--transition"); if (transition !== null) { refuseFixedTarget("--transition", surfacePath("agent_index")); const outcome = runTransition({ absolute: resolve(REPO_ROOT, surfacePath("agent_index")), by: caller, letter: argumentValue("--seat") ?? caller, state: transition, warrant: argumentValue("--ref"), }); process.stdout.write(outcome.message); process.exit(outcome.code); } const indexed = joinedValue("--index"); if (indexed !== null) { refuseFixedTarget("--index", surfacePath("agent_index")); const outcome = runIndex({ absolute: resolve(REPO_ROOT, surfacePath("agent_index")), role: indexed }); process.stdout.write(outcome.message); process.exit(outcome.code); } if (process.argv.includes("--record")) { const outcome = runRecord({ absolute, agent: caller, repoRoot: REPO_ROOT, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const retract = argumentValue("--retract"); if (retract !== null) { const outcome = runRetract({ absolute, clause: retract, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const successor = argumentValue("--successor"); if (successor !== null) { const outcome = runSuccessor({ absolute, invariant: successor, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const defer = argumentValue("--defer"); if (defer !== null) { const to = argumentValue("--to"); if (to === null) { process.stdout.write(DEFER_NEEDS_RECEIVER); process.exit(2); } const outcome = runDefer({ absolute, clause: defer, receiver: to, repoRoot: REPO_ROOT, target }); process.stdout.write(outcome.message); process.exit(outcome.code); } if (process.argv.includes("--arrive")) { const outcome = runArrive({ absolute, predecessor: target }); process.stdout.write(outcome.message); process.exit(outcome.code); } const item = textOperand("--item", "--item-file"); const kind = argumentValue("--kind"); const unsupplied = unsuppliedOperands([ { operation: "--item", refusal: kindRequired(ITEM_KINDS), requested: item !== null, supplied: kind !== null && ITEM_KINDS.includes(kind), }, { operation: "--field", refusal: FIELD_NEEDS_VALUE, requested: argumentValue("--field") !== null, supplied: joinedValue("--value") !== null, }, ]); if (unsupplied.length > 0) { process.stdout.write(operandsMissing(unsupplied)); process.exit(2); } if (item !== null && kind !== null) { const unread = existsSync(absolute) ? unreadSince(readFileSync(absolute, "utf8"), readSnapshot(REPO_ROOT, caller, target), caller) : null; const outcome = runItem({ absolute, agent: caller, archive: resolve(REPO_ROOT, CHANGELOG), at: Date.now(), kind, repoRoot: REPO_ROOT, siblings: siblingSurfaces(absolute), target, text: item, }); process.stdout.write(outcome.message); if (outcome.code !== 0) { process.exit(outcome.code); } process.stdout.write(unreadEcho(unread, target)); process.stdout.write(ownClaimEcho(caller)); process.stdout.write(ownDischargeEcho(caller)); process.stdout.write(openVenueEcho(caller, target)); if (target.endsWith(BLOCKING_SUFFIX)) { process.stdout.write(ownVenueEcho(caller, absolute, target)); } } const field = argumentValue("--field"); const value = joinedValue("--value"); if (field !== null && value !== null) { const outcome = runField({ absolute, agent: caller, field, target, text: value }); process.stdout.write(outcome.message); if (outcome.code !== 0) { process.exit(outcome.code); } writeFieldMark(REPO_ROOT, caller, Date.now()); } if (process.argv.includes("--read")) { const outcome = runReadMark({ absolute, agent: caller, target, text: "" }); process.stdout.write(outcome.message); if (outcome.code !== 0) { process.exit(outcome.code); } } const signature = joinedValue("--sign"); if (signature !== null) { const outcome = runSignature({ absolute, agent: caller, target, text: signature }); process.stdout.write(outcome.message); if (outcome.code !== 0) { process.exit(outcome.code); } } let tidy = 0; const venue = target.endsWith(BLOCKING_SUFFIX); const marker = argumentValue("--compress"); const closes = argumentValue("--closes"); const twin = venue && closes !== null && existsSync(absolute) ? duplicateTwinOf(readFileSync(absolute, "utf8"), closes) : null; if (venue && closes !== null && twin !== null) { process.stdout.write(twinAdmitted(closes, twin)); } if (venue && (marker !== null || (closes !== null && twin === null))) { process.stdout.write(venueNoRemoval(target)); process.exit(2); } const discharged = argumentValue("--discharge"); if (discharged !== null) { tidy = discharge(target, absolute, discharged) || tidy; } if (marker !== null) { tidy = compress(target, absolute, marker); } if (closes !== null) { tidy = closure(target, absolute, closes) || tidy; } if (target.endsWith(BLOCKING_SUFFIX)) { process.stdout.write(venueNoSweep(target)); } else { process.stdout.write(runSweep(REPO_ROOT, absolute, CHANGELOG).message); } if (tidy !== 0 && item === null) { process.exit(tidy); } if (tidy !== 0) { process.stdout.write(POST_LANDED); } if (process.argv.includes(NO_WAIT_FLAG)) { deliverSince(absolute, target); process.exit(0); } const timeout = SLOT_EXPIRY_MS; const baseline = modifiedAt(absolute); if (baseline === null) { process.stdout.write(watchAbsent(target)); process.exit(2); } const now = Date.now(); const admission = admitWaiter(REPO_ROOT, resolve(REPO_ROOT, DEFAULT_TARGET), { agent: caller, now, pid: process.pid, target, timeout, }); process.stdout.write(admission.message); if (admission.code !== 0) { process.exit(admission.code); } const { id } = admission; const deadline = now + timeout; while (Date.now() < deadline) { await sleep(POLL_MS); const current = modifiedAt(absolute); if (current === null) { release(id); process.stdout.write(watchRemoved(target)); process.exit(2); } if (current !== baseline) { release(id); const waited = Math.round((timeout - (deadline - Date.now())) / 1000); process.stdout.write(watchChanged(target, waited)); deliverSince(absolute, target); process.exit(0); } } release(id); process.stdout.write(watchQuiet(target)); deliverSince(absolute, target); process.exit(1); }; await main();