@eir-labs/coltrane 0.24.28 → 0.24.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,380 @@
1
+ /**
2
+ * `coltrane reside` — the standing loop.
3
+ *
4
+ * The state machine this drives already exists (src/residency.ts, 43 laws): states, ops, the
5
+ * party-constrained transition table, the reflex, the reaper, the boot preflight. What did NOT exist
6
+ * was a CALLER. `runReside` was exported, tested and pinned as law I20 while `src/cli.ts`'s KNOWN
7
+ * table had no "reside" in it, so `coltrane reside` answered `unknown command` on a green suite —
8
+ * a mechanism proven to work that nothing could reach. This module is the loop, and the mount in
9
+ * cli.ts is the half that makes it reachable.
10
+ *
11
+ * THREE PROPERTIES THE SHAPE ENFORCES RATHER THAN REQUESTS:
12
+ *
13
+ * 1. NO MODEL ON THE REFLEX PATH. `onInbound` is SYNCHRONOUS. Not "does not call the cortex" as a
14
+ * matter of discipline — it cannot await, so it cannot reach one. An inbound message is acked
15
+ * and appended whether the cortex is busy, dead, or absent; an unacked message means the
16
+ * listener is down, which is a pager fact and must stay one.
17
+ *
18
+ * 2. EVERY SEAM IS INJECTED, AND AN UNWIRED SEAM IS A NAMED REFUSAL. The way `deps.queueGig`
19
+ * injects dispatch (src/server.ts:3436): the engine ships the loop, its refusals and its shape
20
+ * checks; a deployment supplies the backends. Absent must mean DECLINE — `{ok:false,
21
+ * refusal:"no_backend", seam}` in the gig_dispatch shape, naming which seam — never a throw and
22
+ * never a plausible default. `hosted_unsupported` is deliberately not reused: an unwired seam
23
+ * and an unsupported deployment are different facts.
24
+ *
25
+ * 3. THE ROUTER IS CODE. Determinism in the engine, inference in the prompt, no overlap. A clean
26
+ * pass dispatches every due (order, ordinal) and consults the cortex ZERO times. The cortex is
27
+ * reached on NAMED DEMAND only — a store refusal whose `law_ref` the deployment listed — and that
28
+ * is keyed on the law_ref, never on the refusal's prose, because prose is written for humans
29
+ * and gets reworded without notice.
30
+ *
31
+ * A NOTE ON THE IMPORT CYCLE. src/residency.ts re-exports `runReside` from here, and this module
32
+ * imports the state machine from there. The cycle is safe and deliberate: every binding crossing it
33
+ * is either a hoisted function declaration or read inside a function body at call time, never during
34
+ * module evaluation. The alternative was duplicating the transition table, which is the one thing
35
+ * the surface's identity laws exist to forbid.
36
+ */
37
+ import { selectResidencyBacking, resolveSeatBacking } from "./reside_backing.js";
38
+ import { applyResidencyOp, bootResidency, reflexAck, } from "./residency.js";
39
+ export { selectResidencyBacking, resolveSeatBacking, fileSeatBacking, fileSeatSeed, SEAT_MEMBERS, RESIDENCY_DIR_VAR, RESIDENCY_MODULE_VAR, } from "./reside_backing.js";
40
+ /** The gig path is WORK's gig path. A second implementation fails by existing (I12, one level out). */
41
+ export { workOnce as resideGigPath } from "./worker.js";
42
+ export const RESIDE_REFUSALS = [
43
+ "no_backend",
44
+ "backing_conflict",
45
+ "nothing_claimable",
46
+ "gig_scoped_token",
47
+ "silent_wake",
48
+ "cursor_without_seal",
49
+ "needs_amendment",
50
+ "store_refused",
51
+ ];
52
+ /**
53
+ * The exit code each refusal earns, TOTAL over the refusal set — `Record<ResideRefusal, number>`, so
54
+ * adding a refusal without deciding what it means to a supervisor is a type error rather than a
55
+ * silent 1. The set is read at runtime (not merely declared) so an undeclared refusal reaching here
56
+ * exits 1 rather than `undefined`.
57
+ *
58
+ * 2 misconfigured — including a seam no deployment wired · 3 nothing claimable ·
59
+ * 1 the loop ran and something failed · 0 is reserved for a clean release.
60
+ */
61
+ const EXIT_FOR_REFUSAL = {
62
+ no_backend: 2,
63
+ backing_conflict: 2,
64
+ nothing_claimable: 3,
65
+ gig_scoped_token: 2,
66
+ silent_wake: 1,
67
+ cursor_without_seal: 1,
68
+ needs_amendment: 1,
69
+ store_refused: 1,
70
+ };
71
+ /** The supervisor-facing exit code for a refusal. An unknown name is a failure, never a success. */
72
+ export function resideExitCode(refusal) {
73
+ return RESIDE_REFUSALS.includes(refusal) ? EXIT_FOR_REFUSAL[refusal] : 1;
74
+ }
75
+ /**
76
+ * WHICH refusals constitute NAMED DEMAND is configuration, not an engine constant. The engine ships
77
+ * the mechanism — branch on a refusal's `law_ref`, never on its prose, because prose is written for
78
+ * humans and gets reworded — and the deployment supplies the refs that mean "a human must rule".
79
+ * Hard-coding one institution's law reference here named someone else's governance inside the
80
+ * engine, which is the coupling the backing seam exists to prevent, one layer over.
81
+ */
82
+ const NO_NAMED_DEMAND = [];
83
+ /** The seams boot cannot proceed without, in the order they are reported. `callVerb` is absent from
84
+ * this list on purpose: a residency that only listens and answers is a legitimate residency, and
85
+ * the router names its own seam when it is the thing that is unwired. */
86
+ const BOOT_SEAMS = ["claim", "channelListener", "cortex", "say", "sealOutput", "cursorAdvance", "release"];
87
+ const refuse = (refusal, message, extra = {}) => ({ ok: false, refusal, message, ...extra });
88
+ /**
89
+ * A lease token that is narrow. Narrow may not mint broad (L28): a token bound to one gig cannot
90
+ * hold a residency.
91
+ *
92
+ * THE SIGNAL IS gig_id, AND ONLY gig_id — corrected against the store twice, and the second
93
+ * correction is the interesting one. An earlier draft read `may_dispatch === false`, a shape the
94
+ * column (text[]) cannot hold. The fix to "an EMPTY allow-list is narrow" was then ALSO wrong, and
95
+ * would have been worse: the list stopped being the wildcard and became the exact standards a
96
+ * presence may reach, so `{}` is now a perfectly legitimate seating — a residency that dispatches
97
+ * (chair-gated) but reaches no gig it did not dispatch. Treating empty as narrowness would have
98
+ * refused valid seats, and refused them in the one direction nobody tests: the quiet one.
99
+ *
100
+ * The dispatch allow-list is an authorization gate in the STORE, in exactly one place. It is not
101
+ * the engine's business to re-derive it, and a residency's authority sits on its chair regardless.
102
+ *
103
+ * This is a second line either way. The claim door refuses a gig token itself with a message whose
104
+ * machine-readable prefix is `gig_scoped_token:` (see storeRefusalName); the engine still checks,
105
+ * because a local or hand-built backing has no such door in front of it.
106
+ */
107
+ function isGigScoped(claim) {
108
+ return claim.gig_id != null;
109
+ }
110
+ /**
111
+ * The machine-readable name a store refusal begins with (`gig_scoped_token: …`, `not_holder: …`,
112
+ * `cursor_regression: …`). Branching on the PREFIX rather than the prose is the same discipline the
113
+ * router applies to law_ref: the human half of the message is written to be reworded.
114
+ */
115
+ export function storeRefusalName(message) {
116
+ const m = /^([a-z][a-z0-9_]*):/.exec(message.trim());
117
+ return m ? m[1] : null;
118
+ }
119
+ /** A monotonic tick source so the reflex budget is measured on a simulated clock on every machine,
120
+ * never on a wall clock (the property REFLEX_BUDGET_TICKS exists to make machine-independent). */
121
+ function clockOf(deps) {
122
+ if (deps.clock)
123
+ return deps.clock;
124
+ let t = 0;
125
+ return { now: () => t, tick: (n = 1) => { t += n; } };
126
+ }
127
+ export function createResidency(opts, deps) {
128
+ const clock = clockOf(deps);
129
+ const escalateOn = opts.escalateOn ?? NO_NAMED_DEMAND;
130
+ const inbox = [];
131
+ let rec = null;
132
+ let residencyId = null;
133
+ /**
134
+ * THE FENCE on this grant, held for the life of the seat and PRESENTED ON EVERY OP.
135
+ *
136
+ * Presenting it is the whole point, and it was missing: applyResidencyOp gates on
137
+ * `op.fence !== undefined && op.fence < rec.fence`, so an op that omits the field is not gated at
138
+ * all. All six call sites below omitted it, which left law I9 — the fencing law, with a case named
139
+ * for a GC-paused host resuming post-lease — unable to fire anywhere on the live path. The store
140
+ * had the mirror of this defect: no `fence` column at all. A declared invariant enforced by
141
+ * neither side is the shape this repo keeps finding, and it survived two green suites.
142
+ */
143
+ let fence = "";
144
+ let fenceNum = 0;
145
+ let claimed = false;
146
+ let released = false;
147
+ /** The boot refusal, held so a later step answers with the reason it never seated rather than a
148
+ * second, less specific one. */
149
+ let standing = null;
150
+ async function boot() {
151
+ // HOLD THE SEAT. Two boxes reading the same orders both dispatch (plan, seam 3), so the claim
152
+ // door is entered exactly once per instance — a second boot returns the seat already held.
153
+ if (claimed && rec && residencyId)
154
+ return { ok: true, residency_id: residencyId };
155
+ if (standing)
156
+ return standing;
157
+ for (const seam of BOOT_SEAMS) {
158
+ if (typeof deps[seam] !== "function") {
159
+ standing = refuse("no_backend", `reside has no ${seam} backend wired — a deployment supplies it (parallel to deps.queueGig); the engine ships the loop, its refusals and its shape checks.`, { seam });
160
+ return standing;
161
+ }
162
+ }
163
+ claimed = true;
164
+ const claim = await deps.claim(opts.residency);
165
+ if (claim == null) {
166
+ // Not an error and not a seat: an empty roster is the ordinary answer to "is anything free".
167
+ standing = refuse("nothing_claimable", "no residency was claimable — nothing queued for this instance.");
168
+ return standing;
169
+ }
170
+ if (isGigScoped(claim)) {
171
+ // ENGINE-SIDE, BEFORE THE WIRE. The store would refuse this too (42501 at the dispatch door),
172
+ // but a token that cannot possibly dispatch should never travel to find that out.
173
+ standing = refuse("gig_scoped_token", `the claimed credential is scoped to a single gig${claim.gig_id ? ` (${claim.gig_id})` : ""} and cannot hold a residency — narrow may not mint broad.`);
174
+ return standing;
175
+ }
176
+ const booted = bootResidency({ agent_slug: claim.agent_slug, org: claim.org, venue_slug: claim.venue_slug, channel_id: claim.channel_id }, {
177
+ resolveAgent: (s) => (s === claim.agent_slug ? { slug: s } : null),
178
+ resolveVenue: (s) => (s === claim.venue_slug ? { slug: s, credential_surface: [] } : null),
179
+ cortexPresent: () => typeof deps.cortex === "function",
180
+ seatRow: (r) => { rec = r; },
181
+ });
182
+ if (!booted.ok) {
183
+ standing = refuse("no_backend", `boot refused: ${booted.refusal}`, { seam: booted.refusal });
184
+ return standing;
185
+ }
186
+ // The fence is taken from the claim FIRST — the record is built from it, so an ordering slip
187
+ // here would seat every residency at fence 0 and quietly hand the store a stale token on the
188
+ // first heartbeat.
189
+ fence = claim.fence ?? "";
190
+ fenceNum = Number(fence) || 0;
191
+ // The store's session and cursor are the durable ones — a thaw resumes the same life.
192
+ rec = { ...booted.rec, session_id: claim.session_id, cursor: claim.cursor, fence: fenceNum, lease_until: Number.MAX_SAFE_INTEGER };
193
+ residencyId = claim.residency_id;
194
+ const listening = applyResidencyOp(rec, { kind: "listen", fence: fenceNum });
195
+ // A refusal ends the STEP, never the process: an un-listened seat is still a seat.
196
+ if (listening.ok)
197
+ rec = listening.next;
198
+ return { ok: true, residency_id: residencyId };
199
+ }
200
+ /** THE REFLEX. Synchronous by construction — a path that cannot await cannot reach a model. */
201
+ function onInbound(msg) {
202
+ inbox.push(msg);
203
+ if (rec) {
204
+ const acked = applyResidencyOp(rec, { kind: "ack", fence: fenceNum });
205
+ if (acked.ok)
206
+ rec = acked.next;
207
+ }
208
+ // reflexAck is the existing, law-covered primitive (I10/I11) — not a second ack path.
209
+ return reflexAck(msg, { invoke: () => undefined, clock });
210
+ }
211
+ async function wake() {
212
+ if (!rec || !residencyId)
213
+ return standing ?? refuse("no_backend", "not seated", { seam: "claim" });
214
+ const playing = applyResidencyOp(rec, { kind: "play", fence: fenceNum });
215
+ if (playing.ok)
216
+ rec = playing.next;
217
+ const turn = await deps.cortex({ session_id: rec.session_id, inbox: [...inbox] });
218
+ const utterance = turn.utterance;
219
+ if (!utterance || !utterance.text) {
220
+ // THE ALWAYS-ANSWER LAW. A wake that consumed a message and answered nobody is a refusal, not
221
+ // a quiet success — and it seals nothing and moves no cursor, so the unanswered message is not
222
+ // silently dropped.
223
+ return refuse("silent_wake", "the wake produced no channel utterance — a wake that consumes a message must answer it.");
224
+ }
225
+ await deps.say(utterance);
226
+ const sealed = await deps.sealOutput({ residency_id: residencyId, channel_id: utterance.channel_id, text: utterance.text });
227
+ const sha = turn.sealed_output_sha ?? sealed.content_sha;
228
+ // The cursor advances ONLY as a consequence of the seal, in the same write (I1/I3) — the state
229
+ // machine owns that arithmetic, not this loop.
230
+ const advanced = applyResidencyOp(rec, { kind: "wake_seal", fence: fenceNum, message_index: rec.cursor, sealed_output_sha: sha });
231
+ if (!advanced.ok) {
232
+ return refuse(advanced.reason === "cursor_without_seal" ? "cursor_without_seal" : "silent_wake", `the seal did not earn a cursor: ${advanced.reason}`);
233
+ }
234
+ rec = advanced.next;
235
+ await deps.cursorAdvance(residencyId, fence, rec.cursor);
236
+ return { ok: true, utterance, cursor: rec.cursor };
237
+ }
238
+ async function tick() {
239
+ if (!rec || !residencyId)
240
+ return standing ?? refuse("no_backend", "not seated", { seam: "claim" });
241
+ if (typeof deps.callVerb !== "function") {
242
+ return refuse("no_backend", "reside has no callVerb backend wired — the router's hands are the governed verb surface, hydrated under the lease token.", { seam: "callVerb" });
243
+ }
244
+ const pin = { org: rec.org, venue: rec.venue_slug };
245
+ const dispatched = [];
246
+ const relayed = [];
247
+ const escalated = [];
248
+ const monitored = [];
249
+ // A row-routed READ forwards its args verbatim and reads the credential from the header, so it
250
+ // carries no pin. The dispatch is an ACT and names its org and venue in the act itself.
251
+ const due = await deps.callVerb("work-order-due", {});
252
+ if (!due.ok) {
253
+ await deps.say({ channel_id: rec.channel_id, text: due.message });
254
+ return { ok: true, dispatched, monitored, relayed: [{ refusal: due.refusal, message: due.message }], escalated };
255
+ }
256
+ const entries = (Array.isArray(due.data.due) ? due.data.due : []);
257
+ for (const entry of entries) {
258
+ const answer = await deps.callVerb("work-order-dispatch", {
259
+ work_order_id: entry.work_order_id,
260
+ schedule_ordinal: entry.schedule_ordinal,
261
+ mode: entry.mode ?? "live",
262
+ ...(entry.input ? { input: entry.input } : {}),
263
+ pin,
264
+ });
265
+ if (answer.ok) {
266
+ // Re-dispatching a (work_order_id, schedule_ordinal) with a standing non-terminal gig
267
+ // returns that gig's id rather than refusing — so "once per wake" is safe, not merely tidy.
268
+ dispatched.push({ work_order_id: entry.work_order_id, schedule_ordinal: entry.schedule_ordinal, gig_id: String(answer.data["gig_id"] ?? "") });
269
+ continue;
270
+ }
271
+ if (answer.law_ref !== undefined && escalateOn.includes(answer.law_ref)) {
272
+ // THE ONE NAMED DEMAND. Keyed on the law_ref — the identical prose without it is governance
273
+ // and must not reach a model.
274
+ escalated.push({ work_order_id: entry.work_order_id, schedule_ordinal: entry.schedule_ordinal, law_ref: answer.law_ref });
275
+ const turn = await deps.cortex({ session_id: rec.session_id, inbox: [...inbox] });
276
+ if (turn.utterance?.text)
277
+ await deps.say(turn.utterance);
278
+ continue;
279
+ }
280
+ // A refusal is information, and the residency's voice is where it is shown — VERBATIM. The
281
+ // engine does not judge a governance refusal; it raises it.
282
+ //
283
+ // The store names its refusals in a machine-readable PREFIX, so the relayed record carries
284
+ // that name when there is one. This is also the second place a gig-scoped token can surface:
285
+ // the seat check catches one that arrives in a claim, and this catches one the wire reports.
286
+ const named = storeRefusalName(answer.message);
287
+ relayed.push({ refusal: named ?? answer.refusal, message: answer.message });
288
+ await deps.say({ channel_id: rec.channel_id, text: answer.message });
289
+ }
290
+ for (const d of dispatched) {
291
+ const seen = await deps.callVerb("gig_monitor", { gig_id: d.gig_id });
292
+ if (seen.ok)
293
+ monitored.push(d.gig_id);
294
+ }
295
+ return { ok: true, dispatched, monitored, relayed, escalated };
296
+ }
297
+ async function beat() {
298
+ // Renewing after the seat has been handed back is how two boxes come to believe they hold it.
299
+ if (released || !rec || !residencyId)
300
+ return refuse("no_backend", "no live seat to renew", { seam: "claim" });
301
+ const beaten = applyResidencyOp(rec, { kind: "heartbeat", fence: fenceNum, cortex_alive: typeof deps.cortex === "function" });
302
+ if (beaten.ok)
303
+ rec = beaten.next;
304
+ await deps.heartbeat(residencyId, fence);
305
+ return { ok: true };
306
+ }
307
+ async function shutdown(_signal) {
308
+ // A redeploy HANDS THE SEAT OVER rather than racing for it. Idempotent: a second signal during
309
+ // a drain must not release twice, and a seat never held is not released at all.
310
+ if (released || !rec || !residencyId)
311
+ return { ok: true };
312
+ released = true;
313
+ const hibernating = applyResidencyOp(rec, { kind: "hibernate", fence: fenceNum, by: "holder" });
314
+ if (hibernating.ok)
315
+ rec = hibernating.next;
316
+ await deps.release(residencyId, fence, "hibernated");
317
+ return { ok: true };
318
+ }
319
+ return {
320
+ boot,
321
+ onInbound,
322
+ wake,
323
+ tick,
324
+ beat,
325
+ shutdown,
326
+ get inbox() { return inbox; },
327
+ };
328
+ }
329
+ /**
330
+ * The `reside` verb. REUSES work's env contract — src/worker_env.ts's WORKER_ENV_CONTRACT is the
331
+ * single source, and reside introduces no new credential class: the residency's hands materialize
332
+ * from the drain key that already exists. Missing COLTRANE_STORE_URL / COLTRANE_STORE_ANON is a
333
+ * usage refusal (exit 2), the same door `work` uses.
334
+ *
335
+ * Exit codes mirror work's: 0 released cleanly · 1 the cortex failed · 2 misconfigured, including a
336
+ * seam no deployment has wired · 3 nothing claimable.
337
+ *
338
+ * This reads `io.env` when given one and falls back to the process environment otherwise — the
339
+ * fallback is what makes the mounted command usable, and the injection is what makes law I20
340
+ * checkable. It reads no NAMED variable of its own, which is why src/reside.ts can join the
341
+ * WORKER_PATH scan in tests/spec_worker_environment.test.ts and stay honest there.
342
+ */
343
+ export async function runReside(argv, io) {
344
+ const asIo = io;
345
+ const env = asIo?.env ?? process.env;
346
+ const say = (s) => { asIo?.err?.(s + "\n"); };
347
+ const at = argv.indexOf("--residency");
348
+ const residency = at >= 0 && argv[at + 1] ? String(argv[at + 1]) : "any";
349
+ // WHERE THE SEAT LIVES is selected FIRST, and never guessed: a local file roster, a backing you
350
+ // wrote, or a hosted one the DEPLOYMENT injects. The engine holds no hosted provider, so with the
351
+ // drain environment set this refuses and names what to wire.
352
+ //
353
+ // THE ORDER HERE IS THE FIX FOR A REAL DEFECT. This used to demand COLTRANE_STORE_URL/_ANON before
354
+ // selecting anything — and both are DRAIN_VARS, so setting COLTRANE_RESIDENCY_DIR produced a
355
+ // backing CONFLICT every time and the local roster could not be selected by any environment on
356
+ // earth. A store credential is the HOSTED backing's requirement, not the verb's: a local seat has
357
+ // no store to point at, and asking it for one made a whole provider unreachable.
358
+ const choice = selectResidencyBacking(env);
359
+ if (choice.backing === "hosted" && (!env["COLTRANE_STORE_URL"] || !env["COLTRANE_STORE_ANON"])) {
360
+ // Said, not silent. A bare exit 2 leaves an operator to guess which of five variables is
361
+ // missing — and leaves the reachability law with nothing only THIS command could have emitted.
362
+ say("reside refused: no_backend (seam: store-env) — the hosted backing needs COLTRANE_STORE_URL and COLTRANE_STORE_ANON.");
363
+ return 2;
364
+ }
365
+ const seat = await resolveSeatBacking(choice, {});
366
+ if (!seat.ok) {
367
+ say(`reside refused: ${seat.refusal} (seam: ${seat.seam}) — ${seat.message}`);
368
+ return resideExitCode(seat.refusal);
369
+ }
370
+ // The seat resolved; the remaining seams (channel, cortex, hands) are per-deployment on every
371
+ // backing, so an unwired one still refuses BY NAME rather than pretending to stand.
372
+ const r = createResidency({ residency }, { ...seat.seat });
373
+ const booted = await r.boot();
374
+ if (!booted.ok) {
375
+ say(`reside refused: ${booted.refusal}${booted.seam ? ` (seam: ${booted.seam})` : ""} — ${booted.message}`);
376
+ return resideExitCode(booted.refusal);
377
+ }
378
+ return 0;
379
+ }
380
+ //# sourceMappingURL=reside.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reside.js","sourceRoot":"","sources":["../../src/reside.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { ResidencyClaim } from "./reside.js";
2
+ /** The local file-backed roster's root. Its PRESENCE selects the local backing. */
3
+ export declare const RESIDENCY_DIR_VAR = "COLTRANE_RESIDENCY_DIR";
4
+ /** A module you wrote, exporting the four seat operations. Its PRESENCE selects the module backing. */
5
+ export declare const RESIDENCY_MODULE_VAR = "COLTRANE_RESIDENCY_MODULE";
6
+ export type ResidencyBackingChoice = {
7
+ backing: "local";
8
+ root: string;
9
+ } | {
10
+ backing: "module";
11
+ spec: string;
12
+ } | {
13
+ backing: "hosted";
14
+ } | {
15
+ backing: "none";
16
+ why: string;
17
+ } | {
18
+ backing: "conflict";
19
+ why: string;
20
+ };
21
+ /** The four seat seams — where the residency ROW lives, and nothing else. */
22
+ export interface SeatBacking {
23
+ claim: (which: string | "any") => Promise<ResidencyClaim | null>;
24
+ heartbeat: (residencyId: string, fence: string) => Promise<void>;
25
+ release: (residencyId: string, fence: string, status: "hibernated" | "unseated") => Promise<void>;
26
+ cursorAdvance: (residencyId: string, fence: string, n: number) => Promise<number>;
27
+ }
28
+ /** Checked IN THIS ORDER, so a refusal names the first thing a hand-built backing forgot. */
29
+ export declare const SEAT_MEMBERS: readonly ["claim", "heartbeat", "release", "cursorAdvance"];
30
+ export type SeatResolution = {
31
+ ok: true;
32
+ seat: SeatBacking;
33
+ backing: "local" | "module" | "hosted";
34
+ } | {
35
+ ok: false;
36
+ refusal: "no_backend" | "backing_conflict";
37
+ seam: string;
38
+ message: string;
39
+ };
40
+ export interface SeatSeed {
41
+ agent_slug: string;
42
+ org: string;
43
+ venue_slug: string;
44
+ channel_id: string;
45
+ }
46
+ export declare function selectResidencyBacking(env: Record<string, string | undefined>): ResidencyBackingChoice;
47
+ /**
48
+ * Resolve a choice to a usable seat, or refuse naming what is missing. A hosted choice resolves ONLY
49
+ * to what a deployment injected — the engine will not conjure one, which is the whole of its
50
+ * platform-agnosticism. `injected.module` is accepted so a hand-built backing can be handed in
51
+ * directly (and so a law can drive one without writing a file).
52
+ */
53
+ export declare function resolveSeatBacking(choice: ResidencyBackingChoice, injected?: {
54
+ hosted?: Partial<SeatBacking>;
55
+ module?: Partial<SeatBacking>;
56
+ }): Promise<SeatResolution>;
57
+ /** Put one seat on a local roster so there is something to claim. The local counterpart of seating. */
58
+ export declare function fileSeatSeed(root: string, seed: SeatSeed): Promise<string>;
59
+ /**
60
+ * A real seat on disk — not a stub. It holds a lease (so two boxes cannot both claim one roster) and
61
+ * it refuses a cursor regression, because a local backing that were laxer than the hosted one it
62
+ * stands in for would let a bug pass locally and fail only in production.
63
+ */
64
+ export declare function fileSeatBacking(root: string): SeatBacking;