@cello-protocol/daemon 0.0.20 → 0.0.22

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.
@@ -145,6 +145,13 @@ export declare class SessionNodeManager {
145
145
  * dialability the conservative default and fires transport.autonat.unavailable.
146
146
  */
147
147
  autoNatProbers?: () => string[];
148
+ /**
149
+ * M8B F14: backoff schedule for standing-receiver create retries. Attempt 1 runs
150
+ * immediately; each entry is the delay before the next attempt. Default covers the
151
+ * fixed-port race where a teardown and a re-arm interleave (EADDRINUSE clears once
152
+ * the old node's port is released). Tests inject short delays or [] (no retries).
153
+ */
154
+ standingReceiverRetryDelaysMs?: number[];
148
155
  });
149
156
  /**
150
157
  * CELLO-M7-MSG-001: wire the durable-backstop side effects of the awaiting-ACK
@@ -498,6 +505,8 @@ export declare class SessionNodeManager {
498
505
  } | {
499
506
  ok: false;
500
507
  reason: string;
508
+ reportedRootHex?: string;
509
+ sequenceNumber?: number;
501
510
  }>;
502
511
  /**
503
512
  * CELLO-M7-UPGRADE-001 (DOD-UP-1): readiness of a session for B to RATIFY a unilateral seal
@@ -627,6 +636,8 @@ export declare class SessionNodeManager {
627
636
  /**
628
637
  * DOD-LOOP-1: public hook for the composition root to create an agent's standing receiver when
629
638
  * the agent comes online (cello_start_agent), and to tear it down when it goes offline.
639
+ * M8B F14: also called from the inbound accept path (ensure on demand). Marks the agent as
640
+ * WANTING a receiver, which arms the teardown re-arm in destroySessionNode/retireSessionNode.
630
641
  */
631
642
  ensureStandingReceiverForAgent(agentName: string): Promise<void>;
632
643
  removeStandingReceiverForAgent(agentName: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"session-node-manager.d.ts","sourceRoot":"","sources":["../src/session-node-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-node-manager.d.ts","sourceRoot":"","sources":["../src/session-node-manager.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,13 @@ export class SessionNodeManager {
104
104
  // prevents two concurrent ensure() calls from building two nodes for the same agent.
105
105
  #standingReceivers = new Map();
106
106
  #standingReceiverCreating = new Set();
107
+ // M8B F14: agents that SHOULD have a standing receiver — marked by
108
+ // ensureStandingReceiverForAgent (cello_start_agent / the inbound accept path) and
109
+ // unmarked by removeStandingReceiverForAgent (cello_stop_agent). Consulted by the
110
+ // teardown re-arm so a session-node teardown never re-arms an offline agent.
111
+ #agentsWantingReceiver = new Set();
112
+ // M8B F14: standing-receiver create retry schedule (see constructor opts).
113
+ #srRetryDelaysMs;
107
114
  // Agents whose removeStandingReceiverForAgent ran while an #ensureStandingReceiver for them was
108
115
  // in flight (parked on createNode/start, so the map had no entry to delete yet). The in-flight
109
116
  // ensure checks this after start() and tears the fresh node down instead of installing an SR for
@@ -164,7 +171,10 @@ export class SessionNodeManager {
164
171
  // M7-UPGRADE-002: sessions for which B has already submitted its responder SEAL leaf (via
165
172
  // auto-ack OR cello_close_session). Idempotency guard — A's SEAL ctrl leaf may be delivered
166
173
  // more than once (and the relay echoes leaves), so auto-ack fires AT MOST ONCE per session.
167
- #responderSealSubmitted = new Set();
174
+ // M8B FINDING-1: the value carries the first successful submit's reportedRootHex/sequenceNumber
175
+ // (null while the submit is still in flight), so a RETRY close can escalate to a unilateral
176
+ // seal with the original reported root instead of deadlocking on seal_pending_bilateral.
177
+ #responderSealSubmitted = new Map();
168
178
  // M7-SESSION-001 (M-1 PUSH): optional callback fired when a session changes
169
179
  // state, so the composition root can dispatch a session_state_changed
170
180
  // notification to live MCP clients. Injected via a setter AFTER construction
@@ -203,6 +213,7 @@ export class SessionNodeManager {
203
213
  this.#contentTtfMs = opts.contentTtfMs;
204
214
  }
205
215
  this.#autoNatProbers = opts.autoNatProbers ?? (() => []);
216
+ this.#srRetryDelaysMs = opts.standingReceiverRetryDelaysMs ?? [1_000, 5_000, 15_000];
206
217
  }
207
218
  /**
208
219
  * CELLO-M7-MSG-001: wire the durable-backstop side effects of the awaiting-ACK
@@ -1024,6 +1035,26 @@ export class SessionNodeManager {
1024
1035
  agentName: entry.agentName,
1025
1036
  reason,
1026
1037
  });
1038
+ // M8B F14 (fix 1): the torn-down node has just released its port — on a fixed-port
1039
+ // deployment this is the FIRST moment a previously-failed re-arm can succeed. Re-arm
1040
+ // the standing receiver for an online agent that has none (async, never awaited).
1041
+ this.#rearmAfterTeardown(agentName);
1042
+ }
1043
+ /**
1044
+ * M8B F14: re-arm an online agent's standing receiver after a session-node teardown
1045
+ * freed resources (notably the fixed port). No-op when the agent is offline, already
1046
+ * has a receiver, or one is being created. The re-arm is a NEW async flow — it mints
1047
+ * its own correlationId (via the ensure default) rather than inheriting the torn-down
1048
+ * session's.
1049
+ */
1050
+ #rearmAfterTeardown(agentName) {
1051
+ if (this.#shuttingDown)
1052
+ return;
1053
+ if (!this.#agentsWantingReceiver.has(agentName))
1054
+ return;
1055
+ if (this.#standingReceivers.has(agentName) || this.#standingReceiverCreating.has(agentName))
1056
+ return;
1057
+ void this.#ensureStandingReceiver(agentName);
1027
1058
  }
1028
1059
  /**
1029
1060
  * round-2 finding #5: retire a session's live libp2p node WITHOUT changing its
@@ -1058,6 +1089,8 @@ export class SessionNodeManager {
1058
1089
  agentName: entry.agentName,
1059
1090
  reason: "sealing",
1060
1091
  });
1092
+ // M8B F14 (fix 1): same re-arm point as destroySessionNode — the retired node freed its port.
1093
+ this.#rearmAfterTeardown(agentName);
1061
1094
  }
1062
1095
  /** Drop the in-memory tree + received-content caches for a torn-down session (DOD-LOOP-1: per (agent, session)). */
1063
1096
  #evictSessionCaches(agentName, sessionId) {
@@ -1345,6 +1378,17 @@ export class SessionNodeManager {
1345
1378
  agentName,
1346
1379
  reason: "interrupted",
1347
1380
  });
1381
+ // DELIBERATELY NOT #evictSessionCaches here (unlike destroySessionNode/retireSessionNode):
1382
+ // an interrupted session is not terminal. (1) #receivedContent must stay drainable — the
1383
+ // record survives, and cello_receive legitimately reads buffered unread messages after a
1384
+ // transient relay blip; evicting would silently discard deliverable plaintext. (2) Evict
1385
+ // also cancels armed TTF timers (#clearAwaitingForSession) — on a dying session the TTF
1386
+ // park backstop is exactly what must fire for un-acked content (MSG-001). The caches are
1387
+ // reclaimed when the session later seals (destroy/retire paths) or at daemon restart.
1388
+ // M8B F14 (fix 1): the relay-detected interruption is the THIRD teardown path that
1389
+ // frees the fixed port — it must re-arm too, or a session ending on a network blip
1390
+ // leaves the agent deaf again (review finding on the F14 fix).
1391
+ this.#rearmAfterTeardown(agentName);
1348
1392
  }
1349
1393
  this.#logger.warn("session.interrupted.detected", {
1350
1394
  sessionId,
@@ -1744,40 +1788,63 @@ export class SessionNodeManager {
1744
1788
  // two near-simultaneous triggers (e.g. B's own close racing A's delivered SEAL ctrl leaf) cannot
1745
1789
  // both submit. Cleared below on a relay submit failure so a genuine retry can proceed.
1746
1790
  if (this.#responderSealSubmitted.has(sealKey)) {
1747
- return { ok: false, reason: "responder_seal_already_submitted" };
1748
- }
1749
- this.#responderSealSubmitted.add(sealKey);
1750
- const finalRootHex = this.getSessionTreeRootHex(agentName, sessionId);
1751
- const sealPayload = encodeSealPayload({
1752
- session_id: entry.relaySessionIdBytes,
1753
- final_root: new Uint8Array(Buffer.from(finalRootHex, "hex")),
1754
- close_timestamp: Date.now(),
1755
- attestation: "PENDING",
1756
- });
1757
- // content_hash = SHA-256(0x02 || seal_payload) — the ctrl leaf kind byte is 0x02.
1758
- const contentHash = new Uint8Array(createHash("sha256").update(new Uint8Array([LEAF_KIND_CTRL])).update(sealPayload).digest());
1759
- const result = await entry.relayClient.submitLeaf(entry.node, entry.relaySessionIdBytes, contentHash, LEAF_KIND_CTRL);
1760
- if (!result.ok) {
1761
- // Clear the idempotency mark so a genuine retry (agent close / reconnect) can proceed (DB-001).
1791
+ // M8B FINDING-1: carry the FIRST submit's reported root/sequence so a retry close can
1792
+ // still escalate to a unilateral seal. A null value means that submit is still in
1793
+ // flight — return the bare reason and let the caller fall back to the pending path.
1794
+ const prior = this.#responderSealSubmitted.get(sealKey);
1795
+ return prior
1796
+ ? {
1797
+ ok: false,
1798
+ reason: "responder_seal_already_submitted",
1799
+ reportedRootHex: prior.reportedRootHex,
1800
+ sequenceNumber: prior.sequenceNumber,
1801
+ }
1802
+ : { ok: false, reason: "responder_seal_already_submitted" };
1803
+ }
1804
+ this.#responderSealSubmitted.set(sealKey, null);
1805
+ // A throw anywhere before the mark is finalized would strand the null in-flight marker
1806
+ // and lock every future close out of escalation (a FINDING-1-shaped deadlock via a
1807
+ // different trigger) — clear the mark on any unexpected exception.
1808
+ try {
1809
+ const finalRootHex = this.getSessionTreeRootHex(agentName, sessionId);
1810
+ const sealPayload = encodeSealPayload({
1811
+ session_id: entry.relaySessionIdBytes,
1812
+ final_root: new Uint8Array(Buffer.from(finalRootHex, "hex")),
1813
+ close_timestamp: Date.now(),
1814
+ attestation: "PENDING",
1815
+ });
1816
+ // content_hash = SHA-256(0x02 || seal_payload) — the ctrl leaf kind byte is 0x02.
1817
+ const contentHash = new Uint8Array(createHash("sha256").update(new Uint8Array([LEAF_KIND_CTRL])).update(sealPayload).digest());
1818
+ const result = await entry.relayClient.submitLeaf(entry.node, entry.relaySessionIdBytes, contentHash, LEAF_KIND_CTRL);
1819
+ if (!result.ok) {
1820
+ // Clear the idempotency mark so a genuine retry (agent close / reconnect) can proceed (DB-001).
1821
+ this.#responderSealSubmitted.delete(sealKey);
1822
+ this.#logger.warn("session.seal.leaf.submit.failed", { sessionId, reason: result.reason, correlationId });
1823
+ return { ok: false, reason: result.reason };
1824
+ }
1825
+ // SESSION-002: the reported_root for a unilateral seal is the content-hash root the
1826
+ // local tree WOULD have with this SEAL ctrl leaf appended — the same root the directory
1827
+ // rebuilds from the relay's content-hash chain (the relay records the identical
1828
+ // content_hash for this ctrl leaf). Computed without mutating the durable tree /
1829
+ // message_count, so the bilateral + interrupted seal paths are unaffected.
1830
+ const contentHashHex = Buffer.from(contentHash).toString("hex");
1831
+ const reportedRootHex = this.getSessionTree(agentName, sessionId).rootWithAppendedHex(contentHashHex);
1832
+ // M8B FINDING-1: durably associate the submit's escalation values with the idempotency
1833
+ // mark, so any LATER close call can retrieve them via the already-submitted result.
1834
+ this.#responderSealSubmitted.set(sealKey, { reportedRootHex, sequenceNumber: result.sequence_number });
1835
+ this.#logger.info("session.seal.leaf.submitted", {
1836
+ sessionId,
1837
+ sequenceNumber: result.sequence_number,
1838
+ correlationId,
1839
+ });
1840
+ // M7-UPGRADE-002: #responderSealSubmitted was set synchronously at the top of this method —
1841
+ // the guard now blocks any second submit (auto-ack OR a redelivered counterparty SEAL ctrl leaf).
1842
+ return { ok: true, sequenceNumber: result.sequence_number, reportedRootHex };
1843
+ }
1844
+ catch (err) {
1762
1845
  this.#responderSealSubmitted.delete(sealKey);
1763
- this.#logger.warn("session.seal.leaf.submit.failed", { sessionId, reason: result.reason, correlationId });
1764
- return { ok: false, reason: result.reason };
1765
- }
1766
- // SESSION-002: the reported_root for a unilateral seal is the content-hash root the
1767
- // local tree WOULD have with this SEAL ctrl leaf appended — the same root the directory
1768
- // rebuilds from the relay's content-hash chain (the relay records the identical
1769
- // content_hash for this ctrl leaf). Computed without mutating the durable tree /
1770
- // message_count, so the bilateral + interrupted seal paths are unaffected.
1771
- const contentHashHex = Buffer.from(contentHash).toString("hex");
1772
- const reportedRootHex = this.getSessionTree(agentName, sessionId).rootWithAppendedHex(contentHashHex);
1773
- this.#logger.info("session.seal.leaf.submitted", {
1774
- sessionId,
1775
- sequenceNumber: result.sequence_number,
1776
- correlationId,
1777
- });
1778
- // M7-UPGRADE-002: #responderSealSubmitted was set synchronously at the top of this method —
1779
- // the guard now blocks any second submit (auto-ack OR a redelivered counterparty SEAL ctrl leaf).
1780
- return { ok: true, sequenceNumber: result.sequence_number, reportedRootHex };
1846
+ throw err;
1847
+ }
1781
1848
  }
1782
1849
  /**
1783
1850
  * CELLO-M7-UPGRADE-001 (DOD-UP-1): readiness of a session for B to RATIFY a unilateral seal
@@ -2582,8 +2649,15 @@ export class SessionNodeManager {
2582
2649
  * DOD-LOOP-1: ensure the given agent has a standing receiver node (idempotent). Created when an
2583
2650
  * agent comes online (cello_start_agent) and replaced after it is handed off to a session. The
2584
2651
  * `#standingReceiverCreating` guard prevents two concurrent ensure() calls (e.g. the
2585
- * cello_start_agent hook racing a consume-site retry) from building two nodes for one agent. A
2586
- * create failure logs + leaves no entry; the next consume-site ensure() call retries on demand.
2652
+ * cello_start_agent hook racing a consume-site retry) from building two nodes for one agent.
2653
+ *
2654
+ * M8B F14: a create failure no longer strands the agent deaf. Each ensure runs a BOUNDED
2655
+ * retry loop (`standingReceiverRetryDelaysMs`, default 1s/5s/15s) — covering the fixed-port
2656
+ * race where the consumed receiver still holds the port until its session node is torn down —
2657
+ * and when every attempt fails, fires the alarm-worthy `session.standing_receiver.dead`
2658
+ * (error level), distinct from the per-attempt `session.node.create.failed`. Re-arm is also
2659
+ * kicked from destroySessionNode/retireSessionNode (the moment the port frees) and from the
2660
+ * inbound accept path (ensure on demand), so one failure can never leave the agent deaf forever.
2587
2661
  */
2588
2662
  async #ensureStandingReceiver(agentName, correlationId = randomUUID()) {
2589
2663
  if (this.#standingReceivers.has(agentName) || this.#standingReceiverCreating.has(agentName))
@@ -2594,76 +2668,111 @@ export class SessionNodeManager {
2594
2668
  this.#standingReceiverRemoving.delete(agentName);
2595
2669
  this.#standingReceiverCreating.add(agentName);
2596
2670
  try {
2597
- const sessionId = `standing_receiver_${randomUUID()}`;
2598
- const gater = new SessionConnectionGater({
2599
- sessionId,
2600
- allowedPeerId: null, // open counterparty unknown at creation time
2601
- logger: this.#logger,
2602
- });
2603
- let node;
2604
- try {
2605
- node = await this.#factory.createNode({ sessionId, connectionGater: gater, nodeType: "standing_receiver" });
2606
- await node.start();
2607
- }
2608
- catch (err) {
2609
- this.#logger.error("session.node.create.failed", {
2610
- sessionId,
2611
- agentName: `${STANDING_RECEIVER_AGENT_NAME}:${agentName}`,
2612
- error: err instanceof Error ? err.message : String(err),
2613
- correlationId,
2614
- });
2615
- return; // not ready — callers check getStandingReceiverReady / retry via ensure on demand
2616
- }
2617
- // M2: gracefulShutdown may have begun while this node was starting (ensure runs un-awaited).
2618
- // Don't install an orphan bound to a TCP port — stop it and bail.
2619
- if (this.#shuttingDown) {
2620
- try {
2621
- await node.stop();
2671
+ let lastError = "";
2672
+ for (let attempt = 0; attempt <= this.#srRetryDelaysMs.length; attempt++) {
2673
+ if (attempt > 0) {
2674
+ await new Promise((r) => setTimeout(r, this.#srRetryDelaysMs[attempt - 1]));
2622
2675
  }
2623
- catch { /* best-effort */ }
2624
- return;
2625
- }
2626
- // L1: the agent may have gone offline (cello_stop_agent → removeStandingReceiverForAgent)
2627
- // while this ensure was parked on start(). Removal found no map entry to delete, so the
2628
- // tombstone is how we learn of it — tear the fresh node down rather than install an SR for
2629
- // an offline agent.
2630
- if (this.#standingReceiverRemoving.has(agentName)) {
2631
- this.#standingReceiverRemoving.delete(agentName);
2632
- try {
2633
- await node.stop();
2676
+ if (this.#shuttingDown)
2677
+ return;
2678
+ // L1 tombstone: the agent went offline while we were creating / backing off.
2679
+ if (this.#standingReceiverRemoving.has(agentName)) {
2680
+ this.#standingReceiverRemoving.delete(agentName);
2681
+ return;
2634
2682
  }
2635
- catch { /* best-effort */ }
2636
- return;
2683
+ const result = await this.#tryCreateStandingReceiver(agentName, correlationId);
2684
+ if (result.outcome !== "failed")
2685
+ return; // installed, or cleanly aborted (shutdown/offline)
2686
+ lastError = result.error;
2637
2687
  }
2638
- // CELLO-M7-TRANSPORT-001: wrap in a NodeAutoNatService so its dialability drives session-
2639
- // address advertisement and the transport.autonat.* events fire.
2640
- const autoNat = new NodeAutoNatService({
2641
- node,
2642
- logger: this.#logger,
2643
- nodeType: "standing_receiver",
2644
- probers: this.#autoNatProbers(),
2688
+ // M8B F14 (fix 4): an agent that WANTS a receiver has none after every attempt — the
2689
+ // deaf-agent state. Fail LOUD so it is alarm-visible instead of a quiet degradation.
2690
+ this.#logger.error("session.standing_receiver.dead", {
2691
+ agentName,
2692
+ reason: lastError,
2693
+ attempts: this.#srRetryDelaysMs.length + 1,
2694
+ correlationId,
2645
2695
  });
2646
- autoNat.emitInitialResult();
2647
- this.#standingReceivers.set(agentName, { node, gater, autoNat });
2648
- this.#logger.info("session.node.created", {
2696
+ }
2697
+ finally {
2698
+ this.#standingReceiverCreating.delete(agentName);
2699
+ }
2700
+ }
2701
+ /** One standing-receiver create attempt (extracted for the M8B F14 retry loop). */
2702
+ async #tryCreateStandingReceiver(agentName, correlationId) {
2703
+ const sessionId = `standing_receiver_${randomUUID()}`;
2704
+ const gater = new SessionConnectionGater({
2705
+ sessionId,
2706
+ allowedPeerId: null, // open — counterparty unknown at creation time
2707
+ logger: this.#logger,
2708
+ });
2709
+ let node;
2710
+ try {
2711
+ node = await this.#factory.createNode({ sessionId, connectionGater: gater, nodeType: "standing_receiver" });
2712
+ await node.start();
2713
+ }
2714
+ catch (err) {
2715
+ const error = err instanceof Error ? err.message : String(err);
2716
+ this.#logger.error("session.node.create.failed", {
2649
2717
  sessionId,
2650
2718
  agentName: `${STANDING_RECEIVER_AGENT_NAME}:${agentName}`,
2651
- sessionPeerId: node.getPeerId(),
2719
+ error,
2652
2720
  correlationId,
2653
2721
  });
2722
+ return { outcome: "failed", error };
2654
2723
  }
2655
- finally {
2656
- this.#standingReceiverCreating.delete(agentName);
2724
+ // M2: gracefulShutdown may have begun while this node was starting (ensure runs un-awaited).
2725
+ // Don't install an orphan bound to a TCP port — stop it and bail.
2726
+ if (this.#shuttingDown) {
2727
+ try {
2728
+ await node.stop();
2729
+ }
2730
+ catch { /* best-effort */ }
2731
+ return { outcome: "aborted" };
2732
+ }
2733
+ // L1: the agent may have gone offline (cello_stop_agent → removeStandingReceiverForAgent)
2734
+ // while this ensure was parked on start(). Removal found no map entry to delete, so the
2735
+ // tombstone is how we learn of it — tear the fresh node down rather than install an SR for
2736
+ // an offline agent.
2737
+ if (this.#standingReceiverRemoving.has(agentName)) {
2738
+ this.#standingReceiverRemoving.delete(agentName);
2739
+ try {
2740
+ await node.stop();
2741
+ }
2742
+ catch { /* best-effort */ }
2743
+ return { outcome: "aborted" };
2657
2744
  }
2745
+ // CELLO-M7-TRANSPORT-001: wrap in a NodeAutoNatService so its dialability drives session-
2746
+ // address advertisement and the transport.autonat.* events fire.
2747
+ const autoNat = new NodeAutoNatService({
2748
+ node,
2749
+ logger: this.#logger,
2750
+ nodeType: "standing_receiver",
2751
+ probers: this.#autoNatProbers(),
2752
+ });
2753
+ autoNat.emitInitialResult();
2754
+ this.#standingReceivers.set(agentName, { node, gater, autoNat });
2755
+ this.#logger.info("session.node.created", {
2756
+ sessionId,
2757
+ agentName: `${STANDING_RECEIVER_AGENT_NAME}:${agentName}`,
2758
+ sessionPeerId: node.getPeerId(),
2759
+ correlationId,
2760
+ });
2761
+ return { outcome: "installed" };
2658
2762
  }
2659
2763
  /**
2660
2764
  * DOD-LOOP-1: public hook for the composition root to create an agent's standing receiver when
2661
2765
  * the agent comes online (cello_start_agent), and to tear it down when it goes offline.
2766
+ * M8B F14: also called from the inbound accept path (ensure on demand). Marks the agent as
2767
+ * WANTING a receiver, which arms the teardown re-arm in destroySessionNode/retireSessionNode.
2662
2768
  */
2663
2769
  async ensureStandingReceiverForAgent(agentName) {
2770
+ this.#agentsWantingReceiver.add(agentName);
2664
2771
  await this.#ensureStandingReceiver(agentName);
2665
2772
  }
2666
2773
  async removeStandingReceiverForAgent(agentName) {
2774
+ // M8B F14: the agent no longer wants a receiver — disarm the teardown re-arm.
2775
+ this.#agentsWantingReceiver.delete(agentName);
2667
2776
  const sr = this.#standingReceivers.get(agentName);
2668
2777
  if (!sr) {
2669
2778
  // L1: an #ensureStandingReceiver for this agent may be in flight (parked on start(), so no