@cotal-ai/manager 0.16.0 → 0.18.0

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.
Files changed (62) hide show
  1. package/README.md +2 -1
  2. package/dist/attach-endpoint.d.ts +53 -59
  3. package/dist/attach-endpoint.d.ts.map +1 -1
  4. package/dist/attach-endpoint.js +120 -244
  5. package/dist/attach-endpoint.js.map +1 -1
  6. package/dist/commands.js +88 -8
  7. package/dist/commands.js.map +1 -1
  8. package/dist/console/app.js +68 -30
  9. package/dist/console/index.html +3 -2
  10. package/dist/console/session-bundle.js +9736 -0
  11. package/dist/console-crypto-shim.d.ts +16 -0
  12. package/dist/console-crypto-shim.d.ts.map +1 -0
  13. package/dist/console-crypto-shim.js +20 -0
  14. package/dist/console-crypto-shim.js.map +1 -0
  15. package/dist/console-session-entry.d.ts +2 -0
  16. package/dist/console-session-entry.d.ts.map +1 -0
  17. package/dist/console-session-entry.js +26 -0
  18. package/dist/console-session-entry.js.map +1 -0
  19. package/dist/endpoint-evict.d.ts +29 -0
  20. package/dist/endpoint-evict.d.ts.map +1 -0
  21. package/dist/endpoint-evict.js +80 -0
  22. package/dist/endpoint-evict.js.map +1 -0
  23. package/dist/holder-liveness.d.ts +40 -0
  24. package/dist/holder-liveness.d.ts.map +1 -0
  25. package/dist/holder-liveness.js +98 -0
  26. package/dist/holder-liveness.js.map +1 -0
  27. package/dist/manager-service-contract.d.ts +132 -0
  28. package/dist/manager-service-contract.d.ts.map +1 -0
  29. package/dist/manager-service-contract.js +332 -0
  30. package/dist/manager-service-contract.js.map +1 -0
  31. package/dist/manager.d.ts +519 -22
  32. package/dist/manager.d.ts.map +1 -1
  33. package/dist/manager.js +2273 -262
  34. package/dist/manager.js.map +1 -1
  35. package/dist/reconcile-gate.d.ts +82 -0
  36. package/dist/reconcile-gate.d.ts.map +1 -0
  37. package/dist/reconcile-gate.js +118 -0
  38. package/dist/reconcile-gate.js.map +1 -0
  39. package/dist/runtime/pty.d.ts.map +1 -1
  40. package/dist/runtime/pty.js +15 -2
  41. package/dist/runtime/pty.js.map +1 -1
  42. package/dist/session/bridge.d.ts +63 -0
  43. package/dist/session/bridge.d.ts.map +1 -0
  44. package/dist/session/bridge.js +157 -0
  45. package/dist/session/bridge.js.map +1 -0
  46. package/dist/session/establish.d.ts +212 -0
  47. package/dist/session/establish.d.ts.map +1 -0
  48. package/dist/session/establish.js +174 -0
  49. package/dist/session/establish.js.map +1 -0
  50. package/dist/session/index.d.ts +12 -0
  51. package/dist/session/index.d.ts.map +1 -0
  52. package/dist/session/index.js +15 -0
  53. package/dist/session/index.js.map +1 -0
  54. package/dist/session/plane.d.ts +120 -0
  55. package/dist/session/plane.d.ts.map +1 -0
  56. package/dist/session/plane.js +327 -0
  57. package/dist/session/plane.js.map +1 -0
  58. package/dist/static-lifecycle.d.ts +97 -0
  59. package/dist/static-lifecycle.d.ts.map +1 -0
  60. package/dist/static-lifecycle.js +262 -0
  61. package/dist/static-lifecycle.js.map +1 -0
  62. package/package.json +10 -6
@@ -0,0 +1,327 @@
1
+ /**
2
+ * The manager's SESSION PLANE (P2 item 6, 6b): offer mint + redeem ENFORCEMENT + PTY-bridge
3
+ * standup. Each live session serves on its OWN short-lived connection under its OWN per-session
4
+ * credential (SPEC 13.6); the standing connection this plane's ledger rides carries no session rail. The manager holds a single {@link ManagerSessionPlane} field; this module
5
+ * keeps manager.ts surgical — the wiring is a boot line, an attach-handler call, and a stop line.
6
+ *
7
+ * STATIC design (item-6, coordinator-ruled): the mint and the redeem COLLAPSE into
8
+ * {@link ManagerSessionPlane.establishAttach}, with the presenter fixed to the AUTHENTICATED attach
9
+ * caller (`ctx.subject.caller`). This is deliberate and buys three things: (1) no un-redeemed-offer
10
+ * window (the offer is born redeemed — a leaked grant releases nothing, and there is no dangling
11
+ * bearer-ish artifact); (2) no new ep command and no `manager-service-contract` churn (item-2 is
12
+ * live-editing that file); (3) redeem enforcement is still core's `redeemSession` — the one-use
13
+ * `issuing` create-CAS plus presenter-equality on the signed grant, unchanged. The WIRE
14
+ * offer/redeem SEPARATION (a second CLI presentation that mints the caller's per-session
15
+ * credential) is the USER-MODE #29 shape; that path stays out of item 6 and refuses loud here.
16
+ *
17
+ * The manager cannot import implementations/auth (implementations never import each other), so the
18
+ * durable ledger is a manager-local {@link kvManagerSessionLedger} over the SAME core row/key
19
+ * types. The full §13.1 lifecycle-gate fence (revision-pinned credential-row staging) belongs to
20
+ * the auth registry and is user-mode's; the static collapsed path fences on the one thing the
21
+ * manager authoritatively knows — its own serving epoch (a successor incarnation's differing epoch
22
+ * loses the finalize re-check) — plus the SERVING credential's own §13.1 gate-checked stage, which
23
+ * is real: the per-session serving credential is minted, staged revision-pinned, released only on
24
+ * the finalize CAS, and revoked by name at the terminal.
25
+ */
26
+ import { Kvm } from "@nats-io/kv";
27
+ import { assertSessionStateTransition, EpEnvelopeError, principalKey, sessionLedgerKey, } from "@cotal-ai/core";
28
+ import { mintAttachOffer, staticRedemptionSeam, ManagerSessionRegistry } from "./establish.js";
29
+ import { serveSessionBridge } from "./bridge.js";
30
+ const TERMINAL = new Set(["closed", "expired", "superseded", "retired"]);
31
+ /** A manager-local {@link SessionLedger} over `session.<id>` rows in the DEDICATED sessions bucket
32
+ * KV (never the auth bucket — §13.9 subject-blindness confinement). Drives the SAME core row/key
33
+ * types as implementations/auth's ledger with the manager's own KV CAS: the
34
+ * one-use is `createIssuing`'s create-only CAS; finalize/terminal/revoke are revision-pinned
35
+ * updates (a lost CAS returns false / retries on the next sweep, never a silent overwrite). */
36
+ export function kvManagerSessionLedger(kv) {
37
+ const dec = (v) => JSON.parse(new TextDecoder().decode(v));
38
+ const enc = (r) => new TextEncoder().encode(JSON.stringify(r));
39
+ return {
40
+ async read(id) {
41
+ const e = await kv.get(sessionLedgerKey(id));
42
+ return e && e.operation === "PUT" ? dec(e.value) : undefined;
43
+ },
44
+ async createIssuing(row) {
45
+ try {
46
+ await kv.create(sessionLedgerKey(row.sessionId), enc(row));
47
+ return "created";
48
+ }
49
+ catch {
50
+ return "exists"; // the one-use is burned (create-only CAS lost)
51
+ }
52
+ },
53
+ async finalizeActive(id) {
54
+ const e = await kv.get(sessionLedgerKey(id));
55
+ if (!e || e.operation !== "PUT")
56
+ return false;
57
+ const row = dec(e.value);
58
+ if (row.state !== "issuing")
59
+ return false;
60
+ assertSessionStateTransition(row.state, "active");
61
+ row.state = "active";
62
+ try {
63
+ await kv.update(sessionLedgerKey(id), enc(row), e.revision);
64
+ return true;
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ },
70
+ async transitionTerminal(id, to) {
71
+ const e = await kv.get(sessionLedgerKey(id));
72
+ if (!e || e.operation !== "PUT")
73
+ return false;
74
+ const row = dec(e.value);
75
+ if (TERMINAL.has(row.state))
76
+ return false;
77
+ assertSessionStateTransition(row.state, to);
78
+ row.state = to;
79
+ try {
80
+ await kv.update(sessionLedgerKey(id), enc(row), e.revision);
81
+ return true;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ },
87
+ async markRevoked(id, credId) {
88
+ const e = await kv.get(sessionLedgerKey(id));
89
+ if (!e || e.operation !== "PUT")
90
+ return;
91
+ const row = dec(e.value);
92
+ if (credId === row.credCaller)
93
+ row.revoked.caller = true;
94
+ else if (credId === row.credServing)
95
+ row.revoked.serving = true;
96
+ else
97
+ return;
98
+ try {
99
+ await kv.update(sessionLedgerKey(id), enc(row), e.revision);
100
+ }
101
+ catch { /* the next sweep retries */ }
102
+ },
103
+ };
104
+ }
105
+ /** The default global live-session ceiling. Configurable per manager
106
+ * ({@link ManagerSessionPlaneDeps.maxSessions}) because the right number is deployment-shaped: the
107
+ * browser console opens a session PER PANE, so a dashboard over a large mesh legitimately holds
108
+ * many at once, and a ceiling low enough to feel like a bound would break it. */
109
+ export const MAX_LIVE_SESSIONS_DEFAULT = 64;
110
+ export class ManagerSessionPlane {
111
+ #deps;
112
+ #registry = new ManagerSessionRegistry();
113
+ #live = new Map();
114
+ #ledger;
115
+ #maxSessions;
116
+ /** In-flight establishments that have claimed a slot but are not yet live (see {@link claimSlot}). */
117
+ #reserved = 0;
118
+ constructor(deps) {
119
+ this.#deps = deps;
120
+ this.#ledger = kvManagerSessionLedger(deps.ledgerKv);
121
+ this.#maxSessions = deps.maxSessions ?? MAX_LIVE_SESSIONS_DEFAULT;
122
+ if (!Number.isSafeInteger(this.#maxSessions) || this.#maxSessions < 1)
123
+ throw new Error(`maxSessions must be a positive integer; got ${JSON.stringify(deps.maxSessions)}`);
124
+ }
125
+ /** Mint an offer for the authenticated attach caller, enforce its one-use redemption, and stand
126
+ * up the PTY bridge — all atomically. Returns the HOLDER-BOUND grant (the attach reply): no URL,
127
+ * and it must never be logged. Throws on a redeem refusal (a foreign presenter, an already-live
128
+ * session, a stale serving epoch). */
129
+ async establishAttach(caller, target, session,
130
+ /** A slot already claimed by an establisher in front of this one ({@link claimSlot}), so the
131
+ * reservation covers ITS side effects too (the PTY attach above all). Omitted = claim here. */
132
+ claimed) {
133
+ // The ceiling slot is CLAIMED here — or by the establisher in front of us, which passes its
134
+ // claim in — and therefore before the offer mint and before any credential, connection or PTY
135
+ // attach exists: a refused establishment costs a signature verification, never a credential, a
136
+ // socket or an attach. The refusal names the ceiling and its value so an operator who hits it
137
+ // knows what to raise (see ManagerSessionPlaneDeps.maxSessions for the per-caller residual).
138
+ const slot = claimed ?? this.claimSlot();
139
+ try {
140
+ return await this.#establishClaimed(caller, target, session, slot);
141
+ }
142
+ finally {
143
+ // The leak-proof backstop: EVERY exit releases, so a throw from anywhere in the body — the
144
+ // mint included, which runs before the try below — can never strand capacity. Idempotent, so
145
+ // it never double-counts against the release at the live-occupancy hand-off.
146
+ slot.release();
147
+ }
148
+ }
149
+ /** {@link establishAttach}'s body, under an already-claimed slot. Split out ONLY so the claim has
150
+ * a `finally` that covers the whole establishment, mint included. */
151
+ async #establishClaimed(caller, target, session, slot) {
152
+ const holderId = principalKey(caller.owner, caller.actor).key;
153
+ // Collapsed static path: the offer is redeemed at mint, so there is no un-redeemed window for a
154
+ // caller restart to invalidate — the holder process-epoch fence is a no-op here (user-mode #29
155
+ // wires the real lifecycle-registry read). serving epoch IS enforced (a successor loses).
156
+ const holder = { id: holderId, lifecycleUid: caller.uid, processEpoch: 0 };
157
+ const offer = mintAttachOffer({
158
+ space: this.#deps.space,
159
+ serving: this.#deps.serving,
160
+ holder,
161
+ target,
162
+ signer: this.#deps.signer,
163
+ ttlMs: this.#deps.ttlMs,
164
+ ...(this.#deps.window !== undefined ? { window: this.#deps.window } : {}),
165
+ ...(this.#deps.now ? { now: this.#deps.now() } : {}),
166
+ });
167
+ this.#registry.record(offer);
168
+ const sessionId = offer.grant.sessionId;
169
+ const serving = this.#deps.serving;
170
+ const seam = staticRedemptionSeam({
171
+ space: this.#deps.space,
172
+ resolveAnchor: this.#deps.resolveAnchor,
173
+ ledger: this.#ledger,
174
+ serving: this.#deps.servingCredential,
175
+ holderProcessEpoch: () => holder.processEpoch,
176
+ servingEpoch: () => serving.epoch,
177
+ // The HOLDER gate is a placeholder in the static path: the holder is an operator CLI, which
178
+ // has no §13.1 lifecycle gate to observe. It fences nothing, and is not described as if it
179
+ // does — user mode (#29) supplies the real lifecycle-registry read.
180
+ observeHolderGate: (h) => ({ key: `holder.${h.lifecycleUid}`, revision: 1 }),
181
+ // The SERVING gate is REAL: the credential seam observes this instance's own
182
+ // `epgate.manager.<instanceId>` leader-served, and the stage below is revision-pinned to it.
183
+ observeServingGate: (endpoint, instanceId) => this.#deps.servingCredential.observeGate(endpoint, instanceId),
184
+ ...(this.#deps.now ? { now: this.#deps.now } : {}),
185
+ });
186
+ let cred;
187
+ let nc;
188
+ try {
189
+ // One-use CAS + presenter-equality + the gate-pinned serving-credential stage + finalize.
190
+ await seam.redeem(offer.grant, { id: holder.id, lifecycleUid: holder.lifecycleUid });
191
+ // Only now is the row `active`, so only now is the credential authority (§13.6). Retrieved
192
+ // through the serving party's own authenticated path, never out of the redemption answer.
193
+ cred = await seam.serving(sessionId, { endpoint: offer.grant.endpoint, instanceId: serving.instanceId, epoch: serving.epoch });
194
+ nc = await this.#deps.servingCredential.open(cred); // fails loud; there is no shared connection to fall back to
195
+ }
196
+ catch (e) {
197
+ this.#registry.remove(sessionId);
198
+ // A failure anywhere after the one-use was burned leaves a row that must not stay live: mark
199
+ // it terminal and revoke whatever was staged. Best-effort — the §13.6 expiry sweep is the
200
+ // durable backstop, and the original refusal is what the caller must see.
201
+ await this.#collect(sessionId, "closed").catch(() => { });
202
+ throw e;
203
+ }
204
+ const bridge = serveSessionBridge({
205
+ nc,
206
+ grant: offer.grant,
207
+ session,
208
+ onEnd: () => { void this.#teardown(sessionId); },
209
+ ...(this.#deps.now ? { now: this.#deps.now } : {}),
210
+ });
211
+ // Occupancy transfers from the reservation to the live map with no `await` between, so the slot
212
+ // is counted exactly once throughout and a concurrent claim can never see it free twice.
213
+ this.#live.set(sessionId, { bridge, nc, credentialId: cred.id });
214
+ slot.release();
215
+ return { grant: offer.grant };
216
+ }
217
+ /**
218
+ * Retire one session's serving side. ORDER IS LOAD-BEARING: the connection closes FIRST and
219
+ * unconditionally, because closing it is the immediate kill and must not be contingent on a
220
+ * durable write succeeding. The ledger transition and the credential revoke follow; if either
221
+ * fails the rail is already dead, the row keeps its unmarked credential id, and §13.6's sweep
222
+ * retries exactly that id on every later pass. Idempotent.
223
+ */
224
+ async #teardown(sessionId, state = "closed") {
225
+ const live = this.#live.get(sessionId);
226
+ this.#live.delete(sessionId);
227
+ this.#registry.remove(sessionId);
228
+ if (live) {
229
+ try {
230
+ await live.nc.drain();
231
+ }
232
+ catch {
233
+ try {
234
+ live.nc.close();
235
+ }
236
+ catch { /* already gone */ }
237
+ }
238
+ }
239
+ await this.#collect(sessionId, state);
240
+ }
241
+ /** Move the ledger row terminal and revoke the serving credential by name, marking the revoke
242
+ * only when it SUCCEEDED (§13.6: an unmarked id is what makes the sweep's retry real). */
243
+ async #collect(sessionId, state) {
244
+ let row;
245
+ try {
246
+ row = await this.#ledger.read(sessionId);
247
+ }
248
+ catch { /* unreadable: the sweep still collects it */ }
249
+ try {
250
+ await this.#ledger.transitionTerminal(sessionId, state);
251
+ }
252
+ catch { /* sweep backstop */ }
253
+ if (!row)
254
+ return;
255
+ try {
256
+ await this.#deps.servingCredential.revoke(row.credServing);
257
+ await this.#ledger.markRevoked(sessionId, row.credServing);
258
+ }
259
+ catch {
260
+ /* the mark stays unset — the §13.6 sweep retries exactly this id */
261
+ }
262
+ }
263
+ /** End every session bound to a target incarnation, with a distinct reason — the despawn/restart
264
+ * hook (the successor incarnation's differing epoch already refuses old-epoch redemptions; this
265
+ * proactively tears the live bridges down and surfaces the reason to each client). The bridge's
266
+ * own `onEnd` drives {@link #teardown}, so the connection and credential go with it. */
267
+ endForTarget(name, lifecycleUid, reason) {
268
+ for (const id of this.#registry.forTarget(name, lifecycleUid))
269
+ this.#live.get(id)?.bridge.end(reason);
270
+ }
271
+ /** End all live sessions (manager stop / drain). */
272
+ endAll(reason) {
273
+ for (const live of [...this.#live.values()])
274
+ live.bridge.end(reason);
275
+ }
276
+ /** Await every in-flight teardown (manager stop): the bridges' `onEnd` teardown is async, so a
277
+ * synchronous `endAll` alone would let the process exit with connections still draining. */
278
+ async drain(reason) {
279
+ this.endAll(reason);
280
+ await Promise.all([...this.#live.keys()].map((id) => this.#teardown(id, "closed").catch(() => { })));
281
+ }
282
+ get liveSessions() {
283
+ return this.#live.size;
284
+ }
285
+ /** The configured global ceiling (surfaced so an operator-facing status can report it). */
286
+ get maxSessions() {
287
+ return this.#maxSessions;
288
+ }
289
+ /**
290
+ * CLAIM a session slot, or refuse loudly. ONE implementation, called by {@link establishAttach}
291
+ * and by every establisher in front of it, so the two cannot drift into disagreeing about
292
+ * capacity. It must run before ANY of: minting the offer, redeeming it, minting a per-session
293
+ * credential on either side, opening a connection, or attaching the target's PTY.
294
+ *
295
+ * THIS RESERVES, IT DOES NOT MERELY CHECK. A bare read of the live count would be check-then-act:
296
+ * establishment awaits a mint, a redemption and a connection before the session becomes live, so
297
+ * two concurrent establishes at `max - 1` would both observe room, both mint credentials, and
298
+ * both land — overshooting the ceiling by exactly the concurrency the HTTP face already has, and
299
+ * over-minting the seed-signed credentials the ceiling exists to bound. Occupancy is therefore
300
+ * live sessions PLUS in-flight reservations, and the increment happens with no `await` between
301
+ * the read and the write, so on a single-threaded runtime no second establishment can interleave.
302
+ *
303
+ * The returned release is idempotent: the caller releases on every failure path, and
304
+ * {@link establishAttach} releases at the same instant it records the live session, so a slot is
305
+ * counted once and never twice.
306
+ *
307
+ * The message names the ceiling and its current value: an operator who hits it should not have to
308
+ * read source to learn which knob to raise.
309
+ */
310
+ claimSlot() {
311
+ if (this.#live.size + this.#reserved >= this.#maxSessions)
312
+ throw new EpEnvelopeError("resource-exhausted", `the manager is already serving its maximum of ${this.#maxSessions} concurrent sessions (raise ManagerOptions.maxSessions); no session was established and no credential was minted (SPEC 13.6)`);
313
+ this.#reserved++;
314
+ let released = false;
315
+ return { release: () => { if (!released) {
316
+ released = true;
317
+ this.#reserved--;
318
+ } } };
319
+ }
320
+ }
321
+ /** Open the DEDICATED sessions-bucket KV a plane's ledger needs (the `session.<id>` rows live in
322
+ * the §13.6 session store — {@link sessionsBucket}, NOT the auth bucket). Split out so the manager
323
+ * can build the plane from its own bucket handle. */
324
+ export async function openSessionLedgerKv(nc, bucket) {
325
+ return new Kvm(nc).open(bucket);
326
+ }
327
+ //# sourceMappingURL=plane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plane.js","sourceRoot":"","sources":["../../src/session/plane.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * The STATIC §13.1 lifecycle executor (Unit B): the manager-side adapter that drives the ONE
3
+ * shared core saga (`@cotal-ai/core` lifecycle-saga) over a direct-KV
4
+ * {@link LifecycleStateTransport}, plus the static executor's OWN orchestration — the durable
5
+ * slot mapping (F3 outer spawn intent + the F5-bind alias -> (owner, actor, uid) join), the
6
+ * static credential-ledger rows, and the F1 terminal sequence.
7
+ *
8
+ * Three-way split (the Unit B design note, panel-locked): the key/value GRAMMAR lives in core
9
+ * `lifecycle-state.ts`; the CAS SEQUENCING is the shared core saga this module DELEGATES to
10
+ * (never a hand-ordered local copy); the barrier ORCHESTRATION here is the static executor's
11
+ * own (revoke from the slot's recorded credentialIds, best-effort eviction = the child process
12
+ * kill the manager already did, footprint cleanup via the manager's deprovision hooks).
13
+ *
14
+ * F5-bind (the F4 restatement): the wire AUTHORITY coordinate is the incarnation-unique nkey
15
+ * (`actor`); the ALIAS is routing only, protected by the name-keyed slot row + uid reservation +
16
+ * the manager's freeSlot hold — never by the head CAS alone (the head is principal-keyed).
17
+ */
18
+ import { type LifecycleStateTransport, type StaticManagedSlotRow } from "@cotal-ai/core";
19
+ import type { KV } from "@nats-io/kv";
20
+ /** The direct-KV transport over the two authority stores, bound per lifecycle OPERATION on an
21
+ * ephemeral, key-pinned `lifecycle-executor` connection (the manager mints it; see
22
+ * `withLifecycleExecutor`). Mirrors the auth implementation's sealed `transportOf` — a
23
+ * transport carries no sequencing decisions of its own. */
24
+ export declare function staticLifecycleTransport(recordsKv: KV, authKv: KV): LifecycleStateTransport;
25
+ /** Read one slot row (DEL/PURGE marker = corruption, never absence — supervision state is
26
+ * CASed over, never deleted). */
27
+ export declare function readStaticSlot(t: LifecycleStateTransport, owner: string, alias: string): Promise<{
28
+ row: StaticManagedSlotRow;
29
+ revision: number;
30
+ } | undefined>;
31
+ /** Persist the F3 durable OUTER spawn intent — phase `provisioning`, written BEFORE the head
32
+ * activation so a crash between them leaves a discoverable coordinate (the boot sweep or the
33
+ * next same-alias spawn re-drives it). Create-only for a virgin alias; a CAS over the RETIRED
34
+ * predecessor row for a reused alias; anything else is a live/terminalizing/crashed slot and
35
+ * REFUSES loudly (the caller resolves it first — resume or terminal, never silent adoption). */
36
+ export declare function writeStaticSlotIntent(t: LifecycleStateTransport, row: Omit<StaticManagedSlotRow, "phase" | "credentialIds">): Promise<{
37
+ revision: number;
38
+ }>;
39
+ /** CAS a slot row to a new phase/content at its observed revision. */
40
+ export declare function casStaticSlot(t: LifecycleStateTransport, row: StaticManagedSlotRow, revision: number): Promise<number>;
41
+ /** Record a credentialId on the slot BEFORE its ledger row is appended and BEFORE the cred is
42
+ * minted (the crash-safe order: slot record -> ledger row -> mint/write; a credential never
43
+ * exists without its id recorded and its row appended first). */
44
+ export declare function recordSlotCredential(t: LifecycleStateTransport, owner: string, alias: string, lifecycleUid: string, credentialId: string): Promise<void>;
45
+ /** Append this incarnation's credential-ledger row (`cred.<uid>.<credId>`, state `active`,
46
+ * lineage `root` — the manager's seed IS the root authority in static mode). Create-only;
47
+ * an existing SAME row is crash-resume idempotence, anything else refuses. */
48
+ export declare function appendStaticCredentialRow(t: LifecycleStateTransport, args: {
49
+ lifecycleUid: string;
50
+ credentialId: string;
51
+ holderPrincipal: string;
52
+ exp: number;
53
+ }): Promise<void>;
54
+ /** The static terminal's B1 revoke: CAS every recorded row `active -> revoked`. Enumeration is
55
+ * the SLOT's recorded credentialIds (recorded before every mint), never a store listing. An
56
+ * ABSENT row is the legitimate crash window (id recorded, mint never reached) — no credential
57
+ * exists for it, logged and skipped; a revoked row is idempotence. */
58
+ export declare function revokeStaticCredentialRows(t: LifecycleStateTransport, lifecycleUid: string, credentialIds: readonly string[], log: (line: string) => void): Promise<void>;
59
+ /** The static ACTIVATION: F3 intent FIRST (durable outer spawn intent, phase `provisioning`),
60
+ * then the SHARED core activation saga at the spawn's uid (reserve -> gate frozen -> head CAS
61
+ * -> reopen LAST). Returns the slot revision the spawn path later CASes to `active` once the
62
+ * managed row owns the slot. */
63
+ export declare function activateStaticLifecycle(t: LifecycleStateTransport, args: {
64
+ owner: string;
65
+ alias: string;
66
+ actor: string;
67
+ lifecycleUid: string;
68
+ managerInstance: string;
69
+ ownerInstanceId: string;
70
+ }): Promise<{
71
+ slotRevision: number;
72
+ }>;
73
+ /** The static TERMINAL (F1, the (b2) order): freeze-under-the-retirement-op -> head
74
+ * `active -> retiring` -> B1 ledger revoke -> cleanup (the injected footprint teardown; the
75
+ * process kill — static "eviction" — already happened on the manager's stop path) -> gate
76
+ * `frozen -> retired` -> head `retiring -> retired` LAST -> slot `retired` (the alias frees).
77
+ * Every gate/head step DELEGATES to the shared core saga; recovery recognizes a SAME-OP
78
+ * terminal gate and finishes the head (the lost-ack alias wedge the panel closed).
79
+ *
80
+ * Total over partial durable state: an alias whose activation never reached the saga (slot
81
+ * `provisioning`, no gate) terminalizes by slot alone; a crashed activation frozen by its own
82
+ * activation op is terminalized THROUGH that op (gateRetire is op-pinned) — the exact-op static
83
+ * retirement F3 requires. */
84
+ export declare function runStaticTerminal(t: LifecycleStateTransport, args: {
85
+ owner: string;
86
+ alias: string;
87
+ actor: string;
88
+ lifecycleUid: string;
89
+ opId: string;
90
+ }, hooks: {
91
+ cleanup: () => Promise<void>;
92
+ log: (line: string) => void;
93
+ }): Promise<"retired">;
94
+ /** The boot-sweep resume decision, TOTAL over the phase enum (F3): what the manager must do
95
+ * with a durable slot it did not adopt from a live inventory. */
96
+ export declare function planStaticSlotResume(row: StaticManagedSlotRow, adopted: boolean): "none" | "drive-terminal";
97
+ //# sourceMappingURL=static-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-lifecycle.d.ts","sourceRoot":"","sources":["../src/static-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAEL,KAAK,uBAAuB,EAE5B,KAAK,oBAAoB,EAkB1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAItC;;;4DAG4D;AAC5D,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,uBAAuB,CAU3F;AAED;kCACkC;AAClC,wBAAsB,cAAc,CAClC,CAAC,EAAE,uBAAuB,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,GAAG,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAOtE;AAED;;;;iGAIiG;AACjG,wBAAsB,qBAAqB,CACzC,CAAC,EAAE,uBAAuB,EAC1B,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,eAAe,CAAC,GACzD,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAW/B;AAED,sEAAsE;AACtE,wBAAsB,aAAa,CACjC,CAAC,EAAE,uBAAuB,EAC1B,GAAG,EAAE,oBAAoB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;kEAEkE;AAClE,wBAAsB,oBAAoB,CACxC,CAAC,EAAE,uBAAuB,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;+EAE+E;AAC/E,wBAAsB,yBAAyB,CAC7C,CAAC,EAAE,uBAAuB,EAC1B,IAAI,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACzF,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;uEAGuE;AACvE,wBAAsB,0BAA0B,CAC9C,CAAC,EAAE,uBAAuB,EAC1B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;iCAGiC;AACjC,wBAAsB,uBAAuB,CAC3C,CAAC,EAAE,uBAAuB,EAC1B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAC5H,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAWnC;AAED;;;;;;;;;;8BAU8B;AAC9B,wBAAsB,iBAAiB,CACrC,CAAC,EAAE,uBAAuB,EAC1B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACzF,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GACnE,OAAO,CAAC,SAAS,CAAC,CAoFpB;AAED;kEACkE;AAClE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,gBAAgB,CAsB3G"}