@cello-protocol/daemon 0.0.207 → 0.0.209
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/agent-handlers.d.ts +12 -0
- package/dist/agent-handlers.d.ts.map +1 -1
- package/dist/agent-handlers.js +6 -2
- package/dist/agent-handlers.js.map +1 -1
- package/dist/attendance-wiring.js +2 -2
- package/dist/attendance-wiring.js.map +1 -1
- package/dist/boot-agents.d.ts.map +1 -1
- package/dist/boot-agents.js +5 -5
- package/dist/boot-agents.js.map +1 -1
- package/dist/close-session-handler.d.ts.map +1 -1
- package/dist/close-session-handler.js +26 -3
- package/dist/close-session-handler.js.map +1 -1
- package/dist/content-park.d.ts.map +1 -1
- package/dist/content-park.js +5 -3
- package/dist/content-park.js.map +1 -1
- package/dist/daemon.js +5 -4
- package/dist/daemon.js.map +1 -1
- package/dist/outbound-sessions.d.ts +27 -2
- package/dist/outbound-sessions.d.ts.map +1 -1
- package/dist/outbound-sessions.js +53 -3
- package/dist/outbound-sessions.js.map +1 -1
- package/dist/park-recovery.d.ts +3 -2
- package/dist/park-recovery.d.ts.map +1 -1
- package/dist/park-recovery.js +3 -2
- package/dist/park-recovery.js.map +1 -1
- package/dist/refusal-reasons.d.ts +46 -0
- package/dist/refusal-reasons.d.ts.map +1 -1
- package/dist/refusal-reasons.js +44 -0
- package/dist/refusal-reasons.js.map +1 -1
- package/dist/relay-only.d.ts +9 -2
- package/dist/relay-only.d.ts.map +1 -1
- package/dist/relay-only.js +9 -2
- package/dist/relay-only.js.map +1 -1
- package/dist/restart-seal-resolver.d.ts.map +1 -1
- package/dist/restart-seal-resolver.js +13 -0
- package/dist/restart-seal-resolver.js.map +1 -1
- package/dist/session-ceremony.d.ts +17 -0
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +77 -1
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-content-send.js +12 -11
- package/dist/session-content-send.js.map +1 -1
- package/dist/session-lifecycle.d.ts.map +1 -1
- package/dist/session-lifecycle.js +36 -0
- package/dist/session-lifecycle.js.map +1 -1
- package/dist/session-node-factory.js +4 -4
- package/dist/session-node-factory.js.map +1 -1
- package/dist/session-node-manager.d.ts +7 -2
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +22 -6
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-node-types.d.ts +79 -13
- package/dist/session-node-types.d.ts.map +1 -1
- package/dist/session-node-types.js +67 -0
- package/dist/session-node-types.js.map +1 -1
- package/dist/session-relay-client.d.ts +21 -0
- package/dist/session-relay-client.d.ts.map +1 -1
- package/dist/session-relay-client.js +219 -3
- package/dist/session-relay-client.js.map +1 -1
- package/dist/session-relay.d.ts +15 -1
- package/dist/session-relay.d.ts.map +1 -1
- package/dist/session-relay.js +264 -168
- package/dist/session-relay.js.map +1 -1
- package/dist/signaling-connect.d.ts.map +1 -1
- package/dist/signaling-connect.js +23 -4
- package/dist/signaling-connect.js.map +1 -1
- package/dist/signaling-wiring.js +7 -7
- package/dist/signaling-wiring.js.map +1 -1
- package/dist/standing-receivers.d.ts +53 -14
- package/dist/standing-receivers.d.ts.map +1 -1
- package/dist/standing-receivers.js +695 -500
- package/dist/standing-receivers.js.map +1 -1
- package/dist/trust-signal-sweep-tick.d.ts +60 -0
- package/dist/trust-signal-sweep-tick.d.ts.map +1 -0
- package/dist/trust-signal-sweep-tick.js +101 -0
- package/dist/trust-signal-sweep-tick.js.map +1 -0
- package/dist/trust-signal-sweep.d.ts +16 -1
- package/dist/trust-signal-sweep.d.ts.map +1 -1
- package/dist/trust-signal-sweep.js +40 -16
- package/dist/trust-signal-sweep.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +5 -5
|
@@ -340,6 +340,24 @@ export const REVIVAL_BOUND_SWEEP_MS = 60 * 60 * 1000;
|
|
|
340
340
|
/** DOD-M12B-SESSION-SEED-1: per-relay deadline when a revived node asks for a circuit reservation.
|
|
341
341
|
* Three seconds — a relay that has a slot answers well inside it, and one that does not never
|
|
342
342
|
* answers at all (measured: 10,002ms and still waiting). */
|
|
343
|
+
/**
|
|
344
|
+
* 055-ONDEMAND — how long a seal will wait to TELL a relay its slot is free.
|
|
345
|
+
*
|
|
346
|
+
* Short on purpose. Releasing is a courtesy that frees capacity; a seal is the thing the operator
|
|
347
|
+
* is waiting for. An undelivered release costs one slot until its reservation TTL, and that is a
|
|
348
|
+
* far better trade than a seal that waits on an unreachable relay's dial.
|
|
349
|
+
*/
|
|
350
|
+
export const RELEASE_TELL_BUDGET_MS = 3_000;
|
|
351
|
+
/**
|
|
352
|
+
* 055-ONDEMAND — how long a slot taken to answer an OFFER may sit before the offer is called dead.
|
|
353
|
+
*
|
|
354
|
+
* ⚠️ **NOT the directory's 2-second accept clock.** The accept only starts the ceremony: the
|
|
355
|
+
* assignment still has to be FROST-signed by a threshold of directory nodes and delivered to both
|
|
356
|
+
* parties before either builds a session node. Releasing on 2 s would take the slot out from under
|
|
357
|
+
* a session that was about to begin, turning a rare abandoned offer into a common broken session.
|
|
358
|
+
* Sixty seconds is far past any healthy ceremony and far short of the relay's two-hour TTL.
|
|
359
|
+
*/
|
|
360
|
+
export const OFFER_RESERVATION_GRACE_MS = 60_000;
|
|
343
361
|
export const REVIVE_RESERVATION_TIMEOUT_MS = 3_000;
|
|
344
362
|
/** How many relays a revival will ask before settling for a plain node. Two: the worst case is then
|
|
345
363
|
* ~6s to a usable session, against a measured "never" for the unbounded form. */
|
|
@@ -595,4 +613,53 @@ export const UNREAD_RECEIVED_WHERE = `
|
|
|
595
613
|
AND t.sequence > COALESCE(w.last_delivered_seq, -1)`;
|
|
596
614
|
export const REFUSED_SESSIONS_CAP = 200;
|
|
597
615
|
export const TERMINAL_STATUSES = `('sealed','abandoned','seal_interrupted_pending','interrupted')`;
|
|
616
|
+
/**
|
|
617
|
+
* A reservation ask that failed for a CLIENT-SIDE reason, named by the transport.
|
|
618
|
+
*
|
|
619
|
+
* ⚠️ **REVIEW HIGH-2 — WITHOUT THIS, A LIBP2P RENAME READS AS A CAPACITY OUTAGE.** When
|
|
620
|
+
* `listenOnCircuit` throws `transport_manager_unavailable`, the ask never reached the relay at all —
|
|
621
|
+
* but the generic decline below infers its reason from the connection state, finds the proof
|
|
622
|
+
* connection still open, and reports `relay_granted_no_reservation` on every relay in the pool. That
|
|
623
|
+
* string means *"relay CAPACITY, a trustless-cello problem"* in this daemon's own taxonomy, so an
|
|
624
|
+
* upstream API change would send an operator into the relay fleet while the real cause survived only
|
|
625
|
+
* as an `error` field on a warn line nothing surfaces.
|
|
626
|
+
*
|
|
627
|
+
* These faults are ours. They must be described in our vocabulary, not the relay's.
|
|
628
|
+
*/
|
|
629
|
+
export const CLIENT_SIDE_ASK_FAULTS = new Set(["transport_manager_unavailable", "not_a_circuit_address"]);
|
|
630
|
+
export function clientSideAskFault(err) {
|
|
631
|
+
const reason = err?.reason;
|
|
632
|
+
return typeof reason === "string" && CLIENT_SIDE_ASK_FAULTS.has(reason) ? reason : undefined;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Whether this node holds a granted reservation — i.e. announces a circuit address.
|
|
636
|
+
*
|
|
637
|
+
* Review LOW-5: `p2p-circuit` is read as a SEGMENT, the same rule `listenOnCircuit` applies to its
|
|
638
|
+
* own input. A substring test also matches a host or peer id that happens to contain the text, and
|
|
639
|
+
* the file should not argue one rule and apply another two lines later.
|
|
640
|
+
*/
|
|
641
|
+
export function holdsCircuit(node) {
|
|
642
|
+
return node.listenAddresses().some((a) => a.split("/").includes("p2p-circuit"));
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Wait for an abandoned candidate's outstanding work to settle, then stop it — but never wait
|
|
646
|
+
* forever.
|
|
647
|
+
*
|
|
648
|
+
* ⚠️ **REVIEW MEDIUM-4 — `allSettled` ON A PROMISE THAT CANNOT SETTLE NEVER RUNS THE TEARDOWN.**
|
|
649
|
+
* The teardown is chained onto the candidate's own work because `libp2p.stop()` returns immediately
|
|
650
|
+
* unless the node is `started`, so stopping a node mid-flight stops nothing. But a relay that
|
|
651
|
+
* accepts the stream and never answers leaves `listen()` pending forever — that is exactly the case
|
|
652
|
+
* `msg-027`'s fixture models — and the chained stop would then never fire at all, leaving a live
|
|
653
|
+
* node on the receiver's seed while the walk builds more nodes on that same seed.
|
|
654
|
+
*
|
|
655
|
+
* So: settle OR expire. The grace is generous relative to the ask's own deadline, because the point
|
|
656
|
+
* is to bound the wait, not to race it — a node that finishes at the last moment must still be
|
|
657
|
+
* stopped by its own settlement rather than while it is starting.
|
|
658
|
+
*/
|
|
659
|
+
export function stopWhenSettled(node, work, graceMs) {
|
|
660
|
+
const pending = work.filter((p) => p !== undefined);
|
|
661
|
+
const settled = Promise.allSettled(pending);
|
|
662
|
+
const bounded = new Promise((resolve) => { setTimeout(resolve, graceMs).unref?.(); });
|
|
663
|
+
void Promise.race([settled, bounded]).then(() => node.stop().catch(() => { }));
|
|
664
|
+
}
|
|
598
665
|
//# sourceMappingURL=session-node-types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-node-types.js","sourceRoot":"","sources":["../src/session-node-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"session-node-types.js","sourceRoot":"","sources":["../src/session-node-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,6 +52,7 @@ export interface RelayAuthRefusal {
|
|
|
52
52
|
/** Present when the relay said when to come back. */
|
|
53
53
|
retryAfterMs?: number;
|
|
54
54
|
}
|
|
55
|
+
export declare function isLocalCredentialRefusal(reason: string): boolean;
|
|
55
56
|
/**
|
|
56
57
|
* Classify a relay's auth refusal: what to tell the operator, and whether another relay would help.
|
|
57
58
|
*
|
|
@@ -382,6 +383,26 @@ export declare class AgentRelayClient {
|
|
|
382
383
|
* on a question already answered. Only a failure that never reached a verdict is retried.
|
|
383
384
|
*/
|
|
384
385
|
proveReservation(node: CelloNode): Promise<boolean>;
|
|
386
|
+
/**
|
|
387
|
+
* 054-SRSPLIT — **TELL THE RELAY WE ARE DONE WITH OUR SLOT.**
|
|
388
|
+
*
|
|
389
|
+
* Resolves whether the relay confirmed it freed one. `false` covers "we held none" and "we could
|
|
390
|
+
* not reach the relay to say so" alike, and the caller must not read it as failure: releasing is
|
|
391
|
+
* tidy-up, and one that could not be delivered costs a slot until its TTL rather than breaking
|
|
392
|
+
* anything the agent is doing. Every path that returns false says why.
|
|
393
|
+
*
|
|
394
|
+
* ⚠️ **IT GOES ON THE LONG-LIVED DELIVERY STREAM, NOT A RESERVATION-PURPOSE ONE, AND THAT IS NOT
|
|
395
|
+
* A STYLE CHOICE.** The first version opened a fresh stream and authenticated with
|
|
396
|
+
* `purpose: "reservation"` — mirroring the proof. The relay's handler treats that purpose as a
|
|
397
|
+
* proof and nothing else: it answers `relay_auth_ok`, **closes the stream and returns without
|
|
398
|
+
* entering the message loop**. So the release frame went into a stream nobody was reading, the
|
|
399
|
+
* reply never came, and the verb was inert while every test passed. Found in review, not by the
|
|
400
|
+
* suite.
|
|
401
|
+
*
|
|
402
|
+
* ⚠️ **THE FRAME CARRIES NO PEER ID, deliberately.** The relay frees the peer this connection
|
|
403
|
+
* authenticated as. A peer id on the wire would let any registered agent free another's.
|
|
404
|
+
*/
|
|
405
|
+
releaseReservation(node: CelloNode): Promise<boolean>;
|
|
385
406
|
/**
|
|
386
407
|
* Submit a session's CONTENT-leaf hash to the relay. Connects/re-connects from `node` if needed.
|
|
387
408
|
* Globally FIFO across the agent's sessions (the ack has no session_id).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-relay-client.d.ts","sourceRoot":"","sources":["../src/session-relay-client.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGzE,eAAO,MAAM,iBAAiB,uBAAuB,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAC1C,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,iFAAiF;AACjF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAgBtD,CAAC;AAEH,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAE1E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"session-relay-client.d.ts","sourceRoot":"","sources":["../src/session-relay-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -102,6 +102,34 @@ const RELAY_SIDE_REFUSALS = new Set([
|
|
|
102
102
|
*/
|
|
103
103
|
"online_token_no_directory_key",
|
|
104
104
|
]);
|
|
105
|
+
/**
|
|
106
|
+
* ─── WHOSE FAULT IS IT? — `DOD-M15-TOKENSTALE-1` ───────────────────────────────────────────────
|
|
107
|
+
*
|
|
108
|
+
* A SECOND question about the same refusal, and it is deliberately not `tryAnotherRelay` inverted.
|
|
109
|
+
* That one asks "would another relay help?"; this asks "is the broken thing ours?". They disagree
|
|
110
|
+
* on the case that matters: a slot cap is not worth failing over AND is entirely the relay's own
|
|
111
|
+
* answer about its own table — so reusing the failover flag to mean "our fault" would be right for
|
|
112
|
+
* the wrong reason, and would start telling operators their machine is broken when it is not.
|
|
113
|
+
*
|
|
114
|
+
* The consumer is the submit boundary. `#ensureConnected` returns a BOOLEAN, so every refusal below
|
|
115
|
+
* used to collapse into `relay_unavailable` — "the relay is unreachable", which is transient,
|
|
116
|
+
* somebody else's, and the documented reason a send degrades to an unwitnessed leaf and still
|
|
117
|
+
* reports success. An expired token is none of those. Measured live 2026-09-10: an agent reported
|
|
118
|
+
* `ok:true, delivered:true` on every send for over two days while the relay refused all thirteen
|
|
119
|
+
* authentications, and no conversation it held could produce a receipt.
|
|
120
|
+
*
|
|
121
|
+
* ⚠️ AN UNKNOWN REASON IS NOT LOCAL, and the direction of that default is a real choice. A future
|
|
122
|
+
* relay-side reason defaulting to "local" would accuse the reader's own machine, and a wrong
|
|
123
|
+
* accusation about your own setup costs more than a vague one about someone else's.
|
|
124
|
+
*/
|
|
125
|
+
const LOCAL_CREDENTIAL_REFUSALS = new Set([
|
|
126
|
+
"online_token_required",
|
|
127
|
+
"online_token_expired",
|
|
128
|
+
"online_token_pubkey_mismatch",
|
|
129
|
+
]);
|
|
130
|
+
export function isLocalCredentialRefusal(reason) {
|
|
131
|
+
return LOCAL_CREDENTIAL_REFUSALS.has(reason);
|
|
132
|
+
}
|
|
105
133
|
/**
|
|
106
134
|
* Classify a relay's auth refusal: what to tell the operator, and whether another relay would help.
|
|
107
135
|
*
|
|
@@ -121,8 +149,23 @@ export function classifyRelayAuthRefusal(reason, extra = {}) {
|
|
|
121
149
|
"it persists, the agent is not reaching any directory — check that first, not the relay.";
|
|
122
150
|
break;
|
|
123
151
|
case "online_token_expired":
|
|
124
|
-
|
|
125
|
-
|
|
152
|
+
/**
|
|
153
|
+
* ⚠️ THIS SENTENCE USED TO PROMISE A REFRESH THAT DOES NOT HAPPEN, and the promise is why the
|
|
154
|
+
* condition survived for days. It read: *"refreshed on the next directory connection"*. True,
|
|
155
|
+
* and useless — the token is issued only in the directory handshake, it lasts ONE HOUR, and a
|
|
156
|
+
* healthy agent does not make another connection. Measured on one box: a token at
|
|
157
|
+
* 2026-09-08 09:06 and the next over two days later.
|
|
158
|
+
*
|
|
159
|
+
* It now leads with the CONSEQUENCE, because the operator arrives here having been told every
|
|
160
|
+
* send succeeded, and names the one action that works today. The automatic refresh is
|
|
161
|
+
* `DOD-M15-TOKENSTALE-1` unit 2 and needs a directory frame that does not exist yet.
|
|
162
|
+
*/
|
|
163
|
+
advice = "This agent's pass from the directory has expired, so the relay is refusing to " +
|
|
164
|
+
"witness anything it sends: messages still arrive, but nothing is being recorded as proof " +
|
|
165
|
+
"and no conversation can produce a receipt until this clears. It is NOT refreshed while the " +
|
|
166
|
+
"daemon keeps running — restart it (cello logout, then cello login) and the next session " +
|
|
167
|
+
"will be witnessed again. If it comes back within the hour, this machine's clock or its " +
|
|
168
|
+
"directory connection is the thing to look at.";
|
|
126
169
|
break;
|
|
127
170
|
case "online_token_signature_invalid":
|
|
128
171
|
case "online_token_malformed":
|
|
@@ -313,6 +356,12 @@ export class AgentRelayClient {
|
|
|
313
356
|
* whether a different relay would do any better.
|
|
314
357
|
*/
|
|
315
358
|
#lastAuthRefusal = null;
|
|
359
|
+
/**
|
|
360
|
+
* review F6 — which credential refusal we have already explained in full, so a condition that
|
|
361
|
+
* lasts until a relogin is explained once rather than on every send. Reset with the refusal
|
|
362
|
+
* itself, so the next occurrence after a recovery is a first occurrence again.
|
|
363
|
+
*/
|
|
364
|
+
#loggedCredentialRefusal = null;
|
|
316
365
|
/** The last classified auth refusal from this relay, or null if the last attempt succeeded. */
|
|
317
366
|
getLastAuthRefusal() {
|
|
318
367
|
return this.#lastAuthRefusal;
|
|
@@ -326,6 +375,7 @@ export class AgentRelayClient {
|
|
|
326
375
|
* keeps the declared type and says what the reset is for.
|
|
327
376
|
*/
|
|
328
377
|
#clearAuthRefusal() {
|
|
378
|
+
this.#loggedCredentialRefusal = null;
|
|
329
379
|
this.#lastAuthRefusal = null;
|
|
330
380
|
}
|
|
331
381
|
#stream = null;
|
|
@@ -376,6 +426,11 @@ export class AgentRelayClient {
|
|
|
376
426
|
* the same `#submitChain` as submits, guaranteeing no overlap.
|
|
377
427
|
*/
|
|
378
428
|
#pendingRecord = null;
|
|
429
|
+
/**
|
|
430
|
+
* 054-SRSPLIT — the in-flight `relay_release_reservation`. At most one: releases are rare and
|
|
431
|
+
* serialized on the shared stream, exactly like `#pendingRecord`, whose ack also carries no id.
|
|
432
|
+
*/
|
|
433
|
+
#pendingRelease = null;
|
|
379
434
|
/** Serializes submits so only one is in flight at a time across all sessions. */
|
|
380
435
|
#submitChain = Promise.resolve();
|
|
381
436
|
/** session_id hex → { the live node to (re)dial from, inbound leaf handler, Option-B assignment to present }. */
|
|
@@ -823,6 +878,14 @@ export class AgentRelayClient {
|
|
|
823
878
|
...(retry_after_ms !== undefined ? { retry_after_ms } : {}),
|
|
824
879
|
});
|
|
825
880
|
}
|
|
881
|
+
else if (type === "relay_release_ok") {
|
|
882
|
+
// 054-SRSPLIT. `released` is the relay's own answer to "did I actually hold one?" — a
|
|
883
|
+
// release of a slot we never had is a true `false`, not a failure, and the caller says so.
|
|
884
|
+
const r = this.#pendingRelease;
|
|
885
|
+
this.#pendingRelease = null;
|
|
886
|
+
if (r)
|
|
887
|
+
r(frame["released"] === true);
|
|
888
|
+
}
|
|
826
889
|
else if (type === "assignment_ok") {
|
|
827
890
|
// The relay verified + recorded our client-presented assignment.
|
|
828
891
|
const r = this.#pendingRecord;
|
|
@@ -1364,6 +1427,85 @@ export class AgentRelayClient {
|
|
|
1364
1427
|
await stream.close().catch(() => { });
|
|
1365
1428
|
}
|
|
1366
1429
|
}
|
|
1430
|
+
/**
|
|
1431
|
+
* 054-SRSPLIT — **TELL THE RELAY WE ARE DONE WITH OUR SLOT.**
|
|
1432
|
+
*
|
|
1433
|
+
* Resolves whether the relay confirmed it freed one. `false` covers "we held none" and "we could
|
|
1434
|
+
* not reach the relay to say so" alike, and the caller must not read it as failure: releasing is
|
|
1435
|
+
* tidy-up, and one that could not be delivered costs a slot until its TTL rather than breaking
|
|
1436
|
+
* anything the agent is doing. Every path that returns false says why.
|
|
1437
|
+
*
|
|
1438
|
+
* ⚠️ **IT GOES ON THE LONG-LIVED DELIVERY STREAM, NOT A RESERVATION-PURPOSE ONE, AND THAT IS NOT
|
|
1439
|
+
* A STYLE CHOICE.** The first version opened a fresh stream and authenticated with
|
|
1440
|
+
* `purpose: "reservation"` — mirroring the proof. The relay's handler treats that purpose as a
|
|
1441
|
+
* proof and nothing else: it answers `relay_auth_ok`, **closes the stream and returns without
|
|
1442
|
+
* entering the message loop**. So the release frame went into a stream nobody was reading, the
|
|
1443
|
+
* reply never came, and the verb was inert while every test passed. Found in review, not by the
|
|
1444
|
+
* suite.
|
|
1445
|
+
*
|
|
1446
|
+
* ⚠️ **THE FRAME CARRIES NO PEER ID, deliberately.** The relay frees the peer this connection
|
|
1447
|
+
* authenticated as. A peer id on the wire would let any registered agent free another's.
|
|
1448
|
+
*/
|
|
1449
|
+
async releaseReservation(node) {
|
|
1450
|
+
if (this.#closed)
|
|
1451
|
+
return false;
|
|
1452
|
+
if (!(await this.#ensureConnected(node))) {
|
|
1453
|
+
this.#logger.warn("session.relay.reservation_release.failed", {
|
|
1454
|
+
relayPeerId: this.#relayPeerId,
|
|
1455
|
+
reason: "not_connected",
|
|
1456
|
+
impact: "this relay was not told the slot is free, so it holds it until the reservation " +
|
|
1457
|
+
"TTL expires. Nothing the agent is doing is affected.",
|
|
1458
|
+
});
|
|
1459
|
+
return false;
|
|
1460
|
+
}
|
|
1461
|
+
const stream = this.#stream;
|
|
1462
|
+
if (!stream)
|
|
1463
|
+
return false;
|
|
1464
|
+
let resolveRel;
|
|
1465
|
+
const relPromise = new Promise((r) => { resolveRel = r; });
|
|
1466
|
+
this.#pendingRelease = resolveRel;
|
|
1467
|
+
try {
|
|
1468
|
+
stream.send(lp.encode.single(encodeCbor({ type: "relay_release_reservation" })));
|
|
1469
|
+
}
|
|
1470
|
+
catch (err) {
|
|
1471
|
+
if (this.#pendingRelease === resolveRel)
|
|
1472
|
+
this.#pendingRelease = null;
|
|
1473
|
+
this.#logger.warn("session.relay.reservation_release.failed", {
|
|
1474
|
+
relayPeerId: this.#relayPeerId,
|
|
1475
|
+
reason: "send",
|
|
1476
|
+
error: extractErrorMessage(err),
|
|
1477
|
+
impact: "the relay holds the slot until its TTL expires.",
|
|
1478
|
+
});
|
|
1479
|
+
return false;
|
|
1480
|
+
}
|
|
1481
|
+
let timer;
|
|
1482
|
+
const timeout = new Promise((r) => { timer = setTimeout(() => r("timeout"), HASH_SUBMIT_TIMEOUT_MS); });
|
|
1483
|
+
try {
|
|
1484
|
+
const result = await Promise.race([relPromise, timeout]);
|
|
1485
|
+
if (result === "timeout") {
|
|
1486
|
+
// NOT a stream reset. A release is not ordered against anything — no ack of a later frame
|
|
1487
|
+
// can be settled by a late reply to this one, because the reader clears the resolver — so
|
|
1488
|
+
// tearing the stream down would cost sibling sessions their in-flight submits for a tidy-up.
|
|
1489
|
+
this.#logger.warn("session.relay.reservation_release.failed", {
|
|
1490
|
+
relayPeerId: this.#relayPeerId,
|
|
1491
|
+
reason: "no_reply",
|
|
1492
|
+
impact: "the relay did not answer, so it holds the slot until its TTL expires.",
|
|
1493
|
+
});
|
|
1494
|
+
return false;
|
|
1495
|
+
}
|
|
1496
|
+
this.#logger.info("session.relay.reservation_release.result", {
|
|
1497
|
+
relayPeerId: this.#relayPeerId,
|
|
1498
|
+
nodePeerId: node.getPeerId(),
|
|
1499
|
+
released: result,
|
|
1500
|
+
});
|
|
1501
|
+
return result;
|
|
1502
|
+
}
|
|
1503
|
+
finally {
|
|
1504
|
+
clearTimeout(timer);
|
|
1505
|
+
if (this.#pendingRelease === resolveRel)
|
|
1506
|
+
this.#pendingRelease = null;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1367
1509
|
/** Ensure an authenticated stream exists, (re)dialing from `node` if needed. */
|
|
1368
1510
|
async #ensureConnected(node) {
|
|
1369
1511
|
if (this.#closed)
|
|
@@ -1376,6 +1518,22 @@ export class AgentRelayClient {
|
|
|
1376
1518
|
return this.#connecting;
|
|
1377
1519
|
}
|
|
1378
1520
|
async #connect(node) {
|
|
1521
|
+
/**
|
|
1522
|
+
* ⚠️ DROP THE PREVIOUS ATTEMPT'S VERDICT FIRST — `DOD-M15-TOKENSTALE-1` review F4, and the same
|
|
1523
|
+
* reasoning `#proveReservationOnce` already carries in capitals twelve lines from here.
|
|
1524
|
+
*
|
|
1525
|
+
* `#lastAuthRefusal` is cleared only on auth SUCCESS. Both failure exits below — the dial and
|
|
1526
|
+
* the stream open — are transport failures that never reach a verdict at all, so without this
|
|
1527
|
+
* they return `false` carrying whatever an earlier attempt left behind.
|
|
1528
|
+
*
|
|
1529
|
+
* That was survivable while the submit boundary answered `relay_unavailable` for every `false`.
|
|
1530
|
+
* It is not now: this unit makes that boundary REPORT the stored refusal, so a stale
|
|
1531
|
+
* `online_token_expired` would relabel a relay that is genuinely down as our own dead
|
|
1532
|
+
* credential — sending the operator to restart their daemon over somebody else's outage, and
|
|
1533
|
+
* stripping the seal fallbacks that exist for exactly that outage. Clearing here is what makes
|
|
1534
|
+
* the promotion mean "this attempt's verdict" instead of "some past verdict".
|
|
1535
|
+
*/
|
|
1536
|
+
this.#clearAuthRefusal();
|
|
1379
1537
|
// Best-effort dial: newStream auto-dials a known peer, but the relay's addrs may not
|
|
1380
1538
|
// be in the peerstore yet, so dial each addr first. One success is enough.
|
|
1381
1539
|
let dialed = false;
|
|
@@ -1595,6 +1753,14 @@ export class AgentRelayClient {
|
|
|
1595
1753
|
if (r)
|
|
1596
1754
|
r("closed");
|
|
1597
1755
|
}
|
|
1756
|
+
// 054-SRSPLIT: settle an in-flight release too, so it does not wait its full timeout on a
|
|
1757
|
+
// stream that is already gone. `false` is honest — the relay was not told.
|
|
1758
|
+
{
|
|
1759
|
+
const r = this.#pendingRelease;
|
|
1760
|
+
this.#pendingRelease = null;
|
|
1761
|
+
if (r)
|
|
1762
|
+
r(false);
|
|
1763
|
+
}
|
|
1598
1764
|
// A pure-receiver session issues no submit, so it would never trigger a re-dial
|
|
1599
1765
|
// after the node that owned the stream is torn down. If sessions remain, proactively
|
|
1600
1766
|
// re-establish from any still-live registered session node so queued leaf_delivers
|
|
@@ -1927,8 +2093,58 @@ export class AgentRelayClient {
|
|
|
1927
2093
|
async #doSubmitOnce(node, sessionId, contentHash, leafKind, contentBytes, carried) {
|
|
1928
2094
|
if (this.#closed)
|
|
1929
2095
|
return { ok: false, reason: "relay_client_closed" };
|
|
1930
|
-
if (!(await this.#ensureConnected(node)))
|
|
2096
|
+
if (!(await this.#ensureConnected(node))) {
|
|
2097
|
+
/**
|
|
2098
|
+
* ─── OUR OWN DEAD CREDENTIAL IS NOT A RELAY OUTAGE — `DOD-M15-TOKENSTALE-1` ───────────────
|
|
2099
|
+
*
|
|
2100
|
+
* `#ensureConnected` answers with a BOOLEAN, so every reason a relay ever gave for refusing
|
|
2101
|
+
* us arrived here as `false` and left as `relay_unavailable`. That word is a claim about the
|
|
2102
|
+
* RELAY: unreachable, transient, someone else's, and the documented grounds on which a send
|
|
2103
|
+
* appends an unwitnessed leaf and still reports success.
|
|
2104
|
+
*
|
|
2105
|
+
* An expired online token is the opposite on all four counts, and the cost of the mislabel is
|
|
2106
|
+
* not cosmetic. Measured live 2026-09-10: an agent ran for over two days answering
|
|
2107
|
+
* `ok:true, delivered:true` to every send while the relay refused all thirteen of its
|
|
2108
|
+
* authentications. Nothing it said in that time could ever produce a receipt, and no surface
|
|
2109
|
+
* anywhere said so — because the one place that knew called it a relay problem.
|
|
2110
|
+
*
|
|
2111
|
+
* `#lastAuthRefusal` already held the truth (`cello status` reads it); the submit path simply
|
|
2112
|
+
* never looked. Only LOCAL refusals are promoted: a genuine relay fault keeps
|
|
2113
|
+
* `relay_unavailable`, so this is a split rather than a rename, and the caller's existing
|
|
2114
|
+
* degradation for a real outage is untouched.
|
|
2115
|
+
*/
|
|
2116
|
+
const refusal = this.#lastAuthRefusal;
|
|
2117
|
+
if (refusal && isLocalCredentialRefusal(refusal.reason)) {
|
|
2118
|
+
/**
|
|
2119
|
+
* ⚠️ THE PROSE ONCE PER TRANSITION, THE REASON EVERY TIME — review F6.
|
|
2120
|
+
*
|
|
2121
|
+
* This condition lasts until a relogin by construction, and every send retries it. Logging
|
|
2122
|
+
* several hundred bytes of explanation on each one is the shape `96f3179b` measured four
|
|
2123
|
+
* commits earlier: a 176 MB log that was 95% one already-fixed defect repeating itself,
|
|
2124
|
+
* which hid the defect that produced it for eleven hours. The first occurrence carries
|
|
2125
|
+
* everything; the rest are countable without being unreadable.
|
|
2126
|
+
*/
|
|
2127
|
+
const firstOfThisRun = this.#loggedCredentialRefusal !== refusal.reason;
|
|
2128
|
+
this.#loggedCredentialRefusal = refusal.reason;
|
|
2129
|
+
if (firstOfThisRun) {
|
|
2130
|
+
this.#logger.error("session.relay.submit.local_credential_refusal", {
|
|
2131
|
+
relayPeerId: this.#relayPeerId,
|
|
2132
|
+
reason: refusal.reason,
|
|
2133
|
+
impact: "the relay refused THIS AGENT'S credential, so nothing it sends can be witnessed and no " +
|
|
2134
|
+
"conversation can produce a receipt. This is a fault on this machine and it does not " +
|
|
2135
|
+
"clear on its own — it is NOT the relay being unreachable.",
|
|
2136
|
+
guidance: refusal.advice,
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
else {
|
|
2140
|
+
this.#logger.warn("session.relay.submit.local_credential_refusal.again", {
|
|
2141
|
+
relayPeerId: this.#relayPeerId, reason: refusal.reason,
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
return { ok: false, reason: refusal.reason };
|
|
2145
|
+
}
|
|
1931
2146
|
return { ok: false, reason: "relay_unavailable" };
|
|
2147
|
+
}
|
|
1932
2148
|
const sessionIdHex = Buffer.from(sessionId).toString("hex");
|
|
1933
2149
|
// The relay records the session from the CLIENT-presented assignment. It MUST be recorded BEFORE
|
|
1934
2150
|
// the first hash_submit — the relay rejects a submit for an unknown session. Idempotent + no-op when
|