@cello-protocol/daemon 0.0.167 → 0.0.169
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.
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +115 -254
- package/dist/daemon.js.map +1 -1
- package/dist/document-amendment-store.d.ts +94 -46
- package/dist/document-amendment-store.d.ts.map +1 -1
- package/dist/document-amendment-store.js +217 -102
- package/dist/document-amendment-store.js.map +1 -1
- package/dist/document-delivery-transport.d.ts +41 -52
- package/dist/document-delivery-transport.d.ts.map +1 -1
- package/dist/document-delivery-transport.js +6 -156
- package/dist/document-delivery-transport.js.map +1 -1
- package/dist/document-frame-router.d.ts +13 -17
- package/dist/document-frame-router.d.ts.map +1 -1
- package/dist/document-frame-router.js +21 -93
- package/dist/document-frame-router.js.map +1 -1
- package/dist/document-handlers.d.ts +1 -1
- package/dist/document-handlers.d.ts.map +1 -1
- package/dist/document-handlers.js +471 -466
- package/dist/document-handlers.js.map +1 -1
- package/dist/document-handshake.d.ts +4 -1
- package/dist/document-handshake.d.ts.map +1 -1
- package/dist/document-handshake.js +3 -1
- package/dist/document-handshake.js.map +1 -1
- package/dist/document-inbound.d.ts +18 -5
- package/dist/document-inbound.d.ts.map +1 -1
- package/dist/document-inbound.js +94 -110
- package/dist/document-inbound.js.map +1 -1
- package/dist/document-layer.d.ts +28 -67
- package/dist/document-layer.d.ts.map +1 -1
- package/dist/document-layer.js +670 -565
- package/dist/document-layer.js.map +1 -1
- package/dist/document-lifecycle.d.ts +11 -157
- package/dist/document-lifecycle.d.ts.map +1 -1
- package/dist/document-lifecycle.js +26 -561
- package/dist/document-lifecycle.js.map +1 -1
- package/dist/document-publish.d.ts +13 -0
- package/dist/document-publish.d.ts.map +1 -1
- package/dist/document-publish.js +19 -11
- package/dist/document-publish.js.map +1 -1
- package/dist/document-reconcile-engine.d.ts +66 -0
- package/dist/document-reconcile-engine.d.ts.map +1 -0
- package/dist/document-reconcile-engine.js +225 -0
- package/dist/document-reconcile-engine.js.map +1 -0
- package/dist/document-reconcile-scheduler.d.ts +91 -0
- package/dist/document-reconcile-scheduler.d.ts.map +1 -0
- package/dist/document-reconcile-scheduler.js +153 -0
- package/dist/document-reconcile-scheduler.js.map +1 -0
- package/dist/document-rejection.d.ts +2 -0
- package/dist/document-rejection.d.ts.map +1 -1
- package/dist/document-rejection.js +5 -1
- package/dist/document-rejection.js.map +1 -1
- package/dist/document-store.d.ts +18 -220
- package/dist/document-store.d.ts.map +1 -1
- package/dist/document-store.js +95 -717
- package/dist/document-store.js.map +1 -1
- package/dist/initiate-session-handler.d.ts +5 -0
- package/dist/initiate-session-handler.d.ts.map +1 -1
- package/dist/initiate-session-handler.js +1 -0
- package/dist/initiate-session-handler.js.map +1 -1
- package/package.json +5 -5
- package/dist/delivery-sweep-bound.d.ts +0 -79
- package/dist/delivery-sweep-bound.d.ts.map +0 -1
- package/dist/delivery-sweep-bound.js +0 -109
- package/dist/delivery-sweep-bound.js.map +0 -1
- package/dist/document-ack-inbound.d.ts +0 -71
- package/dist/document-ack-inbound.d.ts.map +0 -1
- package/dist/document-ack-inbound.js +0 -210
- package/dist/document-ack-inbound.js.map +0 -1
- package/dist/document-control-notifier.d.ts +0 -107
- package/dist/document-control-notifier.d.ts.map +0 -1
- package/dist/document-control-notifier.js +0 -137
- package/dist/document-control-notifier.js.map +0 -1
- package/dist/document-delivery.d.ts +0 -229
- package/dist/document-delivery.d.ts.map +0 -1
- package/dist/document-delivery.js +0 -449
- package/dist/document-delivery.js.map +0 -1
- package/dist/document-join-store.d.ts +0 -80
- package/dist/document-join-store.d.ts.map +0 -1
- package/dist/document-join-store.js +0 -197
- package/dist/document-join-store.js.map +0 -1
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DOD-DOC-DELIVERY-1 — daemon-autonomous delivery (§16.4).
|
|
3
|
-
*
|
|
4
|
-
* Publish writes the envelope to the log and returns. Delivery is somebody else's job, and that
|
|
5
|
-
* somebody is this worker: it derives what is pending FROM THE LOG, checks the peer is reachable
|
|
6
|
-
* before dialing, opens or reuses a session itself, delivers, and records the ack — with zero agent
|
|
7
|
-
* attention on either end. Two agents in opposite time zones sync overnight without either agent
|
|
8
|
-
* doing anything.
|
|
9
|
-
*
|
|
10
|
-
* ── PENDING IS DERIVED, NEVER HELD ────────────────────────────────────────────────────────────
|
|
11
|
-
*
|
|
12
|
-
* "Unacknowledged envelopes I authored" is a WHERE clause over the log, and that is the whole
|
|
13
|
-
* definition. A queue in memory does not survive a restart — the daemon is a long-running local
|
|
14
|
-
* process that gets restarted routinely — and a queue in its own table is a second source of truth
|
|
15
|
-
* that can disagree with the log about what was sent. The attempt counter and the next-attempt
|
|
16
|
-
* time live on the envelope row for the same reason: a backoff that resets on restart is not a
|
|
17
|
-
* backoff, and a daemon restarting in a reconnect loop would hammer an unreachable peer at full
|
|
18
|
-
* rate forever.
|
|
19
|
-
*
|
|
20
|
-
* ── WHY LOOKUP BEFORE DIAL ────────────────────────────────────────────────────────────────────
|
|
21
|
-
*
|
|
22
|
-
* §16.4's design is presence-driven push, but there is no presence subscription today (parked,
|
|
23
|
-
* M14-P4). Without one, the honest substitute is: ask the directory whether the peer is reachable,
|
|
24
|
-
* and if it is not, do not burn a dial — schedule a retry on a capped backoff. Dialing an offline
|
|
25
|
-
* peer to find out it is offline is the same information at much higher cost, and it is the cost
|
|
26
|
-
* that would be paid on every pending envelope, on every tick, for as long as the peer is away.
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* Backoff schedule in ms: ~1s, 5s, 30s, 2m, 10m, then the last entry repeats.
|
|
30
|
-
*
|
|
31
|
-
* The final entry IS the cap — there is no separate ceiling constant. There was one, set to 900s,
|
|
32
|
-
* and it was unreachable: the index clamp meant the schedule never produced a value above 600s, so
|
|
33
|
-
* the exported "cap" was a number the code could not emit and the tests were using it as a synonym
|
|
34
|
-
* for "much later". A documented limit the implementation cannot reach is worse than none.
|
|
35
|
-
*
|
|
36
|
-
* Capped at all because the peer coming back online is the event we are waiting for and it can
|
|
37
|
-
* happen at any moment — an uncapped curve leaves a peer that returned after a long absence waiting
|
|
38
|
-
* hours for a delivery that has been ready the whole time.
|
|
39
|
-
*/
|
|
40
|
-
/**
|
|
41
|
-
* Total ack-grace one sweep pass may spend, across every agent, document and envelope in it.
|
|
42
|
-
*
|
|
43
|
-
* The wait exists so a session we opened is not torn down before the peer's answer arrives. It is
|
|
44
|
-
* capped as a PASS budget because the loops it sits inside are sequential: a per-envelope allowance
|
|
45
|
-
* meant one silent peer with a backlog could hold the sweep for the better part of an hour, and the
|
|
46
|
-
* only symptom would be other agents' documents quietly not syncing.
|
|
47
|
-
*
|
|
48
|
-
* 30s ≈ three full graces. Enough for the ordinary case (one or two opened sessions per pass, ack
|
|
49
|
-
* back in well under a second) without letting an unresponsive peer own the pass.
|
|
50
|
-
*/
|
|
51
|
-
export const DELIVERY_ACK_GRACE_BUDGET_MS = 30_000;
|
|
52
|
-
export const DELIVERY_BACKOFF_MS = [1_000, 5_000, 30_000, 120_000, 600_000];
|
|
53
|
-
export const DELIVERY_BACKOFF_CAP_MS = DELIVERY_BACKOFF_MS[DELIVERY_BACKOFF_MS.length - 1];
|
|
54
|
-
/**
|
|
55
|
-
* How long to wait for an ACK after a SUCCESSFUL send, before sending again.
|
|
56
|
-
*
|
|
57
|
-
* Deliberately NOT the failure backoff. "How long do I wait after a failure" and "how long do I
|
|
58
|
-
* wait for an answer" are different questions, and reusing the first for the second re-sent a
|
|
59
|
-
* successfully-delivered envelope one second later — and every resend is not free: `sendContent`
|
|
60
|
-
* witnesses a message-leaf hash to the relay and appends a leaf to the session chain, so a
|
|
61
|
-
* never-acked envelope would pollute the peer's sealed conversation record forever.
|
|
62
|
-
*/
|
|
63
|
-
export const DELIVERY_ACK_TIMEOUT_MS = DELIVERY_BACKOFF_CAP_MS;
|
|
64
|
-
/**
|
|
65
|
-
* How many times an envelope may be SENT without ever being acknowledged before the document
|
|
66
|
-
* stalls.
|
|
67
|
-
*
|
|
68
|
-
* A peer that will never answer must eventually stop being treated as a transient. Without a
|
|
69
|
-
* ceiling, an envelope sent to a peer whose client cannot ack — which is every peer until the
|
|
70
|
-
* inbound handler ships on both sides — is re-sent forever and is indistinguishable, in the log
|
|
71
|
-
* and in `list`, from one that is about to land.
|
|
72
|
-
*/
|
|
73
|
-
export const DELIVERY_MAX_UNACKED_SENDS = 5;
|
|
74
|
-
/**
|
|
75
|
-
* A document whose peer cannot be resolved is not transient, so it gets the cap immediately rather
|
|
76
|
-
* than climbing to it — but it DOES get scheduled. See the `no_peer` branch.
|
|
77
|
-
*/
|
|
78
|
-
export const DELIVERY_UNRESOLVABLE_RETRY_MS = DELIVERY_BACKOFF_CAP_MS;
|
|
79
|
-
export function backoffFor(attempts) {
|
|
80
|
-
const idx = Math.min(Math.max(attempts, 0), DELIVERY_BACKOFF_MS.length - 1);
|
|
81
|
-
return DELIVERY_BACKOFF_MS[idx];
|
|
82
|
-
}
|
|
83
|
-
export class DocumentDelivery {
|
|
84
|
-
#store;
|
|
85
|
-
#transport;
|
|
86
|
-
#logger;
|
|
87
|
-
#inFlight = null;
|
|
88
|
-
constructor(store, transport, logger) {
|
|
89
|
-
this.#store = store;
|
|
90
|
-
this.#transport = transport;
|
|
91
|
-
this.#logger = logger;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* One pass over what is due. Returns counts rather than throwing on a per-envelope failure: one
|
|
95
|
-
* unreachable peer must not stop delivery to every other peer, which is precisely the "works
|
|
96
|
-
* only when all nodes are healthy" shape the project forbids.
|
|
97
|
-
*/
|
|
98
|
-
/**
|
|
99
|
-
* One pass over what is due, PER (document, holder). Returns counts rather than throwing on a
|
|
100
|
-
* per-target failure: one unreachable HOLDER must not stop delivery to any other — the same
|
|
101
|
-
* "works only when all nodes are healthy" shape the project forbids, now per holder.
|
|
102
|
-
*/
|
|
103
|
-
async tick(ownerAgentId, holdersFor, nowMs, opts = {}) {
|
|
104
|
-
if (this.#inFlight)
|
|
105
|
-
return this.#inFlight;
|
|
106
|
-
const run = this.#run(ownerAgentId, holdersFor, nowMs, opts);
|
|
107
|
-
this.#inFlight = run;
|
|
108
|
-
try {
|
|
109
|
-
return await run;
|
|
110
|
-
}
|
|
111
|
-
finally {
|
|
112
|
-
this.#inFlight = null;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async #run(ownerAgentId, holdersFor, nowMs, opts) {
|
|
116
|
-
let graceBudgetRemainingMs = DELIVERY_ACK_GRACE_BUDGET_MS;
|
|
117
|
-
const correlationId = opts.correlationId ?? `dlv-${ownerAgentId.slice(0, 8)}-${nowMs}`;
|
|
118
|
-
const senderAgentId = opts.senderAgentId ?? ownerAgentId;
|
|
119
|
-
// LEGACY bilateral rows gain their per-holder twin before anything is read — idempotent
|
|
120
|
-
// insurance, journaled (Entry 14): pre-fan-out backlogs are near-empty at alpha.
|
|
121
|
-
this.#store.backfillBilateralDeliveries(ownerAgentId, senderAgentId, nowMs);
|
|
122
|
-
const pending = this.#store.pendingHolderDeliveries(ownerAgentId, nowMs);
|
|
123
|
-
const result = {
|
|
124
|
-
attempted: 0, delivered: 0, sent: 0, rejected: 0, deferred: 0, failed: 0,
|
|
125
|
-
};
|
|
126
|
-
// DOD-MP-INVITE-FANOUT-1 — AMENDMENTS DRAIN FIRST, and the order is the point.
|
|
127
|
-
//
|
|
128
|
-
// A holder must apply the admitting amendment BEFORE any edit authored at the new epoch,
|
|
129
|
-
// otherwise they refuse that edit as coming from a non-participant — the exact symptom seen
|
|
130
|
-
// live, where a joiner's edits were silently dropped by a holder still at the old epoch.
|
|
131
|
-
// Draining this queue ahead of the envelope queue in every pass makes that ordering a
|
|
132
|
-
// guarantee rather than a coincidence of timing; the store's head-of-line rule makes it hold
|
|
133
|
-
// ACROSS passes too.
|
|
134
|
-
//
|
|
135
|
-
// An owed row whose amendment is not in the recorded chain can never be sent (the pending query
|
|
136
|
-
// inner-joins the chain, deliberately: a redelivery must never send bytes this daemon's own
|
|
137
|
-
// chain does not contain). Such a row is invisible AND owed forever, so it is named rather than
|
|
138
|
-
// scanned past in silence.
|
|
139
|
-
for (const orphan of this.#store.amendmentDeliveriesWithoutChainRow(ownerAgentId)) {
|
|
140
|
-
this.#logger.error("document.amendment.chain_row_missing", {
|
|
141
|
-
documentId: orphan.documentId,
|
|
142
|
-
amendmentHash: orphan.amendmentHash,
|
|
143
|
-
holderAgentId: orphan.holderAgentId,
|
|
144
|
-
correlationId,
|
|
145
|
-
impact: "this membership change is owed to a holder and its bytes are not in the local chain, " +
|
|
146
|
-
"so it can never be delivered — the holder will stay at the old epoch",
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
for (const owed of this.#store.pendingAmendmentDeliveries(ownerAgentId, nowMs)) {
|
|
150
|
-
const holders = holdersFor(owed.documentId);
|
|
151
|
-
if (holders === null) {
|
|
152
|
-
// NOT transient, and NOT silent. The envelope pass logs `no_holders` only for documents
|
|
153
|
-
// that also have pending ENVELOPES — a document whose content is fully acked has none, so
|
|
154
|
-
// this row would otherwise be re-scanned every tick forever with nothing said anywhere.
|
|
155
|
-
// Scheduled at the cap so it stops spinning, and logged so it stops being invisible.
|
|
156
|
-
this.#store.recordAmendmentAttempt(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs + DELIVERY_UNRESOLVABLE_RETRY_MS);
|
|
157
|
-
this.#logger.error("document.amendment.holders_underivable", {
|
|
158
|
-
documentId: owed.documentId,
|
|
159
|
-
amendmentHash: owed.amendmentHash,
|
|
160
|
-
holderAgentId: owed.holderAgentId,
|
|
161
|
-
correlationId,
|
|
162
|
-
impact: "the document row is gone or its chain does not derive, so this membership change " +
|
|
163
|
-
"cannot be addressed to anyone — it stays owed",
|
|
164
|
-
});
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
// A holder the chain no longer contains, or one it records as removed, is owed nothing.
|
|
168
|
-
// RETIRED, never acked: an ack here would make the durable record claim a delivery that
|
|
169
|
-
// never happened. Both checks, because the envelope path uses both and a disagreement
|
|
170
|
-
// between them would otherwise keep this loop dialing a locally-removed holder.
|
|
171
|
-
const removed = this.#store.memberRemoved(ownerAgentId, owed.documentId, owed.holderAgentId);
|
|
172
|
-
if (!holders.includes(owed.holderAgentId) || removed.removed) {
|
|
173
|
-
this.#store.retireAmendmentDelivery(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs);
|
|
174
|
-
this.#logger.info("document.amendment.holder_retired", {
|
|
175
|
-
documentId: owed.documentId,
|
|
176
|
-
amendmentHash: owed.amendmentHash,
|
|
177
|
-
holderAgentId: owed.holderAgentId,
|
|
178
|
-
correlationId,
|
|
179
|
-
});
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
// CLAIM THE ROW BEFORE DIALING — the same rule the envelope path states and for the same
|
|
183
|
-
// reason: a crash mid-dial would otherwise leave the row immediately due with `attempts`
|
|
184
|
-
// unchanged, so a crash-looping daemon dials at full rate forever and never escalates. It
|
|
185
|
-
// also closes the window where the 60s sweep fires inside the invite handler's own await and
|
|
186
|
-
// sends the same amendment twice.
|
|
187
|
-
const attemptsNow = this.#store.recordAmendmentAttempt(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs + backoffFor(owed.attempts));
|
|
188
|
-
result.attempted += 1;
|
|
189
|
-
let sent;
|
|
190
|
-
try {
|
|
191
|
-
const out = await this.#transport.sendBytes({
|
|
192
|
-
peerAgentId: owed.holderAgentId,
|
|
193
|
-
documentId: owed.documentId,
|
|
194
|
-
bytes: owed.bytes,
|
|
195
|
-
correlationId,
|
|
196
|
-
});
|
|
197
|
-
sent = out.ok ? { ok: true, parked: out.parked === true } : out;
|
|
198
|
-
}
|
|
199
|
-
catch (err) {
|
|
200
|
-
sent = { ok: false, reason: "amendment_send_threw", detail: err instanceof Error ? err.message : String(err) };
|
|
201
|
-
}
|
|
202
|
-
if (sent.ok && sent.parked !== true) {
|
|
203
|
-
// SENT, NOT ACKED. Their daemon received the frame; whether it RECORDED it is a separate
|
|
204
|
-
// fact and it can refuse (a chain gap or a failed derivation throws on the receiver and
|
|
205
|
-
// answers nothing). The row stays owed and is re-offered, and it settles for real when the
|
|
206
|
-
// holder acks any envelope at this epoch or later — which proves they applied it, because
|
|
207
|
-
// the inbound epoch gate would have refused that envelope otherwise.
|
|
208
|
-
this.#store.markAmendmentSent(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs, DELIVERY_ACK_TIMEOUT_MS);
|
|
209
|
-
result.sent += 1;
|
|
210
|
-
this.#logger.info("document.amendment.sent", {
|
|
211
|
-
documentId: owed.documentId,
|
|
212
|
-
holderAgentId: owed.holderAgentId,
|
|
213
|
-
amendmentHash: owed.amendmentHash,
|
|
214
|
-
epochId: owed.epochId,
|
|
215
|
-
attempts: attemptsNow,
|
|
216
|
-
correlationId,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
// PARKED IS NOT DELIVERED. The relay took it because the holder had no live counterparty;
|
|
221
|
-
// if that holder never drains it and the debt has been cleared, the membership change is
|
|
222
|
-
// gone with both surfaces reporting success. It is a retry, exactly like a refusal.
|
|
223
|
-
const reason = sent.ok ? "relay_parked" : sent.reason;
|
|
224
|
-
result.failed += 1;
|
|
225
|
-
// WARN, NEVER ERROR, and NEVER ABANDONED: a membership change that cannot be delivered yet
|
|
226
|
-
// is a retry, not a loss. There is no attempt ceiling here on purpose — abandoning would
|
|
227
|
-
// put two holders permanently out of step over exactly the fact they must agree on.
|
|
228
|
-
this.#logger.warn("document.amendment.delivery_failed", {
|
|
229
|
-
documentId: owed.documentId,
|
|
230
|
-
holderAgentId: owed.holderAgentId,
|
|
231
|
-
amendmentHash: owed.amendmentHash,
|
|
232
|
-
epochId: owed.epochId,
|
|
233
|
-
reason,
|
|
234
|
-
// The CAUSE, not just the exit-point label. `session_sealed` says where it surfaced;
|
|
235
|
-
// detail says why.
|
|
236
|
-
detail: sent.ok ? "the relay is holding it — the holder had no live counterparty" : sent.detail,
|
|
237
|
-
attempts: attemptsNow,
|
|
238
|
-
correlationId,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
// Grouped (document, holder): one derivation and one reachability probe serve every pending
|
|
243
|
-
// envelope for that pair.
|
|
244
|
-
const byDocument = new Map();
|
|
245
|
-
for (const p of pending) {
|
|
246
|
-
let holders = byDocument.get(p.documentId);
|
|
247
|
-
if (!holders) {
|
|
248
|
-
holders = new Map();
|
|
249
|
-
byDocument.set(p.documentId, holders);
|
|
250
|
-
}
|
|
251
|
-
const list = holders.get(p.holderAgentId);
|
|
252
|
-
if (list)
|
|
253
|
-
list.push(p);
|
|
254
|
-
else
|
|
255
|
-
holders.set(p.holderAgentId, [p]);
|
|
256
|
-
}
|
|
257
|
-
for (const [documentId, holderGroups] of byDocument) {
|
|
258
|
-
const currentHolders = holdersFor(documentId);
|
|
259
|
-
if (currentHolders === null) {
|
|
260
|
-
// The document row is gone or its chain does not derive — NOT transient. Scheduled at
|
|
261
|
-
// the cap so the rows never starve anything, exactly the old no_peer discipline.
|
|
262
|
-
this.#logger.error("document.delivery.no_holders", {
|
|
263
|
-
documentId,
|
|
264
|
-
pending: [...holderGroups.values()].reduce((n, l) => n + l.length, 0),
|
|
265
|
-
correlationId,
|
|
266
|
-
});
|
|
267
|
-
for (const [holder, rows] of holderGroups) {
|
|
268
|
-
for (const r of rows) {
|
|
269
|
-
this.#store.scheduleHolderRetry(ownerAgentId, documentId, r.envelope.envelopeHash, holder, nowMs + DELIVERY_UNRESOLVABLE_RETRY_MS);
|
|
270
|
-
}
|
|
271
|
-
result.failed += rows.length;
|
|
272
|
-
}
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
const currentSet = new Set(currentHolders);
|
|
276
|
-
for (const [holderAgentId, rows] of holderGroups) {
|
|
277
|
-
// A holder the arrangement no longer includes — removed, or never derivable — is
|
|
278
|
-
// RETIRED, announced: our decision, not evidence about them (DOD-MP-REMOVE-1's
|
|
279
|
-
// delivery-stop clause, generalized per holder).
|
|
280
|
-
if (!currentSet.has(holderAgentId) ||
|
|
281
|
-
this.#store.memberRemoved(ownerAgentId, documentId, holderAgentId).removed) {
|
|
282
|
-
const retiredHashes = this.#store.abandonHolderDeliveries(ownerAgentId, documentId, holderAgentId, nowMs);
|
|
283
|
-
for (const hash of retiredHashes) {
|
|
284
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, hash, nowMs);
|
|
285
|
-
}
|
|
286
|
-
this.#logger.info("document.delivery.peer_removed", {
|
|
287
|
-
documentId, holderAgentId, retired: retiredHashes.length, correlationId,
|
|
288
|
-
});
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
let reach;
|
|
292
|
-
try {
|
|
293
|
-
reach = await this.#transport.isPeerReachable(holderAgentId, correlationId);
|
|
294
|
-
}
|
|
295
|
-
catch (err) {
|
|
296
|
-
// A FAILED LOOKUP IS NOT AN OFFLINE HOLDER — deferred, per holder, without an attempt.
|
|
297
|
-
this.#logger.warn("document.delivery.lookup_failed", {
|
|
298
|
-
documentId, holderAgentId, correlationId,
|
|
299
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
300
|
-
});
|
|
301
|
-
for (const r of rows) {
|
|
302
|
-
// Deferrals ESCALATE the schedule (an offline holder must not be redialed at full
|
|
303
|
-
// rate forever) without touching the SENDS ceiling — waiting is not sending.
|
|
304
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, r.envelope.envelopeHash, holderAgentId, nowMs + backoffFor(r.attempts));
|
|
305
|
-
}
|
|
306
|
-
result.deferred += rows.length;
|
|
307
|
-
continue;
|
|
308
|
-
}
|
|
309
|
-
if (!reach.reachable) {
|
|
310
|
-
this.#logger.info(reach.unknownAgent ? "document.delivery.peer_unknown" : "document.delivery.peer_unreachable", { documentId, holderAgentId, pending: rows.length, correlationId });
|
|
311
|
-
for (const r of rows) {
|
|
312
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, r.envelope.envelopeHash, holderAgentId, nowMs + backoffFor(r.attempts));
|
|
313
|
-
}
|
|
314
|
-
result.deferred += rows.length;
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
for (const row of rows) {
|
|
318
|
-
const envelope = row.envelope;
|
|
319
|
-
result.attempted += 1;
|
|
320
|
-
// CLAIM THE ROW BEFORE DIALING — due-forever-on-crash-mid-dial is the same hazard it
|
|
321
|
-
// always was, per holder now.
|
|
322
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs + backoffFor(row.attempts));
|
|
323
|
-
let outcome;
|
|
324
|
-
const graceStartedAt = Date.now();
|
|
325
|
-
try {
|
|
326
|
-
outcome = await this.#transport.deliver({
|
|
327
|
-
peerAgentId: holderAgentId,
|
|
328
|
-
documentId,
|
|
329
|
-
envelope,
|
|
330
|
-
ackGraceMs: Math.max(0, graceBudgetRemainingMs),
|
|
331
|
-
sessionHint: opts.sessionHints?.get(documentId),
|
|
332
|
-
correlationId,
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
catch (err) {
|
|
336
|
-
outcome = {
|
|
337
|
-
ok: false,
|
|
338
|
-
reason: "document_delivery_threw",
|
|
339
|
-
detail: err instanceof Error ? err.message : String(err),
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
finally {
|
|
343
|
-
graceBudgetRemainingMs -= Date.now() - graceStartedAt;
|
|
344
|
-
}
|
|
345
|
-
if (outcome.ok && outcome.admitted === null) {
|
|
346
|
-
// IN FLIGHT for THIS holder. Parked and live sends want DIFFERENT retry schedules,
|
|
347
|
-
// but both LEFT the machine — the sent-vs-never-left surface counts either (review
|
|
348
|
-
// M7: reporting relay-parked content as "never left" mislabels a delivery that the
|
|
349
|
-
// relay is holding for them).
|
|
350
|
-
this.#store.markHolderDelivered(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
351
|
-
const sends = this.#store.recordHolderSend(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId);
|
|
352
|
-
this.#store.scheduleHolderRetry(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs + (outcome.parked ? backoffFor(row.attempts) : DELIVERY_ACK_TIMEOUT_MS));
|
|
353
|
-
this.#logger.info("document.delivery.sent", {
|
|
354
|
-
documentId,
|
|
355
|
-
envelopeHash: envelope.envelopeHash,
|
|
356
|
-
holderAgentId,
|
|
357
|
-
sessionId: outcome.sessionId,
|
|
358
|
-
sessionOpened: outcome.sessionOpened,
|
|
359
|
-
unackedSends: sends,
|
|
360
|
-
correlationId,
|
|
361
|
-
});
|
|
362
|
-
result.sent += 1;
|
|
363
|
-
if (sends >= DELIVERY_MAX_UNACKED_SENDS) {
|
|
364
|
-
// THIS HOLDER is exhausted — retired, announced, and only theirs. The document
|
|
365
|
-
// stalls ONLY when every current holder is exhausted: one silent peer stopping a
|
|
366
|
-
// living collaboration is the exact availability failure the milestone forbids.
|
|
367
|
-
this.#store.abandonSingleHolderDelivery(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
368
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, envelope.envelopeHash, nowMs);
|
|
369
|
-
this.#logger.error("document.delivery.unacked_limit", {
|
|
370
|
-
documentId,
|
|
371
|
-
envelopeHash: envelope.envelopeHash,
|
|
372
|
-
holderAgentId,
|
|
373
|
-
sends,
|
|
374
|
-
correlationId,
|
|
375
|
-
detail: `this update has been delivered ${sends} times to this holder without their ` +
|
|
376
|
-
`daemon ever confirming it — delivery TO THEM is retired; every other holder ` +
|
|
377
|
-
`is unaffected. Check document.delivery.ack_grace_expired, ` +
|
|
378
|
-
`session.content.held.discarded, and whether their daemon has yet received ` +
|
|
379
|
-
`the amendment that added you (their log would show ` +
|
|
380
|
-
`document.inbound.sender_unknown_epoch_ahead) before concluding their client ` +
|
|
381
|
-
`is at fault.`,
|
|
382
|
-
});
|
|
383
|
-
const allExhausted = currentHolders
|
|
384
|
-
.filter((h) => h !== senderAgentId)
|
|
385
|
-
.every((h) => !this.#store.holderHasPending(ownerAgentId, documentId, h));
|
|
386
|
-
if (allExhausted) {
|
|
387
|
-
this.#store.setDocumentStatus(ownerAgentId, documentId, "stalled");
|
|
388
|
-
this.#logger.error("document.delivery.stalled_all_holders", {
|
|
389
|
-
documentId, correlationId,
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
else if (outcome.ok) {
|
|
395
|
-
const first = this.#store.ackHolderDelivery(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
396
|
-
// The envelope-level record follows the ONE terminal rule (review M3).
|
|
397
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, envelope.envelopeHash, nowMs);
|
|
398
|
-
this.#logger.info("document.delivery.session", {
|
|
399
|
-
documentId, holderAgentId, sessionId: outcome.sessionId,
|
|
400
|
-
opened: outcome.sessionOpened, correlationId,
|
|
401
|
-
});
|
|
402
|
-
if (outcome.admitted) {
|
|
403
|
-
// PROOF BY EPOCH (DOD-MP-INVITE-FANOUT-1). There is no amendment ack frame, but an
|
|
404
|
-
// ADMISSION is one: the inbound epoch gate requires the envelope's epoch to EQUAL the
|
|
405
|
-
// receiver's own derived epoch, so a holder that admitted an envelope at epoch E
|
|
406
|
-
// demonstrably holds every amendment up to E. Their acceptance of the content is an
|
|
407
|
-
// acceptance of the governance that made the content admissible — which settles the
|
|
408
|
-
// amendment row on evidence rather than on inference.
|
|
409
|
-
//
|
|
410
|
-
// ADMITTED ONLY, NEVER MERELY ANSWERED. A rejection is also an ack for delivery
|
|
411
|
-
// purposes, and it proves nothing here: the checks that run BEFORE the epoch gate —
|
|
412
|
-
// an unknown document, a failed signature — refuse terminally while the holder may be
|
|
413
|
-
// at any epoch at all. Settling on those would ack an amendment they do not have,
|
|
414
|
-
// which is the exact defect this queue exists to prevent, reintroduced one layer up.
|
|
415
|
-
const settled = this.#store.ackAmendmentsThroughEpoch(ownerAgentId, documentId, holderAgentId, envelope.epochId, nowMs);
|
|
416
|
-
if (settled > 0) {
|
|
417
|
-
this.#logger.info("document.amendment.confirmed_by_epoch", {
|
|
418
|
-
documentId, holderAgentId, epochId: envelope.epochId, settled, correlationId,
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
this.#logger.info("document.delivery.acked", {
|
|
422
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
423
|
-
sessionId: outcome.sessionId, firstAck: first, correlationId,
|
|
424
|
-
});
|
|
425
|
-
result.delivered += 1;
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
this.#logger.warn("document.delivery.rejected", {
|
|
429
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
430
|
-
sessionId: outcome.sessionId, reason: outcome.rejectionReason, correlationId,
|
|
431
|
-
});
|
|
432
|
-
result.rejected += 1;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
else {
|
|
436
|
-
this.#logger.warn("document.delivery.failed", {
|
|
437
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
438
|
-
reason: outcome.reason, detail: outcome.detail, attempts: row.attempts + 1,
|
|
439
|
-
correlationId,
|
|
440
|
-
});
|
|
441
|
-
result.failed += 1;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
return result;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
//# sourceMappingURL=document-delivery.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"document-delivery.js","sourceRoot":"","sources":["../src/document-delivery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DOD-MP-JOIN-1 (daemon half) — the join-offer store: pending consent, both roles, settle-once.
|
|
3
|
-
*
|
|
4
|
-
* One table for both sides of a join (the `document_proposals` precedent): the INVITEE holds the
|
|
5
|
-
* offer they received — as RECEIVED BYTES, validated before recording — and the INVITER holds the
|
|
6
|
-
* offer they authored plus the invitee's signed answer when it arrives. Keyed on
|
|
7
|
-
* `(owner, amendment_hash)`: the admitting amendment is the fact being consented to, and a
|
|
8
|
-
* re-invitation after a refusal is a new amendment with a new hash — a new row, never a
|
|
9
|
-
* reopened one.
|
|
10
|
-
*
|
|
11
|
-
* A refused-at-arrival offer (bad chain, wrong invitee, version mismatch) is RECORDED refused
|
|
12
|
-
* with its reason rather than dropped — a dropped offer is indistinguishable from an inviter who
|
|
13
|
-
* never sent one.
|
|
14
|
-
*/
|
|
15
|
-
import { type DocumentJoinOffer, type DocumentJoinAnswer } from "@cello-protocol/protocol-types";
|
|
16
|
-
import type { DaemonDatabase } from "./sqlcipher-db.js";
|
|
17
|
-
import type { Logger } from "./types.js";
|
|
18
|
-
export type JoinOfferState = "pending" | "accepted" | "refused";
|
|
19
|
-
export type JoinOfferRole = "invitee" | "inviter";
|
|
20
|
-
export interface JoinOfferRecord {
|
|
21
|
-
documentId: string;
|
|
22
|
-
amendmentHash: string;
|
|
23
|
-
role: JoinOfferRole;
|
|
24
|
-
inviterAgentId: string;
|
|
25
|
-
inviteeAgentId: string;
|
|
26
|
-
offer: DocumentJoinOffer;
|
|
27
|
-
state: JoinOfferState;
|
|
28
|
-
reason: string | null;
|
|
29
|
-
createdAtMs: number;
|
|
30
|
-
decidedAtMs: number | null;
|
|
31
|
-
}
|
|
32
|
-
export declare class DocumentJoinStore {
|
|
33
|
-
#private;
|
|
34
|
-
constructor(db: DaemonDatabase, logger: Logger);
|
|
35
|
-
/**
|
|
36
|
-
* Record an ARRIVING offer under the invitee's key — already validated by the caller; a
|
|
37
|
-
* validation refusal is recorded as `refused` with its reason, never dropped. First arrival's
|
|
38
|
-
* bytes are the permanent record; a redelivery changes nothing.
|
|
39
|
-
*/
|
|
40
|
-
recordIncoming(ownerAgentId: string, wire: Uint8Array, amendmentHash: string, verdict: {
|
|
41
|
-
state: "pending";
|
|
42
|
-
} | {
|
|
43
|
-
state: "refused";
|
|
44
|
-
reason: string;
|
|
45
|
-
}, nowMs: number): {
|
|
46
|
-
state: JoinOfferState;
|
|
47
|
-
reason?: string;
|
|
48
|
-
};
|
|
49
|
-
/** Record an offer WE authored, pending the invitee's answer. */
|
|
50
|
-
recordOutgoing(ownerAgentId: string, wire: Uint8Array, amendmentHash: string, nowMs: number): void;
|
|
51
|
-
/**
|
|
52
|
-
* The INVITEE's local decision. Settle-once: only a pending row decides, and the caller learns
|
|
53
|
-
* whether THIS call decided it — an already-decided offer is a fact to report, not an error.
|
|
54
|
-
*/
|
|
55
|
-
decide(ownerAgentId: string, amendmentHash: string, accepted: boolean, reason: string | null, nowMs: number): {
|
|
56
|
-
decided: boolean;
|
|
57
|
-
state: JoinOfferState;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Record the invitee's signed ANSWER on the inviter's side. The caller verifies the signature
|
|
61
|
-
* against the invitee named in the STORED offer first. Settle-once: a contradicting second
|
|
62
|
-
* answer is refused with both records retained (the stored answer stands).
|
|
63
|
-
*/
|
|
64
|
-
recordAnswer(ownerAgentId: string, wire: Uint8Array, verify: (agentId: string, tbs: Uint8Array, signature: Uint8Array) => boolean, nowMs: number): {
|
|
65
|
-
ok: true;
|
|
66
|
-
answer: DocumentJoinAnswer;
|
|
67
|
-
settled: boolean;
|
|
68
|
-
} | {
|
|
69
|
-
ok: false;
|
|
70
|
-
reason: string;
|
|
71
|
-
};
|
|
72
|
-
get(ownerAgentId: string, amendmentHash: string): JoinOfferRecord | null;
|
|
73
|
-
/** Auto-refused arrivals — surfaced so the refusal sentence reaches an operator. */
|
|
74
|
-
refusedFor(ownerAgentId: string): JoinOfferRecord[];
|
|
75
|
-
/** Offers THIS owner authored — the inviter's view of who has answered what. */
|
|
76
|
-
outgoingFor(ownerAgentId: string): JoinOfferRecord[];
|
|
77
|
-
/** Offers awaiting THIS owner's consent — the inbox surface. */
|
|
78
|
-
pendingFor(ownerAgentId: string): JoinOfferRecord[];
|
|
79
|
-
}
|
|
80
|
-
//# sourceMappingURL=document-join-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"document-join-store.d.ts","sourceRoot":"","sources":["../src/document-join-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAoBzC,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,qBAAa,iBAAiB;;gBAIhB,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM;IAM9C;;;;OAIG;IACH,cAAc,CACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACpE,KAAK,EAAE,MAAM,GACZ;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAmC7C,iEAAiE;IACjE,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAqBlG;;;OAGG;IACH,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GACZ;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,cAAc,CAAA;KAAE;IAY9C;;;;OAIG;IACH,YAAY,CACV,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,KAAK,OAAO,EAC5E,KAAK,EAAE,MAAM,GACZ;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,kBAAkB,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAkE7F,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IASxE,oFAAoF;IACpF,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE;IAWnD,gFAAgF;IAChF,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE;IAWpD,gEAAgE;IAChE,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE;CAUpD"}
|