@cello-protocol/daemon 0.0.131 → 0.0.133

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 (113) hide show
  1. package/dist/content-park.d.ts.map +1 -1
  2. package/dist/content-park.js +29 -11
  3. package/dist/content-park.js.map +1 -1
  4. package/dist/daemon.d.ts +11 -0
  5. package/dist/daemon.d.ts.map +1 -1
  6. package/dist/daemon.js +398 -18
  7. package/dist/daemon.js.map +1 -1
  8. package/dist/document-ack-inbound.d.ts +57 -0
  9. package/dist/document-ack-inbound.d.ts.map +1 -0
  10. package/dist/document-ack-inbound.js +174 -0
  11. package/dist/document-ack-inbound.js.map +1 -0
  12. package/dist/document-control-notifier.d.ts +61 -0
  13. package/dist/document-control-notifier.d.ts.map +1 -0
  14. package/dist/document-control-notifier.js +70 -0
  15. package/dist/document-control-notifier.js.map +1 -0
  16. package/dist/document-delivery-transport.d.ts +94 -0
  17. package/dist/document-delivery-transport.d.ts.map +1 -0
  18. package/dist/document-delivery-transport.js +179 -0
  19. package/dist/document-delivery-transport.js.map +1 -0
  20. package/dist/document-delivery.d.ts +181 -0
  21. package/dist/document-delivery.d.ts.map +1 -0
  22. package/dist/document-delivery.js +289 -0
  23. package/dist/document-delivery.js.map +1 -0
  24. package/dist/document-frame-router.d.ts +210 -0
  25. package/dist/document-frame-router.d.ts.map +1 -0
  26. package/dist/document-frame-router.js +396 -0
  27. package/dist/document-frame-router.js.map +1 -0
  28. package/dist/document-handlers.d.ts +47 -0
  29. package/dist/document-handlers.d.ts.map +1 -0
  30. package/dist/document-handlers.js +657 -0
  31. package/dist/document-handlers.js.map +1 -0
  32. package/dist/document-handshake.d.ts +156 -0
  33. package/dist/document-handshake.d.ts.map +1 -0
  34. package/dist/document-handshake.js +398 -0
  35. package/dist/document-handshake.js.map +1 -0
  36. package/dist/document-inbound.d.ts +91 -0
  37. package/dist/document-inbound.d.ts.map +1 -0
  38. package/dist/document-inbound.js +290 -0
  39. package/dist/document-inbound.js.map +1 -0
  40. package/dist/document-layer.d.ts +137 -0
  41. package/dist/document-layer.d.ts.map +1 -0
  42. package/dist/document-layer.js +255 -0
  43. package/dist/document-layer.js.map +1 -0
  44. package/dist/document-lifecycle.d.ts +125 -0
  45. package/dist/document-lifecycle.d.ts.map +1 -0
  46. package/dist/document-lifecycle.js +433 -0
  47. package/dist/document-lifecycle.js.map +1 -0
  48. package/dist/document-live-docs.d.ts +58 -0
  49. package/dist/document-live-docs.d.ts.map +1 -0
  50. package/dist/document-live-docs.js +126 -0
  51. package/dist/document-live-docs.js.map +1 -0
  52. package/dist/document-notify.d.ts +173 -0
  53. package/dist/document-notify.d.ts.map +1 -0
  54. package/dist/document-notify.js +438 -0
  55. package/dist/document-notify.js.map +1 -0
  56. package/dist/document-publish.d.ts +67 -0
  57. package/dist/document-publish.d.ts.map +1 -0
  58. package/dist/document-publish.js +149 -0
  59. package/dist/document-publish.js.map +1 -0
  60. package/dist/document-reachability.d.ts +42 -0
  61. package/dist/document-reachability.d.ts.map +1 -0
  62. package/dist/document-reachability.js +80 -0
  63. package/dist/document-reachability.js.map +1 -0
  64. package/dist/document-rejection.d.ts +240 -0
  65. package/dist/document-rejection.d.ts.map +1 -0
  66. package/dist/document-rejection.js +407 -0
  67. package/dist/document-rejection.js.map +1 -0
  68. package/dist/document-store.d.ts +154 -8
  69. package/dist/document-store.d.ts.map +1 -1
  70. package/dist/document-store.js +462 -4
  71. package/dist/document-store.js.map +1 -1
  72. package/dist/document-write-path.d.ts.map +1 -1
  73. package/dist/document-write-path.js +10 -43
  74. package/dist/document-write-path.js.map +1 -1
  75. package/dist/inbound-sessions.d.ts +25 -0
  76. package/dist/inbound-sessions.d.ts.map +1 -1
  77. package/dist/inbound-sessions.js +60 -0
  78. package/dist/inbound-sessions.js.map +1 -1
  79. package/dist/initiate-session-handler.d.ts +24 -1
  80. package/dist/initiate-session-handler.d.ts.map +1 -1
  81. package/dist/initiate-session-handler.js +35 -9
  82. package/dist/initiate-session-handler.js.map +1 -1
  83. package/dist/ipc-server.d.ts +11 -1
  84. package/dist/ipc-server.d.ts.map +1 -1
  85. package/dist/ipc-server.js +7 -1
  86. package/dist/ipc-server.js.map +1 -1
  87. package/dist/line-lcs.d.ts +51 -0
  88. package/dist/line-lcs.d.ts.map +1 -0
  89. package/dist/line-lcs.js +71 -0
  90. package/dist/line-lcs.js.map +1 -0
  91. package/dist/notification-handlers.d.ts +2 -1
  92. package/dist/notification-handlers.d.ts.map +1 -1
  93. package/dist/notification-handlers.js +11 -2
  94. package/dist/notification-handlers.js.map +1 -1
  95. package/dist/outbound-sessions.d.ts +2 -0
  96. package/dist/outbound-sessions.d.ts.map +1 -1
  97. package/dist/outbound-sessions.js +23 -2
  98. package/dist/outbound-sessions.js.map +1 -1
  99. package/dist/session-content-handlers.d.ts.map +1 -1
  100. package/dist/session-content-handlers.js +3 -2
  101. package/dist/session-content-handlers.js.map +1 -1
  102. package/dist/session-node-manager.d.ts +15 -0
  103. package/dist/session-node-manager.d.ts.map +1 -1
  104. package/dist/session-node-manager.js +188 -9
  105. package/dist/session-node-manager.js.map +1 -1
  106. package/dist/vocabulary.d.ts.map +1 -1
  107. package/dist/vocabulary.js +16 -0
  108. package/dist/vocabulary.js.map +1 -1
  109. package/dist/wire-content-hash.d.ts +27 -0
  110. package/dist/wire-content-hash.d.ts.map +1 -0
  111. package/dist/wire-content-hash.js +37 -0
  112. package/dist/wire-content-hash.js.map +1 -0
  113. package/package.json +5 -5
@@ -0,0 +1,255 @@
1
+ /**
2
+ * DOD-DOC-INBOUND-2 / DOD-DOC-DELIVERY-2 — the composition of the document layer.
3
+ *
4
+ * Everything M14 built is a unit with injected seams. This is where they become one thing, and it
5
+ * is a module rather than a block inside `daemon.ts` for one reason: the assembly makes decisions.
6
+ * Which verifier, which live-doc policy, and — the one that matters — whether the layer is present
7
+ * at all.
8
+ *
9
+ * ── ALL OR NOTHING ────────────────────────────────────────────────────────────────────────────
10
+ *
11
+ * The layer is built completely or not built. There is no partially-wired mode, because every
12
+ * half-wiring is a distinct silent failure: an inbound path with no ack producer leaves the peer
13
+ * retrying until their document stalls; a delivery worker with no inbound counterpart publishes
14
+ * envelopes nobody can answer. `DOD-DOC-DELIVERY-2` records that ordering constraint on its own
15
+ * line, and this is where it is enforced instead of remembered.
16
+ *
17
+ * ── THE VERIFIER IS REQUIRED, AND RESOLVES THROUGH THE CALLER ─────────────────────────────────
18
+ *
19
+ * Signature verification needs an agent id → public key mapping, which lives with the daemon's
20
+ * contact and session state rather than here. It is passed in, and there is no default: a default
21
+ * would be a default answer to "is this authentic", and both inbound paths refuse rather than
22
+ * admit when it says no.
23
+ */
24
+ import { verify } from "@cello-protocol/crypto";
25
+ import { DocumentStore } from "./document-store.js";
26
+ import { DocumentEngine } from "./document-engine.js";
27
+ import { DocumentGate } from "./document-gate.js";
28
+ import { DocumentRejections } from "./document-rejection.js";
29
+ import { DocumentInbound } from "./document-inbound.js";
30
+ import { DocumentAckInbound } from "./document-ack-inbound.js";
31
+ import { DocumentFrameRouter } from "./document-frame-router.js";
32
+ import { LiveDocuments } from "./document-live-docs.js";
33
+ import { DocumentLifecycle } from "./document-lifecycle.js";
34
+ import { DocumentNotifications } from "./document-notify.js";
35
+ import { DocumentHandshake } from "./document-handshake.js";
36
+ import { DocumentWritePath } from "./document-write-path.js";
37
+ import { decodeDocumentRejection, buildDocumentRejectionTbs, documentRejectionHash, decodeDocumentProposalAck, buildDocumentProposalAckTbs, decodeDocumentControl, buildDocumentControlTbs, decodeDocumentUpdateEnvelope, encodeDocumentAck, buildDocumentAckTbs, } from "@cello-protocol/protocol-types";
38
+ /**
39
+ * The default `publicKeyFor`: a remote agent's id IS its K_local public key, hex-encoded (M14-D5).
40
+ *
41
+ * `agent_id` in this daemon is a LOCAL primary key on the `agents` table — it names rows in our own
42
+ * database and cannot identify a remote peer. The pubkey is the only self-verifying identifier
43
+ * available: the signature checks against it directly, with no lookup that could be stale, missing
44
+ * or poisoned sitting on the critical path of every authentication.
45
+ *
46
+ * Malformed input returns null rather than throwing, and null is a refusal. An id that is not a
47
+ * 32-byte hex key is not "a peer we have no key for" — it is a frame that does not follow the
48
+ * protocol — but both must refuse, and refusing loudly at the verify step is where it belongs.
49
+ */
50
+ export function agentPublicKeyFromId(agentId) {
51
+ if (!/^[0-9a-f]{64}$/.test(agentId))
52
+ return null;
53
+ return Uint8Array.from(Buffer.from(agentId, "hex"));
54
+ }
55
+ export function createDocumentLayer(deps) {
56
+ const { db, logger } = deps;
57
+ const store = new DocumentStore(db, logger);
58
+ const engine = new DocumentEngine(logger);
59
+ const gate = new DocumentGate(engine, {}, logger);
60
+ const rejections = new DocumentRejections(store, logger);
61
+ // Epoch zero comes from the stored PROPOSAL, not from the envelope log — see `LiveDocuments.get`.
62
+ // Declared before `handshake` exists, so it is resolved lazily; a rebuild only ever happens long
63
+ // after construction.
64
+ const live = new LiveDocuments(store, engine, logger, (ownerAgentId, documentId) => {
65
+ const record = handshake.get(ownerAgentId, documentId);
66
+ return record?.envelope.starting_content ?? null;
67
+ });
68
+ const lifecycle = new DocumentLifecycle(store, logger, { notifyPeer: deps.notifyPeer }, deps.rollback);
69
+ const notifications = new DocumentNotifications(store, logger);
70
+ // THE FILE SURFACE. Built, tested and instantiated NOWHERE until now — the same defect the tool
71
+ // surface had: a complete unit with no production caller reads exactly like a working feature.
72
+ // Without it §4.1's whole premise is missing, because a human collaborating on a document edits a
73
+ // file in their editor, and an agent with file tools reaches for them before any MCP verb.
74
+ const writePath = deps.workspaceRoot ? new DocumentWritePath(engine, deps.workspaceRoot, logger) : null;
75
+ /**
76
+ * One verifier for both paths. Ed25519 (RFC 8032) over the TBS the caller built.
77
+ *
78
+ * An UNKNOWN agent verifies as FALSE, and is logged distinctly. "We have no key for this peer"
79
+ * and "the signature is wrong" both have to refuse — admitting what we cannot authenticate is
80
+ * the outcome the verify step exists to prevent — but they are different things to tell an
81
+ * operator, and only one of them is a peer misbehaving.
82
+ *
83
+ * No try/catch: `verify` already fails closed on a malformed key or signature (its own body is a
84
+ * try returning false), so a catch here would be a branch nothing can reach.
85
+ */
86
+ const verifySignature = (agentId, tbs, signature) => {
87
+ const pubkey = deps.publicKeyFor(agentId);
88
+ if (pubkey === null) {
89
+ logger.warn("document.verify.no_key", { agentId });
90
+ return false;
91
+ }
92
+ return verify(pubkey, tbs, signature);
93
+ };
94
+ const inbound = new DocumentInbound({
95
+ store,
96
+ engine,
97
+ gate,
98
+ rejections,
99
+ logger,
100
+ verifySignature,
101
+ liveDocFor: (ownerAgentId, documentId) => live.get(ownerAgentId, documentId),
102
+ sign: deps.sign,
103
+ });
104
+ const ackInbound = new DocumentAckInbound({ store, rejections, logger, verifySignature });
105
+ // The handshake verifies a proposal against its NAMED proposer — the same resolver, so a forged
106
+ // proposal is refused before it can occupy a document_id (ON CONFLICT DO NOTHING makes the first
107
+ // arrival's bytes permanent for that id).
108
+ const handshake = new DocumentHandshake(db, logger, verifySignature);
109
+ const router = new DocumentFrameRouter({
110
+ inbound,
111
+ ackInbound,
112
+ logger,
113
+ ownerKeyFor: deps.ownerKeyFor,
114
+ recordProposal: (ownerAgentId, wire, nowMs) => {
115
+ // THROWS on a forged or misaddressed proposal, which the router contains and reports. That is
116
+ // right: those are refusals, and nothing should be recorded for them.
117
+ handshake.recordProposal(ownerAgentId, wire, nowMs);
118
+ },
119
+ // `_nowMs` unused: the received-rejection row takes its clock where it is written, and the
120
+ // rejection's own SIGNED timestamp is inside the envelope. A second clock read here would put a
121
+ // third time on one event.
122
+ rewriteFile: async (ownerAgentId, inResponseTo) => {
123
+ if (!writePath)
124
+ return;
125
+ const env = decodeDocumentUpdateEnvelope(inResponseTo);
126
+ const document = store.getDocument(ownerAgentId, env.document_id);
127
+ if (!document)
128
+ return;
129
+ await writePath.materialize(ownerAgentId, env.document_id, document.documentType, live.get(ownerAgentId, env.document_id));
130
+ },
131
+ sendFrameToPeer: async (ownerAgentId, inResponseTo, bytes) => {
132
+ // Addressed to whoever AUTHORED the envelope being answered, taken from the envelope itself
133
+ // rather than from the document row: the row's peer and the envelope's sender are the same
134
+ // party in a two-party document, and reading it from the signed bytes means a refusal can
135
+ // only ever go back to the agent that actually sent the thing refused.
136
+ const env = decodeDocumentUpdateEnvelope(inResponseTo);
137
+ const sent = await deps.sendFrame(ownerAgentId, env.sender_agent_id, bytes);
138
+ if (!sent.ok) {
139
+ logger.warn("document.rejection.unsent", {
140
+ documentId: env.document_id,
141
+ peerAgentId: env.sender_agent_id,
142
+ reason: sent.reason,
143
+ });
144
+ }
145
+ },
146
+ sendAck: async (ownerAgentId, wire, outcome) => {
147
+ const env = decodeDocumentUpdateEnvelope(wire);
148
+ const ack = {
149
+ type: "document_ack",
150
+ // The wire version this build speaks. Inlined rather than imported because protocol-types
151
+ // exports the domain and the codec but not the constant; the decoder pins it by value.
152
+ ack_version: 1,
153
+ document_id: env.document_id,
154
+ envelope_hash: outcome.envelopeHash,
155
+ acker_agent_id: ownerAgentId,
156
+ admitted: outcome.admitted,
157
+ ...(outcome.admitted ? {} : { rejection_reason: outcome.rejectionReason ?? "refused" }),
158
+ acked_at_ms: Date.now(),
159
+ signature: new Uint8Array(0),
160
+ };
161
+ ack.signature = await deps.sign(ownerAgentId, buildDocumentAckTbs(ack));
162
+ // BEST-EFFORT, and it must be: an ack that could not be sent is not a reason to refuse
163
+ // content we have already admitted. The sender redelivers on its own timer, and the
164
+ // redelivery is acked too — which is the case this whole path exists to terminate.
165
+ const sent = await deps.sendFrame(ownerAgentId, env.sender_agent_id, encodeDocumentAck(ack));
166
+ if (!sent.ok) {
167
+ logger.warn("document.ack.unsent", {
168
+ documentId: env.document_id,
169
+ envelopeHash: outcome.envelopeHash,
170
+ reason: sent.reason,
171
+ correlationId: outcome.correlationId,
172
+ });
173
+ }
174
+ },
175
+ recordControl: (ownerAgentId, wire, nowMs) => {
176
+ const control = decodeDocumentControl(wire);
177
+ // VERIFIED FIRST. A kill frame ends a collaboration; unsigned, anyone reaching the channel
178
+ // could end any document between any two parties and each operator would believe the other
179
+ // walked away.
180
+ if (!verifySignature(control.sender_agent_id, buildDocumentControlTbs(control), control.signature)) {
181
+ throw new Error(`document_control_signature_invalid: the ${control.verb} claims to come from ` +
182
+ `${control.sender_agent_id} but its signature does not verify against that agent`);
183
+ }
184
+ const verdict = control.verb === "kill"
185
+ ? lifecycle.recordPeerKill(ownerAgentId, control.document_id, control.sender_agent_id, nowMs)
186
+ : lifecycle.recordPeerClose(ownerAgentId, control.document_id, control.sender_agent_id, nowMs);
187
+ if (!verdict.ok) {
188
+ // Refusals here are real: an unknown document, or a sender who is not this document's peer.
189
+ // Thrown so the router reports them rather than recording an end nobody was entitled to.
190
+ throw new Error(`${verdict.reason}: ${verdict.detail}`);
191
+ }
192
+ },
193
+ recordProposalAck: (ownerAgentId, wire, _nowMs) => {
194
+ const ack = decodeDocumentProposalAck(wire);
195
+ // VERIFIED against the agent it names, before anything is written. A refusal ack makes the
196
+ // proposer stop waiting and, at the surface, reads as "they said no" — so unsigned, anyone on
197
+ // the channel could make a proposal appear refused by a party who never saw it, and the two
198
+ // operators would each believe the other walked away.
199
+ if (!verifySignature(ack.acker_agent_id, buildDocumentProposalAckTbs(ack), ack.signature)) {
200
+ throw new Error(`document_proposal_ack_signature_invalid: the answer claims to come from ` +
201
+ `${ack.acker_agent_id} but its signature does not verify against that agent`);
202
+ }
203
+ // The acker is passed through and CHECKED against the proposal's peer. Verifying the
204
+ // signature proves the frame is authentic; it says nothing about whether its author was
205
+ // entitled to answer this proposal.
206
+ const stored = handshake.recordPeerDecision(ownerAgentId, ack.document_id, ack.acker_agent_id, {
207
+ accepted: ack.accepted,
208
+ ...(ack.refusal_reason !== undefined ? { reason: ack.refusal_reason } : {}),
209
+ decidedAtMs: ack.decided_at_ms,
210
+ });
211
+ if (!stored.ok) {
212
+ // SETTLE ONCE — a contradicting second answer is an error, never an update. A peer that
213
+ // accepted must not be able to later claim it refused, or the proposer tears down a
214
+ // document the peer is still editing.
215
+ throw new Error(`${stored.reason}: ${stored.detail}`);
216
+ }
217
+ },
218
+ recordRejection: (ownerAgentId, wire, _nowMs) => {
219
+ const env = decodeDocumentRejection(wire);
220
+ if (!verifySignature(env.rejecting_agent_id, buildDocumentRejectionTbs(env), env.signature)) {
221
+ // A rejection stops the sender retrying and makes them supersede. Unsigned, anyone on the
222
+ // channel could freeze a document by asserting a refusal nobody made.
223
+ throw new Error(`document_rejection_signature_invalid: the rejection claims to come from ` +
224
+ `${env.rejecting_agent_id} but its signature does not verify against that agent`);
225
+ }
226
+ rejections.recordIncomingRejection(ownerAgentId, env.document_id, {
227
+ rejectionEnvelopeHash: documentRejectionHash(env),
228
+ rejectedEnvelopeHash: env.rejected_envelope_hash,
229
+ reason: env.reason,
230
+ detail: env.detail,
231
+ fromAgentId: env.rejecting_agent_id,
232
+ });
233
+ },
234
+ });
235
+ return {
236
+ store,
237
+ writePath,
238
+ handshake,
239
+ engine,
240
+ live,
241
+ lifecycle,
242
+ notifications,
243
+ rejections,
244
+ router,
245
+ onDocumentFrame: (agentName, _sessionId, content, _senderPubkey, correlationId) =>
246
+ // `agentName` names the owning agent for the session; the router maps it to the owner KEY
247
+ // that scopes the store. The session id and the sender's transport pubkey are unused: a
248
+ // document is bound to its PEER by the handshake, not to whichever session carried the
249
+ // frame, and the envelope's own signed `sender_agent_id` is what the inbound path checks
250
+ // against that binding. Trusting the transport identity instead would let a frame arriving
251
+ // on any session act on any document that session's peer happens to share.
252
+ router.routeSync(agentName, content, Date.now(), correlationId ?? "frame"),
253
+ };
254
+ }
255
+ //# sourceMappingURL=document-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-layer.js","sourceRoot":"","sources":["../src/document-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * DOD-DOC-LIFECYCLE-1 — the verbs (§3.5 + §16.4).
3
+ *
4
+ * Three ways a document can end, and they are not interchangeable. Conflating any two of them
5
+ * makes a promise the protocol cannot keep:
6
+ *
7
+ * close BILATERAL. Both sides ack and the document is complete by agreement. One side's
8
+ * close is a REQUEST — treating it as a conclusion would tell this operator the
9
+ * collaboration ended while the peer is still writing into it.
10
+ * kill UNILATERAL. Stop accepting and publishing, notify the peer, and KEEP the local copy
11
+ * and the log. The peer keeps what it holds, and that is said out loud: it is the one
12
+ * thing an operator is most likely to assume a kill undoes, and the one thing it
13
+ * cannot.
14
+ * withdraw ONE UNDELIVERED update. A local rollback plus a withdrawal record BESIDE the
15
+ * original — marked, never deleted, because a hole in an append-only log is
16
+ * indistinguishable from tampering. Once the peer has it, withdrawal is refused rather
17
+ * than faked.
18
+ *
19
+ * ── THE KILL SWITCH (§16.7-11) ────────────────────────────────────────────────────────────────
20
+ *
21
+ * A platform-paused agent refuses OUTBOUND publishes loudly, still admits INBOUND mechanically,
22
+ * and suppresses notifications. The asymmetry is deliberate. Refusing inbound would surface the
23
+ * pause to the peer as a protocol fault and force a rejection round for something that is not
24
+ * their doing; refusing outbound silently would leave the operator writing into a document that is
25
+ * going nowhere, with their work piling up locally and no sign anything is wrong.
26
+ */
27
+ import type { DocumentStore } from "./document-store.js";
28
+ import type { Logger } from "./types.js";
29
+ /** How the peer is told about a unilateral end. Injected — the transport is not this unit's. */
30
+ export interface LifecycleNotifier {
31
+ notifyPeer(documentId: string, verb: "kill" | "close"): Promise<{
32
+ ok: true;
33
+ } | {
34
+ ok: false;
35
+ reason: string;
36
+ }>;
37
+ }
38
+ export interface DocumentListRow {
39
+ documentId: string;
40
+ peerAgentId: string;
41
+ documentType: string;
42
+ /** Constant in V1, shown because it is seam surface — a field nobody sees cannot be noticed. */
43
+ assuranceTier: string;
44
+ epochId: number;
45
+ status: string;
46
+ pendingDeliveries: number;
47
+ /** Of those, how many have LEFT and are awaiting the peer's confirmation. */
48
+ pendingSent: number;
49
+ /** Of those, how many have not left this machine at all. */
50
+ pendingUnsent: number;
51
+ /** We have closed and the peer has not. */
52
+ closePending: boolean;
53
+ }
54
+ export type Verdict = {
55
+ ok: true;
56
+ } | {
57
+ ok: false;
58
+ reason: string;
59
+ detail: string;
60
+ };
61
+ export declare class DocumentLifecycle {
62
+ #private;
63
+ constructor(store: DocumentStore, logger: Logger, notifier: LifecycleNotifier,
64
+ /**
65
+ * Undo one envelope's operations on the LIVE document, as inverses. Injected because the live
66
+ * `Y.Doc` and its UndoManager belong to the engine, not here — and REQUIRED, because a default
67
+ * that quietly did nothing would restore exactly the defect this argument exists to fix.
68
+ */
69
+ rollback: (ownerAgentId: string, documentId: string, envelopeHash: string) => {
70
+ ok: true;
71
+ } | {
72
+ ok: false;
73
+ reason: string;
74
+ }, senderAgentId?: (ownerAgentId: string) => string);
75
+ list(ownerAgentId: string, nowMs: number): DocumentListRow[];
76
+ /** Our half of a bilateral close. Completes only when the peer's half is also on record. */
77
+ close(ownerAgentId: string, documentId: string, nowMs: number): Promise<(Verdict & {
78
+ ok: true;
79
+ peerNotified: boolean;
80
+ }) | (Verdict & {
81
+ ok: false;
82
+ })>;
83
+ /** The peer's half, arriving over the session. */
84
+ recordPeerClose(ownerAgentId: string, documentId: string, peerAgentId: string, nowMs: number): Verdict;
85
+ /**
86
+ * The peer KILLED the document. Their half of the unilateral end.
87
+ *
88
+ * Terminal immediately, and there is no reciprocal step: a kill is one-sided by definition, which
89
+ * is what separates it from a close. Continuing to publish afterwards would send updates to a
90
+ * party who has stopped listening — refused at their end forever, with nothing on this screen
91
+ * explaining why.
92
+ *
93
+ * The SENDER IS CHECKED against the document's peer for the same reason `recordPeerClose` checks
94
+ * it: without that, any string plus a valid-looking frame ends someone else's document.
95
+ */
96
+ recordPeerKill(ownerAgentId: string, documentId: string, peerAgentId: string, nowMs: number): Verdict;
97
+ /**
98
+ * Unilateral end. Local, and deliberately not contingent on the peer hearing about it — a
99
+ * decision to stop that depends on the other party being online is not a decision to stop.
100
+ */
101
+ kill(ownerAgentId: string, documentId: string, nowMs: number): Promise<{
102
+ ok: true;
103
+ peerNotified: boolean;
104
+ note: string;
105
+ } | {
106
+ ok: false;
107
+ reason: string;
108
+ detail: string;
109
+ }>;
110
+ /**
111
+ * Withdraw ONE undelivered update: a withdrawal record beside the original.
112
+ *
113
+ * Every refusal here is the same shape — say no rather than produce a record that claims
114
+ * something untrue about the log.
115
+ */
116
+ withdraw(ownerAgentId: string, documentId: string, envelopeHash: string, nowMs: number): Verdict;
117
+ setPlatformPaused(agentId: string, paused: boolean, nowMs: number): void;
118
+ isPlatformPaused(agentId: string): boolean;
119
+ /** Outbound. Refused loudly while paused, and while the document has ended. */
120
+ canPublish(ownerAgentId: string, documentId: string): Verdict;
121
+ /** Inbound. A pause does NOT refuse it — see the header. */
122
+ canAdmit(ownerAgentId: string, documentId: string): Verdict;
123
+ shouldNotify(agentId: string): boolean;
124
+ }
125
+ //# sourceMappingURL=document-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-lifecycle.d.ts","sourceRoot":"","sources":["../src/document-lifecycle.ts"],"names":[],"mappings":"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"}