/* * Phase 5.1 Task 11 — CLOSE THE LOOP: answer a capability question by * EXERCISING the capability, in the process that would serve it. * * 11.1: NO TIMESTAMP ON THIS BOX CAN ANSWER A CAPABILITY QUESTION. Every * artefact people reach for is a proxy that fails differently: * * an mtime tracks WRITES. A reinstall of byte-identical code moves * it, and an edit that never got built does not. * serverBuildMtime is stamped at ATTACH, so it tells you when a transport * started, not what the running process contains. * a version string is a LABEL someone typed into package.json. Measured * today: a tarball published as 0.5.23 contained a change * the version numbering said it could not, and the number * was believed over the artefact for an hour. * `npm view` answers from a cache, and told this fleet the wrong * published version twice in one morning. * * Each is honest about something and dishonest about capability, and the * failure is always the same shape: an ANSWER ABOUT A LABEL read as an answer * about behaviour. * * 11.2: A RELEASE IS NOT DELIVERED UNTIL A SERVER THAT RESTARTED ANSWERS. * `merged · published · installed · restarted · observed` — five states, and * the last two are the ones that keep being skipped. A probe run INSIDE the * server process is the only artefact that speaks for the loaded code: it * cannot be satisfied by a file that exists, a version that matches, or a * package that installed, because it calls the code and reports what happened. * * WHY A PROBE MAY NEVER READ A VERSION: if a probe branched on a version * string it would inherit that string's dishonesty, and a fleet would then * have a capability check that passes on a restarted-but-not-upgraded server. * Probes call behaviour. The version travels beside the answer as CONTEXT and * is labelled as such. */ import { mkdtempSync, writeFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import { prRefsIn } from "./tools/record-events.js"; import { EVENT_KIND_IDS } from "./tools/event-kinds.js"; import { suggestRecordType, typedRecordMode } from "./typed-records.js"; import { LEAD_REFUSED, PARKED_CATEGORIES } from "./tools/away.js"; import { recordAuthorityFor } from "./roles.js"; // ⟨q-e5cb3538⟩ The renderer and the byte class live in hooks/, shared with both pushers. // @ts-expect-error — untyped .mjs sibling, deliberately not duplicated in TS import { injectLine } from "../hooks/tier.mjs"; import { identityProblem } from "./seat-identity.js"; // @ts-expect-error — untyped .mjs sibling, deliberately not duplicated in TS import { findControlByte } from "../hooks/control-bytes.mjs"; // ⟨q-15d763dc⟩ The ready-box guard's profile, as this process read it from its own env at start. // @ts-expect-error — untyped .mjs sibling, deliberately not duplicated in TS import { readyProfile, readReadyBox } from "../hooks/submit.mjs"; import { subscriptionHealth } from "./tools/events.js"; import { configuredTransport, resolveConfiguredTransport, runningTransport, isTmuxKind, targetOf, herdrMarkerPid, type TransportKind, } from "./transports/index.js"; import { readAllTransportMarkers, markerHoldsLiveProcess } from "./tools/registry.js"; import { decideTokenMapRefresh, bearerHash, TOKEN_HASH_ALGS } from "./store.js"; import { queueWriteSchema } from "./tools/queue-write.js"; import { treeProvenance } from "./tools/tree-provenance.js"; import { detectSpread } from "./server-spread.js"; import { answeringServerIdentity } from "./tools/registry.js"; import { HerdrTransport, herdrKeyName, interpretHerdrReply, submitModeOf, SUBMIT_MODE_ENV_VAR } from "./transports/herdr.js"; import { tickVerdict } from "./tools/tick.js"; import { ensureHerdrTail, herdrTailState, newContext, newMessagesIn, stopHerdrTail } from "./tools/herdr-tail.js"; import { HERDR, TMUX_PUSH, TICK_READS_AS, TICK_STORED_AS, ownPaneTarget, type TickState } from "./transports/types.js"; export type ProbeResult = { id: string; /** The release the behaviour arrived in — reported, never TESTED against. */ since: string; present: boolean; /** What was actually called and what came back. The evidence, not a claim. */ evidence: string; }; type Probe = { id: string; since: string; run: () => { present: boolean; evidence: string } }; /** * ⛔⛆⛆ THE PROBE DECISIONS ARE EXPORTED AS PURE PREDICATES, AND THE MUTATION * MATRIX IS WHY. * * Their first form computed `present` inline and built an evidence string from * the same raw values. Deleting a conjunct from `present` reddened NOTHING: the * tests asserted the EVIDENCE TEXT, which the mutation did not touch, and the * probe's own fixed input could not produce the rejected case. ⭐⭐ ***A * predicate that cannot be handed the input it is supposed to reject is not * guarded — it is decorative, which is the defect one row over and the same * shape this row is about.*** * * Exported so a control can pass the failing shape directly. */ export function retagAccepted(parse: (v: string) => boolean): boolean { // BOTH halves matter: the new member must parse AND a pre-existing one must // still parse. Without the control a schema that accepted ANY string would pass. return parse("retag") === true && parse("reprioritise") === true; } /** * `#283`'s load-bearing property, and it is NOT "it answered": an unfetchable * tree must report `"unknown"` and NEVER `0`. A distance of `0` from an * unfetched ref and from a fetched one are byte-identical and mean opposite * things — so a numeric `behind` on a tree that was never fetched is the exact * failure the verb exists to prevent. */ export function treeProvenanceRefusesZero(r: { behind: number | "unknown"; fetched: boolean; stale: boolean }): boolean { return r.behind === "unknown" && r.fetched === false && r.stale === false; } /** * `#293`'s load-bearing property (0.26.22): a seat that publishes NO module path * makes the fleet `CANNOT_COMPARE` — it is never dropped from the population so * the readable rest can answer `AGREED`. ⛔ BOTH CONTROLS ARE CONJUNCTS ON * PURPOSE: readable seats on one side of the install must still `AGREED` and on * two sides must still `DIVERGED`, or a detector that answered * `CANNOT_COMPARE` for everything would pass this probe while detecting nothing. * * ⭐ AND THIS PROBE EXISTS BECAUSE THE GATE ONE ROW OVER FIRED ON ITS OWN PR: * `#293` bumped `0.26.22` with behaviour and no probe, `main` moved under * `#292`, and qa measured `probedThrough 0.26.21 < running 0.26.22 → ok:false`. * The remedy is the probe, not a softer comparison — softening it would turn * the verb back into the label read ⟨q-1c8e35f9⟩ exists to end. */ /** * ⟨q-8a3f1c05⟩ / #303 — IN-FLIGHT IS DERIVED FROM THE SEAM, NOT MATCHED ON A GLYPH. * A 0.26.21 server read `⛔ Blocked — was 🚧 until the base went red` as IN FLIGHT * (the regex `/🚧|🔍/` matched the mention); the seam's `workStateOf` reads the * LEADING glyph and answers blocked. All three conjuncts matter: the old answer * for the blocked row must be refused AND the two genuine in-flight states must * still read in flight, or a predicate that answers false to everything passes. * The version label did not move for #303 (still 0.26.22), so `check-probe-coverage` * could not see the behaviour arrive — this probe is what sees it. */ export function inFlightDerivedFromSeam(inFlight: (status: string) => boolean): boolean { return inFlight("⛔ Blocked — was 🚧 until the base went red") === false && inFlight("🔍 In Review") === true && inFlight("🚧 In Progress") === true; } export function spreadPoisonedByUnreadableSeat(states: { unreadable: string; agreed: string; diverged: string }): boolean { return states.unreadable === "CANNOT_COMPARE" && states.agreed === "AGREED" && states.diverged === "DIVERGED"; } /** * Each probe calls a behaviour that did not exist before its release and * reports what it observed. A probe that could pass without the code being * loaded is not a probe — it is a restatement of the version. */ const PROBES: Probe[] = [ { id: "typed-records-obligatory", since: "0.26.10", run: () => { const s = suggestRecordType("DONE: shipped it", []); const mode = typedRecordMode(); return { present: s.type === "done" && (mode === "warn" || mode === "refuse"), evidence: `suggestRecordType("DONE: …") -> '${s.type}', policy mode '${mode}'`, }; }, }, { id: "record-events-all-kinds", since: "0.26.12", run: () => { const kinds = [...EVENT_KIND_IDS].sort(); const present = ["item", "phase", "pr", "task"].every((k) => kinds.includes(k as never)); return { present, evidence: `subscribable kinds: ${kinds.join(", ")}` }; }, }, { id: "multi-pr-citation", since: "0.26.14", run: () => { const refs = prRefsIn("owner/repo#170, #173"); return { present: refs.length === 2 && refs[1] === "owner/repo#173", evidence: `prRefsIn("owner/repo#170, #173") -> [${refs.join(", ")}]`, }; }, }, { id: "away-means-david-away", since: "0.26.13", run: () => { const present = "merge" in LEAD_REFUSED && PARKED_CATEGORIES.includes("licence" as never); return { present, evidence: `coord_away refuses [${Object.keys(LEAD_REFUSED).join(", ")}] for the lead; parks ${PARKED_CATEGORIES.length} categories`, }; }, }, { id: "subscription-scanned-vs-evaluated", since: "0.26.15", run: () => { // The capability is that "the machinery ran" and "your kind fired" are // separable. Probed by asking for the state that used to be reported as // broken: scanned, never evaluated — a healthy idle watch. const base = { id: "p", agentId: "p", kind: "item", target: "t", createdAt: 0, lastEvaluatedAt: null, lastEventAt: null, delivered: [] } as never; const quiet = subscriptionHealth({ ...(base as object), lastScannedAt: Date.now() } as never); const unscanned = subscriptionHealth({ ...(base as object), lastScannedAt: null } as never); return { present: quiet.level === "ok" && unscanned.level === "error", evidence: `scanned+quiet -> '${quiet.level}', never-scanned -> '${unscanned.level}'`, }; }, }, /** * ⛔⛆⛆ THE PROBES BELOW CLOSE THE WINDOW ⟨q-1c8e35f9⟩ MEASURED. * * Before them the newest `since` was `0.26.15`, so `capabilities` answered * `ok · missing: []` identically on every version from `0.26.16` to `0.26.21` * — the whole set the fleet was about to install. * * ⚠ AND THE TRAP THE ROW NAMES IS THE ONE TO AVOID WHILE WRITING THESE: * `away-means-david-away` EXISTS, its NAME matches the changed area, and its * ASSERTION predates the change — it tests `0.26.13`'s refusal list, not * `#216`'s query mode. ⭐⭐ ***A probe whose name matches while its assertion * predates reads as coverage and is not. So each probe below asserts a * behaviour that DID NOT EXIST before its own `since`, and would throw or * return `false` on the release before it.*** */ { // #284 — `queue_write` gained `op: "retag"`. On 0.26.20 the enum has three // members and parsing `"retag"` throws, which is the probe's whole point. id: "queue-write-retag", since: "0.26.21", run: () => { const parse = (v: string) => queueWriteSchema.op.safeParse(v).success === true; const present = retagAccepted(parse); return { present, evidence: `queue_write op accepts "retag": ${parse("retag")} (control "reprioritise": ${parse("reprioritise")}) -> present=${present}`, }; }, }, { // #283 — every `repo`-taking verb reports the tree it read. The load-bearing // property is NOT that it answers, it is that an unfetchable tree yields // `"unknown"` and NEVER `0`: a distance of 0 from an unfetched ref and from a // fetched one are byte-identical and mean opposite things. id: "tree-provenance-unknown-not-zero", since: "0.26.21", run: () => { const r = treeProvenance("/nonexistent-path-for-capability-probe"); const present = treeProvenanceRefusesZero(r); return { present, evidence: `unreachable tree -> behind=${JSON.stringify(r.behind)} fetched=${r.fetched} stale=${r.stale} -> present=${present}`, }; }, }, { // ⟨q-b607005a⟩ — a WRITER must not impose this queue's id grammar on a // document that does not use it. Measured on a consumer fleet 2026-09-16: filing ONE item // stamped `⟨q-…⟩` onto ALL 168 rows of a queue keyed by `[Q-nnn]` and broke // two green guards. The property is not "it stamps" — stamping a queue that // ALREADY records ids is correct and must not regress. It is that the // document's own prior art decides, and the row THIS CALL authored is the // exception that keeps the absorption defect closed. id: "stamp-respects-foreign-grammar", since: "0.26.24", run: () => { const head = ["---", 'title: "Queue"', "---", "", "## Queue", ""]; const foreign = parseWorkDoc(head.concat(["- [ ] (P1) [Q-001] a consumer's own convention"]).join("\n")); const native = parseWorkDoc( head.concat(["- [ ] (P1) ⟨q-11111111⟩ records its id", "- [ ] (P2) appended by hand"]).join("\n"), ); const foreignOwn = queueItemsOf(foreign)[0]?.id ?? ""; const left = stampQueueIds(foreign).stamped.length; const owned = stampQueueIds(foreign, { own: [foreignOwn] }).stamped.length; const absorbed = stampQueueIds(native).stamped.length; const present = left === 0 && owned === 1 && absorbed === 1; return { present, evidence: `foreign doc, not ours -> stamped ${left} · foreign doc, our own row -> stamped ${owned} · ` + `doc that already records ids -> absorbed ${absorbed} -> present=${present}`, }; }, }, { // #293 — `detectSpread` did not exist before 0.26.22. The property is not // "it answers": an UNREADABLE seat must poison the verdict rather than be // dropped, while readable seats still resolve to AGREED / DIVERGED. id: "server-spread-unreadable-poisons", since: "0.26.22", run: () => { const installed = { mtime: 1_000, module: "/installed-for-capability-probe" }; const a = { agentId: "a", serverStartedAt: 2_000, serverModule: installed.module }; const b = { agentId: "b", serverStartedAt: 3_000, serverModule: installed.module }; const older = { agentId: "older", serverStartedAt: 500, serverModule: installed.module }; const mute = { agentId: "mute" }; const states = { unreadable: detectSpread([a, mute], installed).state, agreed: detectSpread([a, b], installed).state, diverged: detectSpread([a, older], installed).state, }; const present = spreadPoisonedByUnreadableSeat(states); return { present, evidence: `unreadable seat -> ${states.unreadable} · same side -> ${states.agreed} · two sides -> ${states.diverged} -> present=${present}`, }; }, }, { // #303 (shipped under 0.26.22, no bump) — `isInFlightStatus` derives from the seam. id: "in-flight-derives-from-seam", since: "0.26.22", run: () => { const blocked = isInFlightStatus("⛔ Blocked — was 🚧 until the base went red"); const review = isInFlightStatus("🔍 In Review"); const present = inFlightDerivedFromSeam(isInFlightStatus); return { present, evidence: `"⛔ Blocked — was 🚧 …" in flight: ${blocked} (0.26.21 said true) · "🔍 In Review": ${review} -> present=${present}` }; }, }, { // ⛔ A HERDR SEAT'S OWN SERVER TAILS ITS INBOX. The first version of this probe checked // `typeof startHerdrTail === "function"` — which read PRESENT on six seats while the tail ran // on none, the exact lie this verb exists to refuse. It now STARTS a tail against a scripted // herdr transport and asserts the process registry reports it running, is idempotent on a // second bind, and reports it gone after a stop — plus the line reader's byte offsets, which // are what stop a later held message being skipped. Runtime truth for THIS seat is reported // separately, under `herdrTail`, because a probe answers "can this build" and not "is it". id: "herdr-inbox-tail", since: "0.26.25", run: () => { const probeId = `__probe-herdr-tail-${process.pid}`; const scripted = { kind: HERDR } as unknown as Parameters[1] extends infer O ? O extends { transport?: infer T } ? T : never : never; const dir = mkdtempSync(path.join(tmpdir(), "probe-tail-")); try { const first = ensureHerdrTail(probeId, { transport: scripted, pollMs: 3_600_000, tail: async () => ({ delivered: [], held: [] }) }); const again = ensureHerdrTail(probeId, { transport: scripted, pollMs: 3_600_000, tail: async () => ({ delivered: [], held: [] }) }); const seen = herdrTailState().some((s) => s.agentId === probeId && s.running); const stopped = stopHerdrTail(probeId); const gone = !herdrTailState().some((s) => s.agentId === probeId); const f = path.join(dir, "inbox.jsonl"); const a = `${JSON.stringify({ id: "a" })}\n`; writeFileSync(f, `${a}${JSON.stringify({ id: "b" })}\n{"id":"hal`); const read = newMessagesIn(f, 0); const offsets = read.map((m) => m.end).join(",") === `${Buffer.byteLength(a)},${Buffer.byteLength(a) + Buffer.byteLength(`${JSON.stringify({ id: "b" })}\n`)}`; const present = first.started && !again.started && again.running && seen && stopped && gone && read.length === 2 && offsets; return { present, evidence: `ensureHerdrTail started=${first.started} · second bind started=${again.started} running=${again.running} · registry running=${seen} · stop=${stopped} gone=${gone} · reader ${read.length} whole lines with exact end offsets=${offsets} -> present=${present}` }; } finally { stopHerdrTail(probeId); rmSync(dir, { recursive: true, force: true }); } }, }, { // ⛔⛔ ⟨q-cdb5b007⟩ — the HTTP daemon started NO tails at all, so any seat one message behind // was permanently and silently deaf. This probe exists because the PREVIOUS probe could not // see that: it starts a tail by calling `ensureHerdrTail` directly, which is exactly what // production never did under token auth. A capability that only the test calls is not present. // // Probed here: a tail started the way `startTailOnBind` now starts it types NOTHING that // predates it. That is the half a seat can check about ITSELF; whether this build's auth path // reaches it is reported at runtime under `herdrTail`, which must be non-empty on a live // daemon. Label and code disagree by design — `versionLabel` reads package.json on disk. id: "http-prebound-starts-tail-at-eof", since: "0.26.26", run: () => { const probeId = `__probe-tail-eof-${process.pid}`; const dir = mkdtempSync(path.join(tmpdir(), "probe-tail-eof-")); try { const seeded = newContext(true); const inherited = newContext(false); const hasSeedFields = typeof seeded.seedEof === "boolean" && seeded.seeded instanceof Set; // A seeded context adopts EOF on first sight of a source; an inherited one does not. const scripted = { kind: HERDR } as unknown as NonNullable[1]>["transport"]; const seededStart = ensureHerdrTail(probeId, { transport: scripted, pollMs: 3_600_000, seedEof: true, tail: async () => ({ delivered: [], held: [] }), }); const running = herdrTailState().some((s) => s.agentId === probeId && s.running); const present = hasSeedFields && seeded.seedEof === true && inherited.seedEof === false && seededStart.started && running; return { present, evidence: `newContext(true).seedEof=${seeded.seedEof} · newContext(false).seedEof=${inherited.seedEof} · per-source seeded set=${seeded.seeded instanceof Set} · ensureHerdrTail({seedEof}) started=${seededStart.started} running=${running} -> present=${present}`, }; } finally { stopHerdrTail(probeId); rmSync(dir, { recursive: true, force: true }); } }, }, { // ⛔⛔ ⟨q-c8032c5f⟩ — the ready-box guard HELD EVERY PUSH to a live seat (ticks 191, // delivered 0, held 98) reporting "the ❯ line has no ─ rule directly above it" against a pane // that WAS ready. herdr splices the pane's own label into the frame, so the rule Claude Code // drew as plain dashes arrives as `──… qa2 ─`. `RULE_RE` demanded an unbroken dash line and // read the annotated one as not-a-rule: a false negative in the matcher, reported as a fact // about the pane. The seat stayed queued and functional for PULL and simply never WOKE. // // ⚠ THE NEGATIVES ARE THE PROBE. Accepting the label is one line; accepting it WITHOUT opening // a false-accept is the property. A matcher that took any annotated rule would pass a // positive-only probe while typing into dialogs and menus — so a multi-word label, a label // with no dash after it, and two labels are each asserted REFUSED alongside the accept. id: "ready-box-tolerates-pane-label", since: "0.26.27", run: () => { const D = "─".repeat(60); const screen = (rule: string) => [`${D} above ${D}`, rule, "❯", D, " ⏵⏵ bypass permissions on"].join("\n"); const readyOf = (rule: string) => readReadyBox(screen(rule), "claude-code") as { ready: boolean; reason?: string }; const labelled = readyOf(`${D} qa2 ${D}`).ready === true; // the live failure, now accepted const plain = readyOf(D).ready === true; // control: the un-annotated rule must still work const multiWord = readyOf(`${D} two words ${D}`).ready === false; const noTrailingDash = readyOf(`${D} qa2 `).ready === false; const twoLabels = readyOf(`${D} a ${D} b ${D}`).ready === false; const present = labelled && plain && multiWord && noTrailingDash && twoLabels; return { present, evidence: `herdr-labelled rule accepted=${labelled} · plain rule still accepted=${plain} · REFUSED: multi-word=${multiWord}, no-trailing-dash=${noTrailingDash}, two-labels=${twoLabels} -> present=${present}`, }; }, }, { // ⟨q-d404a6f6⟩/⟨q-9e0072b3⟩ — `configuredSource` is a WIRE VALUE, and #384 changed it from // "config" to "machine-config" because `config.json` is machine-scoped, not fleet-wide. Anything // comparing `configuredSource === "config"` — the console, a gate, a seat checking its own // status — reads one answer from a 0.26.27 server and another from this one. // // ⚠ WHICH IS WHY IT NEEDS A PROBE AND NOT JUST A BUMP: a renamed output is invisible to every // artefact except the one that calls it. ⟨q-9e0072b3⟩ was filed because the tree carried this // change while the registry did not, and nothing in either could say so — the version label was // identical on both sides of a behaviour difference. // ⟨q-54adf191⟩ The daemon read tokens.json ONCE at startup and had no watcher, so a token minted // while it ran was refused with a 401 that looks exactly like a broken daemon. A version label // cannot answer "does this daemon pick up a new token" — only calling the decision can. // // ⛔ THE PROBE DRIVES THE REAL RULE WITH A SCRIPTED FILESYSTEM, and touches no tokens.json: the // decision is one pure function shared with the live path, so this cannot pass while the daemon // behaves differently. The NEGATIVES are the property: a refusal must keep the previous map. id: "token-map-reloads-on-change", since: "0.26.31", run: () => { const map = (n: number) => new Map(Array.from({ length: n }, (_, i) => [`tk${i}`, `a${i}`] as const)); const state = { map: map(1), stamp: "s1", checkedAt: 0 }; const io = (stamp: string | null, read: () => Map | null) => ({ stamp: () => stamp, read }); const opts = { force: true, now: 1 }; const changed = decideTokenMapRefresh(state, io("s2", () => map(2)), opts); const unchanged = decideTokenMapRefresh(state, io("s1", () => map(9)), opts); const malformed = decideTokenMapRefresh(state, io("s2", () => { throw new Error("not valid JSON"); }), opts); const vanished = decideTokenMapRefresh(state, io(null, () => null), opts); const limited = decideTokenMapRefresh({ ...state, checkedAt: 1000 }, io("s2", () => map(2)), { now: 1001 }); const picksUp = changed.result.changed === true && changed.result.count === 2 && changed.next.map?.size === 2; const quiet = unchanged.result.changed === false && unchanged.result.reason === "unchanged"; const keepsOnBadFile = malformed.result.changed === false && malformed.result.reason === "malformed" && malformed.next.map === state.map && malformed.next.stamp === "s1"; const keepsOnGone = vanished.result.reason === "vanished" && vanished.next.map === state.map; const rateLimited = limited.result.reason === "rate-limited" && limited.next.map === state.map; const present = picksUp && quiet && keepsOnBadFile && keepsOnGone && rateLimited; return { present, evidence: `changed -> reloaded ${changed.result.count} agents=${picksUp} · same stamp -> no read=${quiet} · KEEPS THE OLD MAP: malformed=${keepsOnBadFile} (stamp not advanced), vanished=${keepsOnGone} · rate-limited=${rateLimited} -> present=${present}`, }; }, }, { id: "transport-source-is-machine-scoped", since: "0.26.28", run: () => { // ⛔ THIS PROBE MUST PROVE A PROPERTY OF THE CODE, NEVER A FACT ABOUT THIS MACHINE. // The first version called `configuredTransport()` directly — which reads THIS seat's // real config.json off disk — and `check-baseline-declared` correctly flagged that as an // UNDECLARED mutable-baseline read: a probe run by `check-probe-coverage.mjs` in the gate // chain has no business depending on whatever transport this one box happens to have // configured. It also, as a side effect, called `configuredTransport()` uncaught: that // throws by design on an unconfigured seat, and `probeCapabilities`'s outer catch turned // the throw into an undiscriminated `present:false`, breaking `capabilities.ok` for any // fresh/unregistered seat (test/status-capabilities.test.mjs's unregistered-agent case). // // ✅ FIXED BOTH WAYS BY CALLING `resolveConfiguredTransport` — the PURE decision // `configuredTransport()` delegates to — WITH CONSTRUCTED INPUTS instead: two cases, one // for each live source, built here rather than read from anywhere. Nothing outside this // process is touched, so there is no baseline to declare, and there is no live-config // state that could throw. const machineConfig = resolveConfiguredTransport({ fileHasTransport: true, fileTransport: "herdr", env: undefined }); const env = resolveConfiguredTransport({ fileHasTransport: false, fileTransport: undefined, env: "herdr" }); const sources = [machineConfig.source, env.source] as const; const known = sources.every((s) => s === "machine-config" || s === "env"); const retired = (sources as readonly string[]).includes("config"); const present = known && !retired; return { present, evidence: `constructed machine-config case -> source=${JSON.stringify(machineConfig.source)} · constructed env case -> source=${JSON.stringify(env.source)} · in current vocabulary={machine-config,env}=${known} · either is retired "config"=${retired} -> present=${present}`, }; }, }, { // ⟨q-f7e3c701⟩ 0.26.29 — ATOMIC SUBMIT. Two properties, and BOTH are here because each one // alone would have shipped a defect that was actually shipped: // // 1. THE PARSE. #397 first read `json?.status ?? json?.result?.status`. The real herdr 0.9.1 // reply carries `result.type`, and there is no `status` anywhere — so on real hardware the // success check NEVER fired and every genuine delivery fell through to unverified / // safeToRetry:false, which is the DROP path. It would have reported 100% failure while // succeeding, and the canary would have binned a working fix on false evidence. // ⛔ THE UNIT TESTS COULD NOT CATCH IT: they mocked `{status:"agent_prompted"}` — the code's // own assumption — so they asserted the belief rather than the world. The payloads below are // VERBATIM CAPTURES from a real binary, which is the only fixture shape that can fail. // // 2. THE SAFE DEFAULT. Blast radius is both fleets and the failure mode is silence, so the // canary must be opt-in by EXACT literal. A near-miss must NOT opt in. // // Both are pure predicates handed the REJECTED input, per this file's mutation-matrix rule: // a probe that cannot be given the case it must refuse is decorative. id: "atomic-submit-parses-real-herdr-replies", since: "0.26.29", run: () => { // VERBATIM from `herdr agent prompt` on herdr 0.9.1 — success carries result.type. const REAL_PROMPTED = '{"id":"cli:agent:prompt","result":{"agent":{"agent":"claude","agent_status":"idle","pane_id":"w16:pD"},"type":"agent_prompted"}}'; // VERBATIM from the same binary against a blocked agent — a TOP-LEVEL error.code, no result. const REAL_BLOCKED = '{"error":{"code":"agent_blocked","message":"agent w16:pD is blocked and requires interactive input"},"id":"cli:agent:prompt"}'; const okReply = interpretHerdrReply({ status: 0, stdout: REAL_PROMPTED, stderr: "" }); const blockedReply = interpretHerdrReply({ status: 1, stdout: REAL_BLOCKED, stderr: "" }); const prompted = (okReply.json as { result?: { type?: string } } | undefined)?.result?.type === "agent_prompted"; // The two live in DIFFERENT PLACES — one field cannot serve both, which was the bug. const blockedCode = blockedReply.ok === false && blockedReply.error?.code === "agent_blocked"; // ⛔ THE NEGATIVE CONTROL FOR THE PARSE: the old expression must NOT find anything, or this // probe would pass on the broken code it exists to refuse. const oldPathFindsNothing = (okReply.json as { status?: string; result?: { status?: string } } | undefined)?.status === undefined && (okReply.json as { status?: string; result?: { status?: string } } | undefined)?.result?.status === undefined; const defaultsSafe = submitModeOf({}) === "send-keys"; const optsIn = submitModeOf({ [SUBMIT_MODE_ENV_VAR]: "agent-prompt" }) === "agent-prompt"; // ⛔ NEGATIVE CONTROLS FOR THE FLAG: a trailing space and a near-miss must NOT flip a fleet. const typoStaysSafe = submitModeOf({ [SUBMIT_MODE_ENV_VAR]: "agent-prompt " }) === "send-keys" && submitModeOf({ [SUBMIT_MODE_ENV_VAR]: "AGENT-PROMPT" }) === "send-keys" && submitModeOf({ [SUBMIT_MODE_ENV_VAR]: "true" }) === "send-keys"; const present = prompted && blockedCode && oldPathFindsNothing && defaultsSafe && optsIn && typoStaysSafe; return { present, evidence: `real agent_prompted -> result.type read=${prompted} · real agent_blocked -> error.code read=${blockedCode} · ` + `old \`status\` path finds nothing on the real payload=${oldPathFindsNothing} · ` + `default=${JSON.stringify(submitModeOf({}))} safe=${defaultsSafe} · exact opt-in=${optsIn} · near-misses stay send-keys=${typoStaysSafe} -> present=${present}`, }; }, }, { // ⟨q-1c95f7d4⟩ Phase 5.4 Task 5 — the external tick, probed by CALLING the code that // decides what a reading MEANS (every probe here is synchronous, so the async read is // exercised by its test suite and this asserts the decision layer plus the wiring): // a `blocked` reading is a measured HIT, an `idle` one is coverage and NOT a hit, an // unreadable one is neither, and herdr's measured write/read asymmetry is in place. id: "external-tick-evidence", since: "0.26.24", run: () => { const seat = (state: TickState) => ({ agentId: "probe", transport: HERDR, readable: true as const, state, source: "herdr pane w0:p0" }); const blocked = tickVerdict(seat("blocked")); const idle = tickVerdict(seat("idle")); const blind = tickVerdict({ agentId: "probe", transport: HERDR, readable: false as const, why: "no agent there" }); const wired = typeof new HerdrTransport().readTick === "function" && typeof new HerdrTransport().publishTick === "function"; const stored = TICK_STORED_AS.idle === "done" && TICK_READS_AS.done === "idle"; const present = blocked?.hit === true && idle?.hit === false && idle?.measured === true && blind?.measured === false && wired && stored; return { present, evidence: `tickVerdict blocked -> hit=${blocked?.hit} · idle -> hit=${idle?.hit} measured=${idle?.measured} · unreadable -> measured=${blind?.measured} · readTick/publishTick wired=${wired} · TICK_STORED_AS.idle="${TICK_STORED_AS.idle}" -> present=${present}`, }; }, }, { // Phase 5.4 Task 4 (0.26.23) — the herdr transport exists and refuses by name: a scripted // dead pane reads dead from herdr's own reply, and a tmux key name is refused, not typed. id: "herdr-transport-registered", since: "0.26.23", run: () => { const scripted = new HerdrTransport({ run: (a) => (a[0] === "status" ? { ok: true, status: 0, stdout: "server:\n status: running\n", stderr: "" } : { ok: false, status: 0, stdout: "", stderr: "", json: { error: { code: "pane_not_found", message: "pane w0:p0 not found" } }, error: { code: "pane_not_found", message: "pane w0:p0 not found" } }), sleep: () => {}, }); const key = herdrKeyName("C-u"); const exists = scripted.paneExists("w0:p0"); const present = scripted.kind === HERDR && exists === false && key.ok === false; return { present, evidence: `HerdrTransport.kind=${scripted.kind} · scripted pane_not_found -> paneExists=${exists} · herdrKeyName("C-u").ok=${key.ok} -> present=${present}` }; }, }, { // ⟨q-e5cb3538⟩ (0.26.25) — a control byte in message content never reaches a pane as a // keystroke: the renderer every push path uses shows it as a visible escape, and a new send // carrying one is refused at ingress. Measured on qa's payload (CR, ESC[201~, ETX) plus DEL // and C1, rendered through THIS process's hooks — a seat whose server predates the fix answers // false here, which is the question a release is delivered by. id: "pane-render-neutralizes-controls", since: "0.26.25", run: () => { const body = "X1\rX2\x1b[201~X3\x03X4\x7f\u0085"; const line = String(injectLine({ ts: 0, tag: "DM", from: "probe", text: body })); const leaked = (line.match(/[\x00-\x09\x0b-\x1f\x7f\u0080-\u009f]/g) ?? []).length; const visible = line.includes("X1\\rX2\\x1b[201~X3\\x03X4\\x7f\\u0085"); const refused = findControlByte({ text: body }) !== null && findControlByte({ text: "ok\n\tok" }) === null; const present = leaked === 0 && visible && refused; return { present, evidence: `rendered qa's payload + DEL + C1 -> leaked ${leaked} control byte(s) · escapes visible=${visible} · ingress refuses it and passes LF/TAB=${refused} -> present=${present}` }; }, }, { // ⟨q-abd88dd4⟩ — a herdr marker's pid is chosen for the pre-herdr readers that cannot be // patched: 1 only where this process may not signal pid 1 (EPERM), 0 otherwise, and this // build never reads it as a process. Both functions are new in 0.26.25. id: "herdr-marker-survives-pre-herdr-readers", since: "0.26.25", run: () => { const eperm = () => { const e = new Error("EPERM") as NodeJS.ErrnoException; e.code = "EPERM"; throw e; }; const notSignalable = herdrMarkerPid(eperm).pid; const signalable = herdrMarkerPid(() => true).pid; const holds = markerHoldsLiveProcess({ agentId: "probe", transport: HERDR, pid: 1, since: 0 }); const present = notSignalable === 1 && signalable === 0 && holds === false; return { present, evidence: `kill(1,0) EPERM -> pid ${notSignalable} · kill(1,0) permitted (root/container) -> pid ${signalable} · herdr marker pid 1 holds a live process: ${holds} -> present=${present}` }; }, }, { // ⟨q-3cd5a77d⟩ — the result word counts only in the CLAIM position. A seat on an older server // reads the #359 routing header (PASS in the PR title) as the coordinator gating it PASS. id: "gate-claim-needs-claim-position", since: "0.26.25", run: () => { const sha = "0826519e043add993c5d757908c1903239542160"; const line = (text: string) => JSON.stringify({ ts: 1, from: "probe", text, record: { type: "go", payload: {}, cites: [{ kind: "pr", ref: "#359" }] } }); const routing = gateClaimsIn(line(`GATE, prioritised: #359 (test-all prints PASS after FAILED) @ ${sha}`), "359", sha).length; const typed = gateClaimsIn(line(`QA GATE — **PASS** @ \`${sha}\``), "359", sha).length; const present = routing === 0 && typed === 1; return { present, evidence: `routing header with PASS in the title -> ${routing} claim(s) · typed QA GATE — **PASS** @ sha -> ${typed} -> present=${present}` }; }, }, { // ⟨q-18a719c5⟩ The spread can place a seat at all: the identity THIS server stamps names its // module (resolved by package name, through the real caller in dist/tools/registry.js), a // stamp whose pid is gone reads unknown, and unknowns block AGREED but not DIVERGED. Before // 0.26.25 the module resolved to undefined on every server. id: "server-spread-places-seats", since: "0.26.25", run: () => { const me = answeringServerIdentity(); const installed = typeof me.serverModule === "string" ? { mtime: 1_000, module: me.serverModule } : null; const seat = (agentId: string, startedAt: number, pid = 101) => ({ agentId, serverPid: pid, serverStartedAt: startedAt, serverModule: me.serverModule }); const alive = (pid: number) => pid !== 999; const stale = installed ? detectSpread([seat("gone", 2_000, 999), seat("b", 3_000)], installed, { isRunning: alive }) : null; const split = installed ? detectSpread([seat("old", 500), seat("new", 3_000), { agentId: "mute" }], installed, { isRunning: alive }) : null; const staleUnknown = !!stale?.uncomparable.some((u) => u.agentId === "gone" && /no longer running/.test(u.why)); const present = typeof me.serverModule === "string" && staleUnknown && split?.state === "DIVERGED"; return { present, evidence: `module ${me.serverModule ?? "UNRESOLVED"} · dead stamp -> unknown: ${staleUnknown} · split + unstamped seat -> ${split?.state ?? "n/a"} -> present=${present}` }; }, }, { // ⟨q-caa2959e⟩ (0.26.30) — the merge-window live control's APPLICABILITY is own landings in the // horizon, never its own window count. A quiet fleet (record commits, no landing) is NOT // APPLICABLE and says so with both counts; a landing whose PR announced no window is a problem, // which is the violation the control exists to catch and the one a count-based rule would skip // green. Asked of the running function, so a server on the pre-fix build answers false. // ⟨q-4b9cdeab⟩ RELEASE A: can this daemon authenticate a HASHED tokens.json, and does it refuse an // alg it cannot evaluate? A version label cannot answer either — and the second half is the one // that matters, because ignoring an unknown entry drops a seat silently while treating it as // plaintext locks that seat out with every file on disk looking correct. id: "token-file-reads-both-forms", since: "0.26.34", run: () => { const bearer = "tk_probe_not_a_real_secret"; const h = bearerHash(bearer); const hex64 = /^[0-9a-f]{64}$/.test(h); // The map is keyed by HASH, so the same lookup serves a plaintext entry (hashed at load) and a // hashed one. Proven here on the hash function the reader itself uses. const stable = bearerHash(bearer) === h && bearerHash(bearer + "x") !== h; const algs = TOKEN_HASH_ALGS.join(",") === "sha256"; const present = hex64 && stable && algs; return { present, evidence: `bearerHash -> 64 hex=${hex64} · deterministic and input-sensitive=${stable} · known algs=${TOKEN_HASH_ALGS.join(", ")} (an entry naming anything else refuses the file)=${algs} -> present=${present}`, }; }, }, { id: "merge-window-applies-on-own-landings", since: "0.26.30", run: () => { const T = Date.parse("2026-09-20T12:00:00Z"); const landing = { sha: "a".repeat(40), at: T, author: "seat", subject: "docs(done): close it (#900)", mergeOf: 900 }; const plain = { sha: "b".repeat(40), at: T, author: "seat", subject: "docs(board): claim a row", mergeOf: null }; const opts = { now: T + 60_000, floorMs: T - 60_000 }; const unannounced = mergeWindowLivePopulation({ logText: "", writes: [landing], ...opts }); const quiet = mergeWindowLivePopulation({ logText: "", writes: [plain], ...opts }); const windowsOnly = mergeWindowLivePopulation({ logText: `{"ts":${T},"from":"qa","to":"#k","text":"QA GATE: PASS #900\nMERGE WINDOW: #900 — hold queue/board writes"}`, writes: [], ...opts }); const present = unannounced.applicable === true && unannounced.missingWindow.length === 1 && quiet.applicable === false && /landed nothing in the horizon/.test(quiet.reason) && /0 own landing\(s\)/.test(quiet.reason) && windowsOnly.applicable === false; return { present, evidence: `landing with no window -> applicable=${unannounced.applicable} missingWindow=${unannounced.missingWindow.length} · ` + `record commit, no landing -> applicable=${quiet.applicable} (names both counts: ${/0 own landing\(s\)/.test(quiet.reason)}) · ` + `windows but no landing -> applicable=${windowsOnly.applicable} -> present=${present}`, }; }, }, { // ⟨q-927e28cd⟩ (0.26.32) — a consumer reads a seat's pane THROUGH its transport. The console // answered 410 "session gone?" for every live herdr seat because it captured through tmux. // Asked of the function read_pane reaches (HerdrTransport.readPaneNow) against a scripted // herdr: a live pane is READ, a gone pane and a foreign marker are UNKNOWN — never an empty // screen. A server on the pre-fix build has no readPaneNow and answers false. id: "read-pane-through-transport", since: "0.26.32", run: () => { const STATUS = "client:\n version: 0.9.0\nserver:\n status: running\n version: 0.9.0\n"; const run = (args: string[]) => { if (args[0] === "status") return interpretHerdrReply({ status: 0, stdout: STATUS, stderr: "" }); if (args[1] === "read" && args[2] === "wP:p1") return interpretHerdrReply({ status: 0, stdout: "❯ PANE-PROBE\n", stderr: "" }); return interpretHerdrReply({ status: 0, stdout: JSON.stringify({ error: { code: "pane_not_found", message: `pane ${args[2]} not found` } }), stderr: "" }); }; const t = new HerdrTransport({ run, sleep: () => {}, env: {} }) as HerdrTransport & { readPaneNow?: (m: unknown, o?: unknown) => { state: string; text?: string } }; // BOTH methods: read_pane calls readPane, which must exist on the interface; readPaneNow is the rule it runs. if (typeof t.readPane !== "function" || typeof t.readPaneNow !== "function") return { present: false, evidence: `HerdrTransport readPane=${typeof t.readPane} readPaneNow=${typeof t.readPaneNow} — this build cannot answer read_pane` }; const m = (target: string, kind: string = HERDR) => ({ agentId: "probe", transport: kind, pid: 0, since: 0, target, tmuxTarget: target }); const live = t.readPaneNow(m("wP:p1")); const gone = t.readPaneNow(m("wP:p9")); const foreign = t.readPaneNow(m("wP:p1", "carrier-pigeon")); const present = live.state === "read" && /PANE-PROBE/.test(live.text ?? "") && gone.state === "unknown" && foreign.state === "unknown"; return { present, evidence: `live pane -> ${live.state} · gone pane -> ${gone.state} · foreign marker -> ${foreign.state} -> present=${present}` }; }, }, { // ⟨q-f995c3c7⟩ — a seat re-claiming its OWN pane is not an intruder. The same-pane exception read // process.env.TMUX_PANE only, which a herdr seat never has, so no herdr seat could match its own // marker and every restart was refused (8 occurrences by 2026-09-23, David's own seat among them). // Probed through the function the guard calls, so a server on the pre-fix build answers false. id: "own-pane-reclaim-accepted", since: "0.26.31", run: () => { const pane = "wA3:p4"; const mine = ownPaneTarget(HERDR, { HERDR_PANE_ID: pane } as NodeJS.ProcessEnv); const tmuxSeat = ownPaneTarget(TMUX_PUSH, { TMUX_PANE: "%7" } as NodeJS.ProcessEnv); const noHerdrPane = ownPaneTarget(HERDR, { TMUX_PANE: "%7" } as NodeJS.ProcessEnv); const present = mine === pane && tmuxSeat === "%7" && noHerdrPane === undefined; return { present, evidence: `herdr seat's own pane -> ${mine ?? "undefined"} · tmux seat -> ${tmuxSeat ?? "undefined"} · herdr with only TMUX_PANE -> ${noHerdrPane ?? "undefined"} (the pre-fix read) -> present=${present}`, }; }, }, { // ⟨q-0c5476ec⟩ — a seat's identity is stated once, and the launcher refuses a config that states // another seat. Probed through the function coord-seat itself calls, so a build whose launcher // would start such a seat answers false here. id: "seat-identity-stated-once", since: "0.26.33", run: () => { const tokens = { "seat-a": "tk_probe_a", "seat-b": "tk_probe_b" }; const at = (token: string) => identityProblem({ agentId: "seat-a", configPath: "/p/.mcp.json", config: { token }, tokens, tokensPath: "/c/tokens.json" }); const foreign = at("tk_probe_b"); const rotated = at("tk_gone"); const agreeing = at("tk_probe_a"); const namesOther = !!foreign && /'seat-b'/.test(foreign.message) && /'seat-a'/.test(foreign.message); const namesRotation = !!rotated && /rotated or revoked/.test(rotated.message); const leaks = [foreign, rotated].some((p) => p && /tk_probe_b|tk_gone/.test(p.message)); const present = namesOther && namesRotation && agreeing === null && !leaks; return { present, evidence: `another seat's bearer -> names both seats: ${namesOther} · unknown bearer -> named as rotated: ${namesRotation} · agreeing -> no problem: ${agreeing === null} · bearer in message: ${leaks} -> present=${present}`, }; }, }, { id: "record-authority", since: "0.24.0", run: () => { const worker = recordAuthorityFor({ roleId: "worker" }); return { present: worker.mayNotEmit.includes("verdict"), evidence: `a worker mayNotEmit: [${worker.mayNotEmit.join(", ")}]`, }; }, }, ]; /** * TWO CLAIMS, AND THE TYPE MAKES YOU CARRY BOTH (Phase 5.4 Task 3.3). * * *A config value is a label someone typed.* `configured` is that label; * `running` is answered by CALLING the transport in this process. They are * separate fields because they are separate facts, and `agrees` exists so a * reader cannot skim one and believe the other. * * ⛔ THIS IS THE MACHINE-READABLE FORM OF A MISTAKE MADE IN PROSE. An hour * before this shipped, a Task 2 contract asserted that "every seat in this fleet * is running on the code you are refactoring." Measured afterwards: every server * and every pusher loads the global install at 0.26.19 while `main` declared * 0.26.20 — the fleet was running PRE-refactor code and always had been. The * claim came from what the repo said, not from what any process answered. That * is `configured` reported as `running`, in English instead of in a type. * * `running` is `undefined` when nothing is wired, which is NOT "tmux by * default": a process with no transport delivers nothing, and substituting a * default there would restage the same substitution one layer down. */ export type TransportCapability = { configured: TransportKind; /** Answered by calling the transport, never by reading config. */ running: TransportKind | undefined; agrees: boolean; /** What was called and what came back. */ evidence: string; /** Where `configured` came from — this machine's config.json, or env. ⟨q-d404a6f6⟩: config.json is * machine-scoped, not fleet-wide. ⟨q-ec020f6a⟩: no built-in default. */ configuredSource: "machine-config" | "env"; /** * MIXED FLEET, MADE LOUD (3.4). Agents whose marker names a transport other * than the running one. Whole-fleet is the rule; this is the code noticing * when reality disagrees with the rule rather than trusting it — at 2-of-5 * stall coverage a silent disagreement is a failure nobody can see. */ disagreeingAgents: { agentId: string; marker: string }[]; }; export type CapabilityReport = { /** * WHICH PROCESS ANSWERED. Not evidence of anything — context, so a reader can * tell two servers apart when their answers disagree. Deliberately beside the * probe results rather than above them: the temptation this whole verb exists * to remove is reading the identity INSTEAD of the answers. */ answeredBy: { pid: number; startedAtIso: string; module: string; versionLabel: string }; probes: ProbeResult[]; /** Whether the probes reach the version this process claims to be. */ coverage: { probedThrough: string | null; running: string; covered: boolean; verdict: string; }; missing: string[]; /** Every probe passed AND the probes reach the running version. */ ok: boolean; /** Absent only if the probe itself threw — see `probeTransport`. */ transport?: TransportCapability; note: string; }; /** * ⛔⛆⛆ `missing: []` MEANS TWO DIFFERENT THINGS AND THIS SEPARATES THEM. * * "Nothing is missing" and "nothing was tested" produce the SAME answer today. * ⭐⭐ ***Measured 2026-09-14: `capabilities` answered `ok · missing: []` * IDENTICALLY on `0.26.20` and `0.26.21` — the probe set stops at `since * 0.26.15`, so every version the fleet was about to install was unprobed, and * the verb the fleet reaches for to prove a restart took could not see the three * changes it would have been asked to certify.*** * * That is `0`-vs-`unknown` inside the instrument the six delivery states END on: * while this is blind, `observed` is unmeasurable BY CONSTRUCTION and every * "delivered" claim in the fleet rests on a version LABEL. * * ⚠ THE COMPARISON IS AGAINST THE LABEL, WHICH IS NOT EVIDENCE — and that is * deliberate rather than sloppy. The label is the only statement of intent * available about what this process is SUPPOSED to be; the probes are the only * evidence about what it IS. Comparing them is precisely how a divergence * becomes visible, and this function says which side is which rather than * blending them. */ function coverageOf(probes: ProbeResult[], versionLabel: string) { const cmp = (a: string, b: string) => { const pa = a.split(".").map((n) => Number.parseInt(n, 10)); const pb = b.split(".").map((n) => Number.parseInt(n, 10)); for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) { const x = Number.isFinite(pa[i]) ? pa[i] : 0; const y = Number.isFinite(pb[i]) ? pb[i] : 0; if (x !== y) return x < y ? -1 : 1; } return 0; }; const sinces = probes.map((p) => p.since).filter((v) => /^\d+(\.\d+)*$/.test(v)); const probedThrough = sinces.length ? sinces.reduce((hi, v) => (cmp(v, hi) > 0 ? v : hi)) : null; const labelUsable = /^\d+(\.\d+)*$/.test(versionLabel); if (!probedThrough || !labelUsable) { return { probedThrough, running: versionLabel, covered: false as const, verdict: `COVERAGE UNKNOWN — ${!probedThrough ? "no probe declares a numeric `since`" : "the version label is not numeric"}. ` + `Unknown is not covered: this cannot be read as "nothing is missing".`, }; } const covered = cmp(probedThrough, versionLabel) >= 0; return { probedThrough, running: versionLabel, covered, verdict: covered ? `PROBES REACH THE RUNNING VERSION — newest probe \`since ${probedThrough}\`, label \`${versionLabel}\`. ` + `So \`missing: []\` here means TESTED-AND-PRESENT rather than untested.` : `UNPROBED WINDOW \`${probedThrough}\` → \`${versionLabel}\` — every behaviour introduced after ` + `\`${probedThrough}\` is UNTESTED by this verb. \`missing: []\` below therefore does NOT mean "nothing is ` + `missing"; it means "nothing in that window was looked at". A restart certified on this answer certifies the ` + `versions it can see and is silent about the ones it cannot.`, }; } export function probeCapabilities(context: { module: string; versionLabel: string }): CapabilityReport { const probes: ProbeResult[] = PROBES.map((p) => { try { const r = p.run(); return { id: p.id, since: p.since, present: r.present, evidence: r.evidence }; } catch (e) { // A THROWN PROBE IS AN ABSENT CAPABILITY, NOT A BROKEN CHECK. Older code // that lacks the symbol throws exactly here, and reporting that as an // error rather than an absence would make the common case look like a // malfunction. return { id: p.id, since: p.since, present: false, evidence: `probe threw: ${(e as Error).message}` }; } }); const missing = probes.filter((p) => !p.present).map((p) => p.id); const coverage = coverageOf(probes, context.versionLabel); return { coverage, answeredBy: { pid: process.pid, startedAtIso: new Date(Date.now() - Math.round(process.uptime() * 1000)).toISOString(), module: context.module, versionLabel: context.versionLabel, }, probes, missing, /** * ⛔ `ok` NOW REQUIRES COVERAGE AS WELL AS PRESENCE. It previously meant * "no probe failed", which on an unprobed version is "no probe ran" — the * reading this row exists to stop. A reader asking "is this server good?" * gets `false` when the honest answer is "I cannot tell", and `coverage` * says which of the two it is. */ ok: missing.length === 0 && coverage.covered, note: "Every line above was produced by CALLING the code in this process. `versionLabel` is a label someone typed " + "into package.json and is context, never evidence — a published tarball has already been observed carrying a " + "change its version said it could not. THIS ANSWER IS ABOUT ONE PROCESS: a release is delivered when every " + "live agent's OWN server answers, which is the fifth state (merged · published · installed · restarted · observed). " + "A server that has not restarted answers honestly about the old code it is still running.", }; } /* ── the verb ──────────────────────────────────────────────────────────────── */ import { resolveServerIdentity } from "./server-identity.js"; import { seatBuildOf, installedFrom, psReader, type SeatBuild } from "./tools/seat-build.js"; import { isInFlightStatus, gateClaimsIn, mergeWindowLivePopulation } from "./tools/stall.js"; import { parseWorkDoc, queueItemsOf, stampQueueIds } from "@davidbalzan/groundwork-seam"; export const capabilitiesSchema = {} as const; /** * Build the transport capability by CALLING things, then compare. * * Deliberately async and deliberately separate from `probeCapabilities`, which * is synchronous: the transport answer requires I/O (a `tmux -V`, a pane probe), * and making the sync report do I/O to obtain it would have meant reading the * config instead — which is the substitution this whole field exists to refuse. */ export async function probeTransport(): Promise { const conf = configuredTransport(); const running = await runningTransport(); // 3.4 — a mixed fleet must be detectable and LOUD. Every marker on disk is // read and any that names a different transport is listed by agent, because a // count alone tells you something is wrong and not where to look. const disagreeingAgents: { agentId: string; marker: string }[] = []; try { // READ-ONLY on purpose. The reaping loader would delete markers it judged // not-live, so a diagnostic would mutate the fleet it is describing — and it // would hide the remote kind, whose liveness needs a registry heartbeat. for (const { marker, live } of await readAllTransportMarkers()) { if (running.kind !== undefined && marker.transport !== running.kind) { const where = isTmuxKind(marker.transport) ? targetOf(marker) : undefined; disagreeingAgents.push({ agentId: marker.agentId, marker: `${marker.transport}${where ? ` (${where})` : ""}${live ? "" : " [stale]"}`, }); } } } catch { // An unreadable transports dir is not evidence of a uniform fleet. Left // empty, and the caller can see `running` was still answered. } return { configured: conf.kind, running: running.kind, agrees: running.kind === conf.kind, evidence: running.evidence, configuredSource: conf.source, disagreeingAgents, }; } /** * ⟨q-8a3f1c05⟩ — EVERY LIVE SEAT'S BUILD STATE, STATED. The restart operation read * `capabilities` to certify a stage and it could not see a pusher; this is that verb * answering the question it was asked. `seats[]` carries each live seat's PUSHER half * (keyed by the `--agent` on its own command line, against the installed hook's mtime); * `answering` carries the SERVER half of the one process that can know it — this one. * Servers carry no `--agent`, so no other seat's server is observable from here, and * each seat entry says so rather than borrowing its marker's attach-time stamp. */ export async function seatBuilds(): Promise<{ installed: { module: string; hookPath: string; hookMtime: string | null; buildMtime: string | null }; answering: SeatBuild["server"]; seats: SeatBuild[]; note: string }> { const id = resolveServerIdentity(); const installed = installedFrom(id.path); const startedAt = Date.now() - Math.round(process.uptime() * 1000); const answering = seatBuildOf({ agentId: "(answering process)", marker: undefined, installed, ps: psReader, server: { pid: process.pid, startedAt, buildMtime: installed.buildMtime } }).server; const seats: SeatBuild[] = []; try { for (const { marker, live } of await readAllTransportMarkers()) { if (!live) continue; seats.push(seatBuildOf({ agentId: marker.agentId, marker, installed, ps: psReader, server: null })); } } catch { /* an unreadable transports dir yields no seats — an empty list, not a healthy fleet */ } const toIso = (ms: number | null) => (ms === null ? null : new Date(ms).toISOString()); return { installed: { module: installed.module, hookPath: installed.hookPath, hookMtime: toIso(installed.hookMtime), buildMtime: toIso(installed.buildMtime) }, answering, seats, note: "seats[] states each live seat's PUSHER against the installed hook's own mtime (hooks/tmux-pusher.mjs, read directly), " + "keyed by the --agent on the pusher's command line. The SERVER half is known only for the answering process " + "(`answering`): servers carry no --agent, so another seat's server cannot be keyed from ps — ask that seat's own " + "`status`, which states both halves for itself. A seat that reads current here and stale in its own status is half-restarted.", }; } /** * ⟨q-15d763dc⟩ Is THIS process's pane push guarded? `guarded:false` means AGENT_COORD_READY_PROFILE=none * was set in this server's env at start: its pushes type into panes without checking for Claude * Code's input box. Stated here so an unguarded seat is visible fleet-wide, not only in a log. */ function readyBoxState(): { profile: string; guarded: boolean; source: string; warning?: string } { const p = readyProfile() as { profile: string; raw: string | null; warning?: string }; return { profile: p.profile, guarded: p.profile !== "none", source: "AGENT_COORD_READY_PROFILE in this process's env at start (never a message or the bus dir)", ...(p.warning ? { warning: p.warning } : {}) }; } export async function capabilitiesTool() { const id = resolveServerIdentity(); const report = probeCapabilities({ module: id.path, versionLabel: id.version }); try { // ⭐ `herdrTail` is RUNTIME truth for this process — the tails actually ticking here — kept apart // from the build probe on purpose, because "this build can tail" and "this seat is tailing" // are different facts and the first version of #353 reported the first as the second. return { ...report, transport: await probeTransport(), herdrTail: herdrTailState(), readyBox: readyBoxState(), seats: await seatBuilds() }; } catch (e) { // A THROWN TRANSPORT PROBE IS NOT A BROKEN VERB. An unknown configured value // refuses at startup by design, and this verb is exactly what an operator // reaches for to find out why — so it must still answer, and say what threw. return { ...report, transportError: `transport probe threw: ${(e as Error).message}`, }; } }