@cello-protocol/daemon 0.0.168 → 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 -265
- 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 +462 -511
- 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 +655 -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 -568
- 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 -247
- package/dist/document-store.d.ts.map +1 -1
- package/dist/document-store.js +95 -827
- 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 -124
- package/dist/document-control-notifier.d.ts.map +0 -1
- package/dist/document-control-notifier.js +0 -176
- package/dist/document-control-notifier.js.map +0 -1
- package/dist/document-delivery.d.ts +0 -250
- package/dist/document-delivery.d.ts.map +0 -1
- package/dist/document-delivery.js +0 -608
- 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,608 +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
|
-
import { CONTROL_RESEND_AFTER_MS, CONTROL_MAX_SENDS, CONTROL_UNREACHABLE_REPORT_AFTER, } from "./document-control-notifier.js";
|
|
29
|
-
/**
|
|
30
|
-
* Backoff schedule in ms: ~1s, 5s, 30s, 2m, 10m, then the last entry repeats.
|
|
31
|
-
*
|
|
32
|
-
* The final entry IS the cap — there is no separate ceiling constant. There was one, set to 900s,
|
|
33
|
-
* and it was unreachable: the index clamp meant the schedule never produced a value above 600s, so
|
|
34
|
-
* the exported "cap" was a number the code could not emit and the tests were using it as a synonym
|
|
35
|
-
* for "much later". A documented limit the implementation cannot reach is worse than none.
|
|
36
|
-
*
|
|
37
|
-
* Capped at all because the peer coming back online is the event we are waiting for and it can
|
|
38
|
-
* happen at any moment — an uncapped curve leaves a peer that returned after a long absence waiting
|
|
39
|
-
* hours for a delivery that has been ready the whole time.
|
|
40
|
-
*/
|
|
41
|
-
/**
|
|
42
|
-
* Total ack-grace one sweep pass may spend, across every agent, document and envelope in it.
|
|
43
|
-
*
|
|
44
|
-
* The wait exists so a session we opened is not torn down before the peer's answer arrives. It is
|
|
45
|
-
* capped as a PASS budget because the loops it sits inside are sequential: a per-envelope allowance
|
|
46
|
-
* meant one silent peer with a backlog could hold the sweep for the better part of an hour, and the
|
|
47
|
-
* only symptom would be other agents' documents quietly not syncing.
|
|
48
|
-
*
|
|
49
|
-
* 30s ≈ three full graces. Enough for the ordinary case (one or two opened sessions per pass, ack
|
|
50
|
-
* back in well under a second) without letting an unresponsive peer own the pass.
|
|
51
|
-
*/
|
|
52
|
-
export const DELIVERY_ACK_GRACE_BUDGET_MS = 30_000;
|
|
53
|
-
export const DELIVERY_BACKOFF_MS = [1_000, 5_000, 30_000, 120_000, 600_000];
|
|
54
|
-
export const DELIVERY_BACKOFF_CAP_MS = DELIVERY_BACKOFF_MS[DELIVERY_BACKOFF_MS.length - 1];
|
|
55
|
-
/**
|
|
56
|
-
* How long to wait for an ACK after a SUCCESSFUL send, before sending again.
|
|
57
|
-
*
|
|
58
|
-
* Deliberately NOT the failure backoff. "How long do I wait after a failure" and "how long do I
|
|
59
|
-
* wait for an answer" are different questions, and reusing the first for the second re-sent a
|
|
60
|
-
* successfully-delivered envelope one second later — and every resend is not free: `sendContent`
|
|
61
|
-
* witnesses a message-leaf hash to the relay and appends a leaf to the session chain, so a
|
|
62
|
-
* never-acked envelope would pollute the peer's sealed conversation record forever.
|
|
63
|
-
*/
|
|
64
|
-
export const DELIVERY_ACK_TIMEOUT_MS = DELIVERY_BACKOFF_CAP_MS;
|
|
65
|
-
/**
|
|
66
|
-
* How many times an envelope may be SENT without ever being acknowledged before the document
|
|
67
|
-
* stalls.
|
|
68
|
-
*
|
|
69
|
-
* A peer that will never answer must eventually stop being treated as a transient. Without a
|
|
70
|
-
* ceiling, an envelope sent to a peer whose client cannot ack — which is every peer until the
|
|
71
|
-
* inbound handler ships on both sides — is re-sent forever and is indistinguishable, in the log
|
|
72
|
-
* and in `list`, from one that is about to land.
|
|
73
|
-
*/
|
|
74
|
-
export const DELIVERY_MAX_UNACKED_SENDS = 5;
|
|
75
|
-
/**
|
|
76
|
-
* A document whose peer cannot be resolved is not transient, so it gets the cap immediately rather
|
|
77
|
-
* than climbing to it — but it DOES get scheduled. See the `no_peer` branch.
|
|
78
|
-
*/
|
|
79
|
-
export const DELIVERY_UNRESOLVABLE_RETRY_MS = DELIVERY_BACKOFF_CAP_MS;
|
|
80
|
-
export function backoffFor(attempts) {
|
|
81
|
-
const idx = Math.min(Math.max(attempts, 0), DELIVERY_BACKOFF_MS.length - 1);
|
|
82
|
-
return DELIVERY_BACKOFF_MS[idx];
|
|
83
|
-
}
|
|
84
|
-
export class DocumentDelivery {
|
|
85
|
-
#store;
|
|
86
|
-
#transport;
|
|
87
|
-
#logger;
|
|
88
|
-
#controlHolders;
|
|
89
|
-
#inFlight = null;
|
|
90
|
-
constructor(store, transport, logger,
|
|
91
|
-
/**
|
|
92
|
-
* REQUIRED IN PRACTICE. The default refuses rather than falling back to the envelope
|
|
93
|
-
* derivation: a fallback would look correct for every ordinary document and silently drop
|
|
94
|
-
* every legacy one, which is precisely the bug this parameter exists to prevent.
|
|
95
|
-
*/
|
|
96
|
-
controlHolders = () => ({ ok: false, reason: "control_holders_unavailable" })) {
|
|
97
|
-
this.#store = store;
|
|
98
|
-
this.#transport = transport;
|
|
99
|
-
this.#logger = logger;
|
|
100
|
-
this.#controlHolders = controlHolders;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* One pass over what is due. Returns counts rather than throwing on a per-envelope failure: one
|
|
104
|
-
* unreachable peer must not stop delivery to every other peer, which is precisely the "works
|
|
105
|
-
* only when all nodes are healthy" shape the project forbids.
|
|
106
|
-
*/
|
|
107
|
-
/**
|
|
108
|
-
* One pass over what is due, PER (document, holder). Returns counts rather than throwing on a
|
|
109
|
-
* per-target failure: one unreachable HOLDER must not stop delivery to any other — the same
|
|
110
|
-
* "works only when all nodes are healthy" shape the project forbids, now per holder.
|
|
111
|
-
*/
|
|
112
|
-
async tick(ownerAgentId, holdersFor, nowMs, opts = {}) {
|
|
113
|
-
if (this.#inFlight)
|
|
114
|
-
return this.#inFlight;
|
|
115
|
-
const run = this.#run(ownerAgentId, holdersFor, nowMs, opts);
|
|
116
|
-
this.#inFlight = run;
|
|
117
|
-
try {
|
|
118
|
-
return await run;
|
|
119
|
-
}
|
|
120
|
-
finally {
|
|
121
|
-
this.#inFlight = null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
async #run(ownerAgentId, holdersFor, nowMs, opts) {
|
|
125
|
-
let graceBudgetRemainingMs = DELIVERY_ACK_GRACE_BUDGET_MS;
|
|
126
|
-
const correlationId = opts.correlationId ?? `dlv-${ownerAgentId.slice(0, 8)}-${nowMs}`;
|
|
127
|
-
const senderAgentId = opts.senderAgentId ?? ownerAgentId;
|
|
128
|
-
// LEGACY bilateral rows gain their per-holder twin before anything is read — idempotent
|
|
129
|
-
// insurance, journaled (Entry 14): pre-fan-out backlogs are near-empty at alpha.
|
|
130
|
-
this.#store.backfillBilateralDeliveries(ownerAgentId, senderAgentId, nowMs);
|
|
131
|
-
const pending = this.#store.pendingHolderDeliveries(ownerAgentId, nowMs);
|
|
132
|
-
const result = {
|
|
133
|
-
attempted: 0, delivered: 0, sent: 0, rejected: 0, deferred: 0, failed: 0,
|
|
134
|
-
};
|
|
135
|
-
// DOD-MP-INVITE-FANOUT-1 — AMENDMENTS DRAIN FIRST, and the order is the point.
|
|
136
|
-
//
|
|
137
|
-
// A holder must apply the admitting amendment BEFORE any edit authored at the new epoch,
|
|
138
|
-
// otherwise they refuse that edit as coming from a non-participant — the exact symptom seen
|
|
139
|
-
// live, where a joiner's edits were silently dropped by a holder still at the old epoch.
|
|
140
|
-
// Draining this queue ahead of the envelope queue in every pass makes that ordering a
|
|
141
|
-
// guarantee rather than a coincidence of timing; the store's head-of-line rule makes it hold
|
|
142
|
-
// ACROSS passes too.
|
|
143
|
-
//
|
|
144
|
-
// An owed row whose amendment is not in the recorded chain can never be sent (the pending query
|
|
145
|
-
// inner-joins the chain, deliberately: a redelivery must never send bytes this daemon's own
|
|
146
|
-
// chain does not contain). Such a row is invisible AND owed forever, so it is named rather than
|
|
147
|
-
// scanned past in silence.
|
|
148
|
-
for (const orphan of this.#store.amendmentDeliveriesWithoutChainRow(ownerAgentId)) {
|
|
149
|
-
this.#logger.error("document.amendment.chain_row_missing", {
|
|
150
|
-
documentId: orphan.documentId,
|
|
151
|
-
amendmentHash: orphan.amendmentHash,
|
|
152
|
-
holderAgentId: orphan.holderAgentId,
|
|
153
|
-
correlationId,
|
|
154
|
-
impact: "this membership change is owed to a holder and its bytes are not in the local chain, " +
|
|
155
|
-
"so it can never be delivered — the holder will stay at the old epoch",
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
for (const owed of this.#store.pendingAmendmentDeliveries(ownerAgentId, nowMs)) {
|
|
159
|
-
const holders = holdersFor(owed.documentId);
|
|
160
|
-
if (holders === null) {
|
|
161
|
-
// NOT transient, and NOT silent. The envelope pass logs `no_holders` only for documents
|
|
162
|
-
// that also have pending ENVELOPES — a document whose content is fully acked has none, so
|
|
163
|
-
// this row would otherwise be re-scanned every tick forever with nothing said anywhere.
|
|
164
|
-
// Scheduled at the cap so it stops spinning, and logged so it stops being invisible.
|
|
165
|
-
this.#store.recordAmendmentAttempt(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs + DELIVERY_UNRESOLVABLE_RETRY_MS);
|
|
166
|
-
this.#logger.error("document.amendment.holders_underivable", {
|
|
167
|
-
documentId: owed.documentId,
|
|
168
|
-
amendmentHash: owed.amendmentHash,
|
|
169
|
-
holderAgentId: owed.holderAgentId,
|
|
170
|
-
correlationId,
|
|
171
|
-
impact: "the document row is gone or its chain does not derive, so this membership change " +
|
|
172
|
-
"cannot be addressed to anyone — it stays owed",
|
|
173
|
-
});
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
// A holder the chain no longer contains, or one it records as removed, is owed nothing.
|
|
177
|
-
// RETIRED, never acked: an ack here would make the durable record claim a delivery that
|
|
178
|
-
// never happened. Both checks, because the envelope path uses both and a disagreement
|
|
179
|
-
// between them would otherwise keep this loop dialing a locally-removed holder.
|
|
180
|
-
const removed = this.#store.memberRemoved(ownerAgentId, owed.documentId, owed.holderAgentId);
|
|
181
|
-
if (!holders.includes(owed.holderAgentId) || removed.removed) {
|
|
182
|
-
this.#store.retireAmendmentDelivery(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs);
|
|
183
|
-
this.#logger.info("document.amendment.holder_retired", {
|
|
184
|
-
documentId: owed.documentId,
|
|
185
|
-
amendmentHash: owed.amendmentHash,
|
|
186
|
-
holderAgentId: owed.holderAgentId,
|
|
187
|
-
correlationId,
|
|
188
|
-
});
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
// CLAIM THE ROW BEFORE DIALING — the same rule the envelope path states and for the same
|
|
192
|
-
// reason: a crash mid-dial would otherwise leave the row immediately due with `attempts`
|
|
193
|
-
// unchanged, so a crash-looping daemon dials at full rate forever and never escalates. It
|
|
194
|
-
// also closes the window where the 60s sweep fires inside the invite handler's own await and
|
|
195
|
-
// sends the same amendment twice.
|
|
196
|
-
const attemptsNow = this.#store.recordAmendmentAttempt(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs + backoffFor(owed.attempts));
|
|
197
|
-
result.attempted += 1;
|
|
198
|
-
let sent;
|
|
199
|
-
try {
|
|
200
|
-
const out = await this.#transport.sendBytes({
|
|
201
|
-
peerAgentId: owed.holderAgentId,
|
|
202
|
-
documentId: owed.documentId,
|
|
203
|
-
bytes: owed.bytes,
|
|
204
|
-
correlationId,
|
|
205
|
-
});
|
|
206
|
-
sent = out.ok ? { ok: true, parked: out.parked === true } : out;
|
|
207
|
-
}
|
|
208
|
-
catch (err) {
|
|
209
|
-
sent = { ok: false, reason: "amendment_send_threw", detail: err instanceof Error ? err.message : String(err) };
|
|
210
|
-
}
|
|
211
|
-
if (sent.ok && sent.parked !== true) {
|
|
212
|
-
// SENT, NOT ACKED. Their daemon received the frame; whether it RECORDED it is a separate
|
|
213
|
-
// fact and it can refuse (a chain gap or a failed derivation throws on the receiver and
|
|
214
|
-
// answers nothing). The row stays owed and is re-offered, and it settles for real when the
|
|
215
|
-
// holder acks any envelope at this epoch or later — which proves they applied it, because
|
|
216
|
-
// the inbound epoch gate would have refused that envelope otherwise.
|
|
217
|
-
this.#store.markAmendmentSent(ownerAgentId, owed.documentId, owed.amendmentHash, owed.holderAgentId, nowMs, DELIVERY_ACK_TIMEOUT_MS);
|
|
218
|
-
result.sent += 1;
|
|
219
|
-
this.#logger.info("document.amendment.sent", {
|
|
220
|
-
documentId: owed.documentId,
|
|
221
|
-
holderAgentId: owed.holderAgentId,
|
|
222
|
-
amendmentHash: owed.amendmentHash,
|
|
223
|
-
epochId: owed.epochId,
|
|
224
|
-
attempts: attemptsNow,
|
|
225
|
-
correlationId,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
// PARKED IS NOT DELIVERED. The relay took it because the holder had no live counterparty;
|
|
230
|
-
// if that holder never drains it and the debt has been cleared, the membership change is
|
|
231
|
-
// gone with both surfaces reporting success. It is a retry, exactly like a refusal.
|
|
232
|
-
const reason = sent.ok ? "relay_parked" : sent.reason;
|
|
233
|
-
result.failed += 1;
|
|
234
|
-
// WARN, NEVER ERROR, and NEVER ABANDONED: a membership change that cannot be delivered yet
|
|
235
|
-
// is a retry, not a loss. There is no attempt ceiling here on purpose — abandoning would
|
|
236
|
-
// put two holders permanently out of step over exactly the fact they must agree on.
|
|
237
|
-
this.#logger.warn("document.amendment.delivery_failed", {
|
|
238
|
-
documentId: owed.documentId,
|
|
239
|
-
holderAgentId: owed.holderAgentId,
|
|
240
|
-
amendmentHash: owed.amendmentHash,
|
|
241
|
-
epochId: owed.epochId,
|
|
242
|
-
reason,
|
|
243
|
-
// The CAUSE, not just the exit-point label. `session_sealed` says where it surfaced;
|
|
244
|
-
// detail says why.
|
|
245
|
-
detail: sent.ok ? "the relay is holding it — the holder had no live counterparty" : sent.detail,
|
|
246
|
-
attempts: attemptsNow,
|
|
247
|
-
correlationId,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
// Grouped (document, holder): one derivation and one reachability probe serve every pending
|
|
252
|
-
// envelope for that pair.
|
|
253
|
-
const byDocument = new Map();
|
|
254
|
-
for (const p of pending) {
|
|
255
|
-
let holders = byDocument.get(p.documentId);
|
|
256
|
-
if (!holders) {
|
|
257
|
-
holders = new Map();
|
|
258
|
-
byDocument.set(p.documentId, holders);
|
|
259
|
-
}
|
|
260
|
-
const list = holders.get(p.holderAgentId);
|
|
261
|
-
if (list)
|
|
262
|
-
list.push(p);
|
|
263
|
-
else
|
|
264
|
-
holders.set(p.holderAgentId, [p]);
|
|
265
|
-
}
|
|
266
|
-
// DOD-MP-CONTROL-DURABLE-1 — endings for documents with NO pending content go FIRST.
|
|
267
|
-
//
|
|
268
|
-
// The ordering rule is per-document (D's ending after D's content), so draining every
|
|
269
|
-
// document's ending behind every OTHER document's content bought nothing while creating a real
|
|
270
|
-
// hazard: the pass is time-bounded and restarts from the top, so a large backlog or one slow
|
|
271
|
-
// dial meant the control queue was deterministically never reached. A document with nothing
|
|
272
|
-
// queued cannot violate the rule, so it is served before that risk applies.
|
|
273
|
-
const documentsWithContent = new Set(byDocument.keys());
|
|
274
|
-
for (const owed of this.#store.pendingControlDeliveries(ownerAgentId, nowMs)) {
|
|
275
|
-
if (documentsWithContent.has(owed.documentId))
|
|
276
|
-
continue;
|
|
277
|
-
await this.#deliverControl(ownerAgentId, owed, nowMs, correlationId, result);
|
|
278
|
-
}
|
|
279
|
-
for (const [documentId, holderGroups] of byDocument) {
|
|
280
|
-
const currentHolders = holdersFor(documentId);
|
|
281
|
-
if (currentHolders === null) {
|
|
282
|
-
// The document row is gone or its chain does not derive — NOT transient. Scheduled at
|
|
283
|
-
// the cap so the rows never starve anything, exactly the old no_peer discipline.
|
|
284
|
-
this.#logger.error("document.delivery.no_holders", {
|
|
285
|
-
documentId,
|
|
286
|
-
pending: [...holderGroups.values()].reduce((n, l) => n + l.length, 0),
|
|
287
|
-
correlationId,
|
|
288
|
-
});
|
|
289
|
-
for (const [holder, rows] of holderGroups) {
|
|
290
|
-
for (const r of rows) {
|
|
291
|
-
this.#store.scheduleHolderRetry(ownerAgentId, documentId, r.envelope.envelopeHash, holder, nowMs + DELIVERY_UNRESOLVABLE_RETRY_MS);
|
|
292
|
-
}
|
|
293
|
-
result.failed += rows.length;
|
|
294
|
-
}
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
const currentSet = new Set(currentHolders);
|
|
298
|
-
for (const [holderAgentId, rows] of holderGroups) {
|
|
299
|
-
// A holder the arrangement no longer includes — removed, or never derivable — is
|
|
300
|
-
// RETIRED, announced: our decision, not evidence about them (DOD-MP-REMOVE-1's
|
|
301
|
-
// delivery-stop clause, generalized per holder).
|
|
302
|
-
if (!currentSet.has(holderAgentId) ||
|
|
303
|
-
this.#store.memberRemoved(ownerAgentId, documentId, holderAgentId).removed) {
|
|
304
|
-
const retiredHashes = this.#store.abandonHolderDeliveries(ownerAgentId, documentId, holderAgentId, nowMs);
|
|
305
|
-
for (const hash of retiredHashes) {
|
|
306
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, hash, nowMs);
|
|
307
|
-
}
|
|
308
|
-
this.#logger.info("document.delivery.peer_removed", {
|
|
309
|
-
documentId, holderAgentId, retired: retiredHashes.length, correlationId,
|
|
310
|
-
});
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
let reach;
|
|
314
|
-
try {
|
|
315
|
-
reach = await this.#transport.isPeerReachable(holderAgentId, correlationId);
|
|
316
|
-
}
|
|
317
|
-
catch (err) {
|
|
318
|
-
// A FAILED LOOKUP IS NOT AN OFFLINE HOLDER — deferred, per holder, without an attempt.
|
|
319
|
-
this.#logger.warn("document.delivery.lookup_failed", {
|
|
320
|
-
documentId, holderAgentId, correlationId,
|
|
321
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
322
|
-
});
|
|
323
|
-
for (const r of rows) {
|
|
324
|
-
// Deferrals ESCALATE the schedule (an offline holder must not be redialed at full
|
|
325
|
-
// rate forever) without touching the SENDS ceiling — waiting is not sending.
|
|
326
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, r.envelope.envelopeHash, holderAgentId, nowMs + backoffFor(r.attempts));
|
|
327
|
-
}
|
|
328
|
-
result.deferred += rows.length;
|
|
329
|
-
continue;
|
|
330
|
-
}
|
|
331
|
-
if (!reach.reachable) {
|
|
332
|
-
this.#logger.info(reach.unknownAgent ? "document.delivery.peer_unknown" : "document.delivery.peer_unreachable", { documentId, holderAgentId, pending: rows.length, correlationId });
|
|
333
|
-
for (const r of rows) {
|
|
334
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, r.envelope.envelopeHash, holderAgentId, nowMs + backoffFor(r.attempts));
|
|
335
|
-
}
|
|
336
|
-
result.deferred += rows.length;
|
|
337
|
-
continue;
|
|
338
|
-
}
|
|
339
|
-
for (const row of rows) {
|
|
340
|
-
const envelope = row.envelope;
|
|
341
|
-
result.attempted += 1;
|
|
342
|
-
// CLAIM THE ROW BEFORE DIALING — due-forever-on-crash-mid-dial is the same hazard it
|
|
343
|
-
// always was, per holder now.
|
|
344
|
-
this.#store.recordHolderAttempt(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs + backoffFor(row.attempts));
|
|
345
|
-
let outcome;
|
|
346
|
-
const graceStartedAt = Date.now();
|
|
347
|
-
try {
|
|
348
|
-
outcome = await this.#transport.deliver({
|
|
349
|
-
peerAgentId: holderAgentId,
|
|
350
|
-
documentId,
|
|
351
|
-
envelope,
|
|
352
|
-
ackGraceMs: Math.max(0, graceBudgetRemainingMs),
|
|
353
|
-
sessionHint: opts.sessionHints?.get(documentId),
|
|
354
|
-
correlationId,
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
catch (err) {
|
|
358
|
-
outcome = {
|
|
359
|
-
ok: false,
|
|
360
|
-
reason: "document_delivery_threw",
|
|
361
|
-
detail: err instanceof Error ? err.message : String(err),
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
finally {
|
|
365
|
-
graceBudgetRemainingMs -= Date.now() - graceStartedAt;
|
|
366
|
-
}
|
|
367
|
-
if (outcome.ok && outcome.admitted === null) {
|
|
368
|
-
// IN FLIGHT for THIS holder. Parked and live sends want DIFFERENT retry schedules,
|
|
369
|
-
// but both LEFT the machine — the sent-vs-never-left surface counts either (review
|
|
370
|
-
// M7: reporting relay-parked content as "never left" mislabels a delivery that the
|
|
371
|
-
// relay is holding for them).
|
|
372
|
-
this.#store.markHolderDelivered(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
373
|
-
const sends = this.#store.recordHolderSend(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId);
|
|
374
|
-
this.#store.scheduleHolderRetry(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs + (outcome.parked ? backoffFor(row.attempts) : DELIVERY_ACK_TIMEOUT_MS));
|
|
375
|
-
this.#logger.info("document.delivery.sent", {
|
|
376
|
-
documentId,
|
|
377
|
-
envelopeHash: envelope.envelopeHash,
|
|
378
|
-
holderAgentId,
|
|
379
|
-
sessionId: outcome.sessionId,
|
|
380
|
-
sessionOpened: outcome.sessionOpened,
|
|
381
|
-
unackedSends: sends,
|
|
382
|
-
correlationId,
|
|
383
|
-
});
|
|
384
|
-
result.sent += 1;
|
|
385
|
-
if (sends >= DELIVERY_MAX_UNACKED_SENDS) {
|
|
386
|
-
// THIS HOLDER is exhausted — retired, announced, and only theirs. The document
|
|
387
|
-
// stalls ONLY when every current holder is exhausted: one silent peer stopping a
|
|
388
|
-
// living collaboration is the exact availability failure the milestone forbids.
|
|
389
|
-
this.#store.abandonSingleHolderDelivery(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
390
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, envelope.envelopeHash, nowMs);
|
|
391
|
-
this.#logger.error("document.delivery.unacked_limit", {
|
|
392
|
-
documentId,
|
|
393
|
-
envelopeHash: envelope.envelopeHash,
|
|
394
|
-
holderAgentId,
|
|
395
|
-
sends,
|
|
396
|
-
correlationId,
|
|
397
|
-
detail: `this update has been delivered ${sends} times to this holder without their ` +
|
|
398
|
-
`daemon ever confirming it — delivery TO THEM is retired; every other holder ` +
|
|
399
|
-
`is unaffected. Check document.delivery.ack_grace_expired, ` +
|
|
400
|
-
`session.content.held.discarded, and whether their daemon has yet received ` +
|
|
401
|
-
`the amendment that added you (their log would show ` +
|
|
402
|
-
`document.inbound.sender_unknown_epoch_ahead) before concluding their client ` +
|
|
403
|
-
`is at fault.`,
|
|
404
|
-
});
|
|
405
|
-
const allExhausted = currentHolders
|
|
406
|
-
.filter((h) => h !== senderAgentId)
|
|
407
|
-
.every((h) => !this.#store.holderHasPending(ownerAgentId, documentId, h));
|
|
408
|
-
if (allExhausted) {
|
|
409
|
-
this.#store.setDocumentStatus(ownerAgentId, documentId, "stalled");
|
|
410
|
-
this.#logger.error("document.delivery.stalled_all_holders", {
|
|
411
|
-
documentId, correlationId,
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
else if (outcome.ok) {
|
|
417
|
-
const first = this.#store.ackHolderDelivery(ownerAgentId, documentId, envelope.envelopeHash, holderAgentId, nowMs);
|
|
418
|
-
// The envelope-level record follows the ONE terminal rule (review M3).
|
|
419
|
-
this.#store.reconcileEnvelopeSettlement(ownerAgentId, documentId, envelope.envelopeHash, nowMs);
|
|
420
|
-
this.#logger.info("document.delivery.session", {
|
|
421
|
-
documentId, holderAgentId, sessionId: outcome.sessionId,
|
|
422
|
-
opened: outcome.sessionOpened, correlationId,
|
|
423
|
-
});
|
|
424
|
-
if (outcome.admitted) {
|
|
425
|
-
// PROOF BY EPOCH (DOD-MP-INVITE-FANOUT-1). There is no amendment ack frame, but an
|
|
426
|
-
// ADMISSION is one: the inbound epoch gate requires the envelope's epoch to EQUAL the
|
|
427
|
-
// receiver's own derived epoch, so a holder that admitted an envelope at epoch E
|
|
428
|
-
// demonstrably holds every amendment up to E. Their acceptance of the content is an
|
|
429
|
-
// acceptance of the governance that made the content admissible — which settles the
|
|
430
|
-
// amendment row on evidence rather than on inference.
|
|
431
|
-
//
|
|
432
|
-
// ADMITTED ONLY, NEVER MERELY ANSWERED. A rejection is also an ack for delivery
|
|
433
|
-
// purposes, and it proves nothing here: the checks that run BEFORE the epoch gate —
|
|
434
|
-
// an unknown document, a failed signature — refuse terminally while the holder may be
|
|
435
|
-
// at any epoch at all. Settling on those would ack an amendment they do not have,
|
|
436
|
-
// which is the exact defect this queue exists to prevent, reintroduced one layer up.
|
|
437
|
-
const settled = this.#store.ackAmendmentsThroughEpoch(ownerAgentId, documentId, holderAgentId, envelope.epochId, nowMs);
|
|
438
|
-
if (settled > 0) {
|
|
439
|
-
this.#logger.info("document.amendment.confirmed_by_epoch", {
|
|
440
|
-
documentId, holderAgentId, epochId: envelope.epochId, settled, correlationId,
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
this.#logger.info("document.delivery.acked", {
|
|
444
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
445
|
-
sessionId: outcome.sessionId, firstAck: first, correlationId,
|
|
446
|
-
});
|
|
447
|
-
result.delivered += 1;
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
// PROOF THAT OUR CLOSE LANDED (DOD-MP-CONTROL-DURABLE-1). A control frame has no ack,
|
|
451
|
-
// and the tempting inference — "they closed, so they heard us" — is FALSE: a holder
|
|
452
|
-
// closes on their own initiative in the ordinary flow, having received nothing.
|
|
453
|
-
//
|
|
454
|
-
// This one is sound. A holder answers `document_closed` only once their status is
|
|
455
|
-
// closed, and that is set only when the settle finds a recorded close from OUR agent
|
|
456
|
-
// id — which is written only on receipt of our signed close frame. So this rejection
|
|
457
|
-
// is evidence, not inference. It does NOT generalise to `kill`: `document_killed` is
|
|
458
|
-
// equally produced by their own kill.
|
|
459
|
-
if (outcome.rejectionReason === "document_closed") {
|
|
460
|
-
this.#store.settleControlDelivery(ownerAgentId, documentId, "close", holderAgentId, nowMs, "acked");
|
|
461
|
-
}
|
|
462
|
-
this.#logger.warn("document.delivery.rejected", {
|
|
463
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
464
|
-
sessionId: outcome.sessionId, reason: outcome.rejectionReason, correlationId,
|
|
465
|
-
});
|
|
466
|
-
result.rejected += 1;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
this.#logger.warn("document.delivery.failed", {
|
|
471
|
-
documentId, envelopeHash: envelope.envelopeHash, holderAgentId,
|
|
472
|
-
reason: outcome.reason, detail: outcome.detail, attempts: row.attempts + 1,
|
|
473
|
-
correlationId,
|
|
474
|
-
});
|
|
475
|
-
result.failed += 1;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
// DOD-MP-CONTROL-DURABLE-1 — and then the rest. A document whose content has just gone out in
|
|
481
|
-
// this same pass gets its ending immediately after it, which is the order the receiver needs.
|
|
482
|
-
for (const owed of this.#store.pendingControlDeliveries(ownerAgentId, nowMs)) {
|
|
483
|
-
await this.#deliverControl(ownerAgentId, owed, nowMs, correlationId, result);
|
|
484
|
-
}
|
|
485
|
-
return result;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* One owed control frame — extracted so the drain can run in two phases without duplicating it.
|
|
489
|
-
*
|
|
490
|
-
* Control-first would not merely leave a holder with a lesser copy: the inbound path refuses
|
|
491
|
-
* envelopes on a closed or killed document TERMINALLY, and the worker treats a rejection as an
|
|
492
|
-
* ack — so every queued envelope would settle unsent and never be retried. Content-then-ending is
|
|
493
|
-
* what stops that content being silently lost.
|
|
494
|
-
*/
|
|
495
|
-
async #deliverControl(ownerAgentId, owed, nowMs, correlationId, result) {
|
|
496
|
-
// THE SAME DERIVATION THE NOTIFIER USED. Using the sweep's `holdersFor` here made a document
|
|
497
|
-
// with no stored genesis proposal a permanent no-op: seeded, sent once by the fast path, then
|
|
498
|
-
// rescheduled forever because the drain could not derive a recipient the notifier had already
|
|
499
|
-
// found. `controlHolders`'s own comment names this — the two paths must agree about what
|
|
500
|
-
// "cannot answer" means.
|
|
501
|
-
const derived = this.#controlHolders(owed.documentId);
|
|
502
|
-
if (!derived.ok) {
|
|
503
|
-
this.#store.recordControlAttempt(ownerAgentId, owed.documentId, owed.verb, owed.holderAgentId, nowMs + DELIVERY_UNRESOLVABLE_RETRY_MS);
|
|
504
|
-
// NOT SILENT. The sibling amendment branch logs for the reason its comment gives: the row
|
|
505
|
-
// would otherwise be re-scanned every tick forever with nothing said anywhere, and here the
|
|
506
|
-
// consequence is a holder who thinks the document is still open.
|
|
507
|
-
this.#logger.error("document.control.holders_underivable", {
|
|
508
|
-
documentId: owed.documentId,
|
|
509
|
-
holderAgentId: owed.holderAgentId,
|
|
510
|
-
verb: owed.verb,
|
|
511
|
-
reason: derived.reason,
|
|
512
|
-
correlationId,
|
|
513
|
-
impact: "this ending cannot be addressed to anyone — the holder will go on believing the " +
|
|
514
|
-
"document is open",
|
|
515
|
-
});
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
const holders = derived.holders;
|
|
519
|
-
// A holder the chain no longer contains is not owed the ending — removal already stopped
|
|
520
|
-
// delivery to them, and chasing them with a close would contradict the act that removed them.
|
|
521
|
-
// BOTH checks, matching the amendment loop: a disagreement between the derived set and the
|
|
522
|
-
// recorded removal would otherwise keep this loop dialing a locally-removed holder.
|
|
523
|
-
if (this.#store.memberRemoved(ownerAgentId, owed.documentId, owed.holderAgentId).removed
|
|
524
|
-
|| !holders.includes(owed.holderAgentId)) {
|
|
525
|
-
this.#store.settleControlDelivery(ownerAgentId, owed.documentId, owed.verb, owed.holderAgentId, nowMs, "retired");
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
// REPORTED EVEN WHEN WE HAVE NOT GIVEN UP. A holder we can never reach never advances
|
|
529
|
-
// `sends` (only a successful send does), so the ceiling below never fires for them — the loud
|
|
530
|
-
// report existed for the holder you CAN reach and not for the one the DoD line is actually
|
|
531
|
-
// about. This says so once, and keeps trying, because stopping would be the Entry-15 defect:
|
|
532
|
-
// quiet deferrals to an absent peer are not evidence that further tries are pointless.
|
|
533
|
-
if (owed.attempts === CONTROL_UNREACHABLE_REPORT_AFTER) {
|
|
534
|
-
this.#logger.error("document.control.unconfirmed", {
|
|
535
|
-
documentId: owed.documentId,
|
|
536
|
-
holderAgentId: owed.holderAgentId,
|
|
537
|
-
verb: owed.verb,
|
|
538
|
-
attempts: owed.attempts,
|
|
539
|
-
stillTrying: true,
|
|
540
|
-
correlationId,
|
|
541
|
-
impact: "this holder has not been reachable since the document ended — their copy may still " +
|
|
542
|
-
"be open, and delivery keeps trying",
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
if (owed.sends >= CONTROL_MAX_SENDS) {
|
|
546
|
-
// STOP, AND SAY SO. A control frame has no ack, so retrying forever would chatter at every
|
|
547
|
-
// holder for the life of the document. Retired rather than acked — the record must not
|
|
548
|
-
// claim they were told when nothing confirmed it — and at ERROR, because the consequence is
|
|
549
|
-
// that someone still believes this document is open.
|
|
550
|
-
this.#store.settleControlDelivery(ownerAgentId, owed.documentId, owed.verb, owed.holderAgentId, nowMs, "retired");
|
|
551
|
-
this.#logger.error("document.control.unconfirmed", {
|
|
552
|
-
documentId: owed.documentId,
|
|
553
|
-
holderAgentId: owed.holderAgentId,
|
|
554
|
-
verb: owed.verb,
|
|
555
|
-
sends: owed.sends,
|
|
556
|
-
correlationId,
|
|
557
|
-
impact: "this holder was never confirmed to have received the ending — their copy may still " +
|
|
558
|
-
"be open, and their next edit will be refused rather than applied",
|
|
559
|
-
});
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
result.attempted += 1;
|
|
563
|
-
// CLAIM THE ROW BEFORE DIALING, the rule both sibling loops state. Without it a crash
|
|
564
|
-
// mid-dial leaves the row immediately due with the counters unchanged, so a crash-looping
|
|
565
|
-
// daemon dials at full rate forever and never backs off — and the 60s sweep firing inside the
|
|
566
|
-
// notifier's own await sends the same close twice, which was PROVEN in review: both holders
|
|
567
|
-
// received it twice and 40% of the send ceiling was spent before the first retry.
|
|
568
|
-
this.#store.recordControlAttempt(ownerAgentId, owed.documentId, owed.verb, owed.holderAgentId, nowMs + backoffFor(owed.attempts));
|
|
569
|
-
try {
|
|
570
|
-
const sent = await this.#transport.sendBytes({
|
|
571
|
-
peerAgentId: owed.holderAgentId,
|
|
572
|
-
documentId: owed.documentId,
|
|
573
|
-
bytes: owed.bytes,
|
|
574
|
-
correlationId,
|
|
575
|
-
});
|
|
576
|
-
if (sent.ok && sent.parked !== true) {
|
|
577
|
-
this.#store.markControlSent(ownerAgentId, owed.documentId, owed.verb, owed.holderAgentId, nowMs, CONTROL_RESEND_AFTER_MS);
|
|
578
|
-
result.sent += 1;
|
|
579
|
-
}
|
|
580
|
-
else {
|
|
581
|
-
// Parked is not delivered, here for the same reason as everywhere else: the relay holding
|
|
582
|
-
// it is not the holder having it. The attempt was already claimed above.
|
|
583
|
-
result.failed += 1;
|
|
584
|
-
this.#logger.warn("document.control.delivery_failed", {
|
|
585
|
-
documentId: owed.documentId,
|
|
586
|
-
holderAgentId: owed.holderAgentId,
|
|
587
|
-
verb: owed.verb,
|
|
588
|
-
reason: sent.ok ? "relay_parked" : sent.reason,
|
|
589
|
-
detail: sent.ok ? "the relay is holding it — the holder had no live counterparty" : sent.detail,
|
|
590
|
-
attempts: owed.attempts + 1,
|
|
591
|
-
correlationId,
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
catch (err) {
|
|
596
|
-
result.failed += 1;
|
|
597
|
-
this.#logger.warn("document.control.delivery_failed", {
|
|
598
|
-
documentId: owed.documentId,
|
|
599
|
-
holderAgentId: owed.holderAgentId,
|
|
600
|
-
verb: owed.verb,
|
|
601
|
-
reason: "control_send_threw",
|
|
602
|
-
detail: err instanceof Error ? err.message : String(err),
|
|
603
|
-
correlationId,
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
//# 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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"}
|