import type { RuntimeDirectoryRecovery } from "../seams/directory.js"; import type { RuntimeDirectoryEntry, RuntimeDirectoryStore } from "../seams/directory-store.js"; export interface RuntimeDirectoryRecoveryHooks { /** * WS-15 §6.4 step 2 / WS-14 §9: is the recorded `{pid, startedAt}` still that same process? * * A BARE PID IS NEVER ENOUGH — an OS recycles them — so an implementation must compare the start * identity too, which is why the field is a pair. Absent: nothing revalidates. */ revalidateProcessIdentity?: (entry: RuntimeDirectoryEntry) => Promise | boolean; /** * WS-15 §6.4 step 3: "where policy permits" — the host's call, never the router's. * * THIS HOOK IS THE READER OF §6 RULE 2's DURABLE ROOT (whole-branch review, F-5). `entry.configDir` * is the `CLAUDE_CONFIG_DIR` the child was OBSERVED to get — for a store-backed resume, a * `claude-resume-` staging root that "the default spawner exposes no post-cleanup lookup * for". The field exists precisely for the case where the process that knew it is gone, which is * this one, and nothing inside this package can act on it: reconciling or cleaning a vendor root * after a crash is a policy decision (WS-05 §12's barrier does it for a live handoff; a restart is * the host's). So it travels on the entry, the step's own report counts the rows that carry one, * and a host that reattaches is expected to read it. */ reattachSupervised?: (entry: RuntimeDirectoryEntry) => Promise<"reattached" | "skipped"> | "reattached" | "skipped"; } /** * How long the two durable sinks REMEMBER, in milliseconds (Lane B fix r1, n3). * * BOTH DEFAULT TO "FOREVER" (`undefined`), and that is deliberate rather than lazy: forgetting is a * product decision with a visible model-facing consequence, so the router will not make it for a host * that did not ask. `nameLeases` in particular is exactly how long a stale name keeps answering "that * referred to something that has gone" instead of "no such agent" (WS-10 §11 rule 5). * * Neither number can delete evidence: a claimed-but-unreceipted delivery (WS-15 §6.4 step 5) and a * HELD lease are excluded by the stores' own doors, at every retention. */ export interface RuntimeDirectoryRetention { /** Receipted delivery records older than this are dropped at recovery. Absent = kept forever. */ deliveries?: number; /** Released name leases released longer ago than this are dropped. Absent = kept forever. */ nameLeases?: number; } export interface RecoverDirectoryInput { store: RuntimeDirectoryStore; now: () => number; hooks: RuntimeDirectoryRecoveryHooks; /** WS-10 §13's caps, applied at step 6. Absent = both sinks keep everything. */ retention?: RuntimeDirectoryRetention; } export declare function recoverDirectory(input: RecoverDirectoryInput): Promise;