@cello-protocol/daemon 0.0.182 → 0.0.183

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/agent-settings-keys.d.ts.map +1 -1
  2. package/dist/agent-settings-keys.js +18 -0
  3. package/dist/agent-settings-keys.js.map +1 -1
  4. package/dist/consortium-bootstrap.d.ts.map +1 -1
  5. package/dist/consortium-bootstrap.js +117 -2
  6. package/dist/consortium-bootstrap.js.map +1 -1
  7. package/dist/content-encryption-status.d.ts +97 -0
  8. package/dist/content-encryption-status.d.ts.map +1 -0
  9. package/dist/content-encryption-status.js +122 -0
  10. package/dist/content-encryption-status.js.map +1 -0
  11. package/dist/content-park-client.d.ts +10 -0
  12. package/dist/content-park-client.d.ts.map +1 -1
  13. package/dist/content-park-client.js +84 -3
  14. package/dist/content-park-client.js.map +1 -1
  15. package/dist/content-park.d.ts.map +1 -1
  16. package/dist/content-park.js +184 -13
  17. package/dist/content-park.js.map +1 -1
  18. package/dist/daemon.d.ts.map +1 -1
  19. package/dist/daemon.js +306 -23
  20. package/dist/daemon.js.map +1 -1
  21. package/dist/document-handlers.d.ts.map +1 -1
  22. package/dist/document-handlers.js +119 -0
  23. package/dist/document-handlers.js.map +1 -1
  24. package/dist/document-layer.d.ts +0 -2
  25. package/dist/document-layer.d.ts.map +1 -1
  26. package/dist/document-layer.js.map +1 -1
  27. package/dist/initiate-session-handler.d.ts.map +1 -1
  28. package/dist/initiate-session-handler.js +34 -3
  29. package/dist/initiate-session-handler.js.map +1 -1
  30. package/dist/manifest-deps.d.ts +0 -11
  31. package/dist/manifest-deps.d.ts.map +1 -1
  32. package/dist/manifest-deps.js +28 -2
  33. package/dist/manifest-deps.js.map +1 -1
  34. package/dist/manifest-validity.d.ts +2 -0
  35. package/dist/manifest-validity.d.ts.map +1 -1
  36. package/dist/manifest-validity.js +1 -1
  37. package/dist/manifest-validity.js.map +1 -1
  38. package/dist/outbound-sessions.d.ts.map +1 -1
  39. package/dist/outbound-sessions.js +19 -0
  40. package/dist/outbound-sessions.js.map +1 -1
  41. package/dist/park-envelope.d.ts +23 -0
  42. package/dist/park-envelope.d.ts.map +1 -1
  43. package/dist/park-envelope.js +76 -0
  44. package/dist/park-envelope.js.map +1 -1
  45. package/dist/register-handler.d.ts.map +1 -1
  46. package/dist/register-handler.js +76 -0
  47. package/dist/register-handler.js.map +1 -1
  48. package/dist/relay-only.d.ts +133 -0
  49. package/dist/relay-only.d.ts.map +1 -0
  50. package/dist/relay-only.js +183 -0
  51. package/dist/relay-only.js.map +1 -0
  52. package/dist/retry-queue.d.ts +26 -1
  53. package/dist/retry-queue.d.ts.map +1 -1
  54. package/dist/retry-queue.js +18 -1
  55. package/dist/retry-queue.js.map +1 -1
  56. package/dist/session-ceremony.d.ts +6 -0
  57. package/dist/session-ceremony.d.ts.map +1 -1
  58. package/dist/session-ceremony.js +26 -0
  59. package/dist/session-ceremony.js.map +1 -1
  60. package/dist/session-content-handlers.d.ts +12 -0
  61. package/dist/session-content-handlers.d.ts.map +1 -1
  62. package/dist/session-content-handlers.js +39 -4
  63. package/dist/session-content-handlers.js.map +1 -1
  64. package/dist/session-node-manager.d.ts +247 -4
  65. package/dist/session-node-manager.d.ts.map +1 -1
  66. package/dist/session-node-manager.js +3088 -304
  67. package/dist/session-node-manager.js.map +1 -1
  68. package/dist/session-read-handlers.d.ts.map +1 -1
  69. package/dist/session-read-handlers.js +16 -1
  70. package/dist/session-read-handlers.js.map +1 -1
  71. package/dist/session-relay-client.d.ts +116 -0
  72. package/dist/session-relay-client.d.ts.map +1 -1
  73. package/dist/session-relay-client.js +395 -6
  74. package/dist/session-relay-client.js.map +1 -1
  75. package/dist/session-salt-agreement.d.ts +58 -4
  76. package/dist/session-salt-agreement.d.ts.map +1 -1
  77. package/dist/session-salt-agreement.js +110 -3
  78. package/dist/session-salt-agreement.js.map +1 -1
  79. package/dist/signaling-connect.d.ts +18 -1
  80. package/dist/signaling-connect.d.ts.map +1 -1
  81. package/dist/signaling-connect.js +164 -1
  82. package/dist/signaling-connect.js.map +1 -1
  83. package/dist/types.d.ts +21 -0
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/types.js.map +1 -1
  86. package/dist/wire-content-hash.d.ts +15 -3
  87. package/dist/wire-content-hash.d.ts.map +1 -1
  88. package/dist/wire-content-hash.js +15 -3
  89. package/dist/wire-content-hash.js.map +1 -1
  90. package/package.json +5 -5
@@ -80,6 +80,17 @@ export declare const PARK_ENVELOPE_REASONS: {
80
80
  /** The entry names a content-hash algorithm this build cannot itself reproduce. */
81
81
  readonly ALG_UNREADABLE: "park_envelope_alg_unreadable";
82
82
  };
83
+ /**
84
+ * The relay's park-refusal codes.
85
+ *
86
+ * ⚠️ RE-EXPORTED FROM `@cello-protocol/protocol-types`, NOT declared here. They used to be a private
87
+ * copy that happened to agree with the relay's strings — verified by hand once, which is not a
88
+ * guard. A rename on the relay side would have left this copy silently unmatched, falling through to
89
+ * the generic "the relay link is down" wording: the exact defect this family of work removed,
90
+ * reintroduced by a change nobody would think of as a protocol change.
91
+ */
92
+ import { RELAY_PARK_REFUSALS } from "@cello-protocol/protocol-types";
93
+ export { RELAY_PARK_REFUSALS };
83
94
  export type ParkEnvelopeReason = (typeof PARK_ENVELOPE_REASONS)[keyof typeof PARK_ENVELOPE_REASONS];
84
95
  /**
85
96
  * A REFUSAL TO SEAL, carrying a code the caller can branch on — `DOD-M15-SEALWIRE-1` B2b-2
@@ -161,4 +172,16 @@ export declare function authenticateParkedEntry(args: {
161
172
  contentHash: Uint8Array;
162
173
  counterpartyPubkeyHex: string | undefined;
163
174
  }): ParkAuthVerdict;
175
+ /**
176
+ * The operator-facing guidance for a refused park hand-off — **a pure function, deliberately.**
177
+ *
178
+ * ⚠️ It was an inline ternary inside `sendContent`, which meant the only way to assert any branch of
179
+ * it was to stand up a two-connection fixture and drive a real send. That is why the branch that was
180
+ * WRONG for a throttling relay survived: nothing cheap could reach it. A guidance string is a
181
+ * decision about what a person does next, and it deserves to be testable on its own.
182
+ *
183
+ * `durable` distinguishes "queued and will retry" from "not queued — it is lost", which is the one
184
+ * distinction that changes whether the reader must act right now.
185
+ */
186
+ export declare function parkRefusalGuidance(cause: string | undefined, durable: boolean, retryAfterMs?: number): string;
164
187
  //# sourceMappingURL=park-envelope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"park-envelope.d.ts","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"AA8BA,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAInF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAW3F;AAED,sGAAsG;AACtG,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAY3C,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,eAAe,GACf,yBAAyB,GACzB,sBAAsB,CAAC;AAE3B,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAEpF;;;GAGG;AACH,eAAO,MAAM,qBAAqB;IAChC,mFAAmF;;CAE3E,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAC;AAEpG;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAMxE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,UAAU,CAAC;IACzB,OAAO,EAAE,UAAU,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,oFAAoF;IACpF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,UAAU,CAyCb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,UAAU,CAAC;IAC5B,WAAW,EAAE,UAAU,CAAC;IACxB,OAAO,EAAE,UAAU,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,iGAAiG;IACjG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,UAAU,CAAC,CAgBtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU,GAAG,YAAY,CAwCtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,YAAY,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,UAAU,CAAC;IAC5B,WAAW,EAAE,UAAU,CAAC;IACxB,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C,GAAG,eAAe,CA8BlB"}
1
+ {"version":3,"file":"park-envelope.d.ts","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"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"}
@@ -107,6 +107,17 @@ export const PARK_ENVELOPE_REASONS = {
107
107
  /** The entry names a content-hash algorithm this build cannot itself reproduce. */
108
108
  ALG_UNREADABLE: "park_envelope_alg_unreadable",
109
109
  };
110
+ /**
111
+ * The relay's park-refusal codes.
112
+ *
113
+ * ⚠️ RE-EXPORTED FROM `@cello-protocol/protocol-types`, NOT declared here. They used to be a private
114
+ * copy that happened to agree with the relay's strings — verified by hand once, which is not a
115
+ * guard. A rename on the relay side would have left this copy silently unmatched, falling through to
116
+ * the generic "the relay link is down" wording: the exact defect this family of work removed,
117
+ * reintroduced by a change nobody would think of as a protocol change.
118
+ */
119
+ import { RELAY_PARK_REFUSALS } from "@cello-protocol/protocol-types";
120
+ export { RELAY_PARK_REFUSALS };
110
121
  /**
111
122
  * A REFUSAL TO SEAL, carrying a code the caller can branch on — `DOD-M15-SEALWIRE-1` B2b-2
112
123
  * constraint 6, inherited from B2a's review.
@@ -285,4 +296,69 @@ export function authenticateParkedEntry(args) {
285
296
  }
286
297
  return { ok: true };
287
298
  }
299
+ /**
300
+ * The operator-facing guidance for a refused park hand-off — **a pure function, deliberately.**
301
+ *
302
+ * ⚠️ It was an inline ternary inside `sendContent`, which meant the only way to assert any branch of
303
+ * it was to stand up a two-connection fixture and drive a real send. That is why the branch that was
304
+ * WRONG for a throttling relay survived: nothing cheap could reach it. A guidance string is a
305
+ * decision about what a person does next, and it deserves to be testable on its own.
306
+ *
307
+ * `durable` distinguishes "queued and will retry" from "not queued — it is lost", which is the one
308
+ * distinction that changes whether the reader must act right now.
309
+ */
310
+ export function parkRefusalGuidance(cause, durable, retryAfterMs) {
311
+ if (cause === PARK_ENVELOPE_REASONS.ALG_UNREADABLE) {
312
+ return ("This message names a content-hash algorithm your build cannot produce, so it could not be " +
313
+ "sealed for hand-off. The relay is NOT involved and this will not clear on its own — the " +
314
+ "message is safely stored but every retry fails the same way. Upgrade to a build that knows " +
315
+ "the algorithm, or start a new session with this counterparty. Re-sending on this build " +
316
+ "changes nothing.");
317
+ }
318
+ /**
319
+ * ⚠️ DIAGNOSIS AND ACTION ARE COMPOSED, NOT WRITTEN TOGETHER — and this shape is the fix for a
320
+ * defect review found in the first version.
321
+ *
322
+ * That version returned a complete paragraph per cause and **never consulted `durable`**, so all
323
+ * three new branches ended "The message is queued and re-sent automatically. Do not re-send it."
324
+ * `durable` is OBSERVED, not assumed: it is false when the durable enqueue was refused as a
325
+ * duplicate, or when the retry hook is unwired. In that case the daemon logs at ERROR that the
326
+ * content is *not* separately retained while the operator was simultaneously told it was queued
327
+ * and instructed not to re-send. **Nothing held the message.** That is precisely the lie this
328
+ * family of work exists to kill, reintroduced one layer up.
329
+ *
330
+ * Splitting them makes the mistake unavailable: the action half is produced in exactly one place
331
+ * and cannot be reached without reading the flag.
332
+ */
333
+ const diagnosis = cause === RELAY_PARK_REFUSALS.RATE_LIMITED
334
+ ? `The relay is healthy and deliberately rate-limiting this agent's hand-offs, so it refused this one. NOTHING IS WRONG with the link or the counterparty, and the limit clears on its own${describeRetryWindow(retryAfterMs)}.`
335
+ : cause === RELAY_PARK_REFUSALS.RECIPIENT_FULL
336
+ ? "The relay is holding as much undelivered content for THIS counterparty as it will, so it refused the hand-off. That is about their mailbox, not your connection, and another relay would refuse it too. It clears when they come online and collect it, or when older entries expire."
337
+ : cause === RELAY_PARK_REFUSALS.STORE_FULL
338
+ ? "The relay's parked-content store is full, so it refused the hand-off. The link is fine. If this persists the relay operator needs to know — it means the store is under sustained pressure."
339
+ : null;
340
+ if (diagnosis !== null) {
341
+ return durable
342
+ ? `${diagnosis} The message is queued and re-sent automatically. Do not re-send it: an identical re-send is not separately queued.`
343
+ : `${diagnosis} ⚠️ BUT THIS MESSAGE WAS NOT QUEUED — it is lost. Send it again.`;
344
+ }
345
+ return durable
346
+ ? "Direct delivery failed and the relay refused the hand-off, so the message is queued and will be re-sent automatically when the relay link is back. Do not re-send it: an identical re-send is not separately queued."
347
+ : "Direct delivery failed and the message could NOT be queued for retry — it is lost. Send it again.";
348
+ }
349
+ /**
350
+ * Render the relay's own retry delay, or say nothing at all.
351
+ *
352
+ * ⚠️ SAYS NOTHING WHEN THE RELAY DID NOT SAY — review MEDIUM-6. The first version of the guidance
353
+ * asserted the limit clears *"in about a minute"*, which is a hardcoded guess about the relay's
354
+ * CONFIGURABLE window: a relay run at ten minutes makes that a wrong promise, and a wrong number is
355
+ * worse than no number because the reader plans around it. When the relay tells us, we quote it;
356
+ * when it does not, the sentence simply ends.
357
+ */
358
+ function describeRetryWindow(retryAfterMs) {
359
+ if (retryAfterMs === undefined || !Number.isFinite(retryAfterMs) || retryAfterMs <= 0)
360
+ return "";
361
+ const seconds = Math.ceil(retryAfterMs / 1000);
362
+ return seconds < 90 ? ` in about ${String(seconds)} seconds` : ` in about ${String(Math.ceil(seconds / 60))} minutes`;
363
+ }
288
364
  //# sourceMappingURL=park-envelope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"park-envelope.js","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"park-envelope.js","sourceRoot":"","sources":["../src/park-envelope.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"register-handler.d.ts","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAMnE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,CAAC;IACjE,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,KAAK;QAAE,SAAS,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;IACxJ,yBAAyB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,wBAAwB,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACrG,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAChF,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CA+KvE"}
1
+ {"version":3,"file":"register-handler.d.ts","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOnE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,CAAC;IACjE,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,KAAK;QAAE,SAAS,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;IACxJ,yBAAyB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1F,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACrG,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,wBAAwB,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACrG,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAChF,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;CACtC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CA4PvE"}
@@ -18,6 +18,7 @@ import { manifestNodesToEndpoints } from "./directory-bootstrap.js";
18
18
  import { DaemonRegistrationContext } from "./registration-context.js";
19
19
  import { RegistrationManager } from "./registration-manager.js";
20
20
  import { validatorNodes } from "@cello-protocol/protocol-types";
21
+ import { classifyManifestValidity } from "./manifest-validity.js";
21
22
  export function registerRegisterHandler(deps) {
22
23
  const { handlers, logger, keyProviders, getPersistence, getAgentSignaling, waitForSignalingConnected, dropAgentSignaling, startAgentInternal, directoryEndpointResolver, loadedAgents, registrationGuidance, manifestProvider, } = deps;
23
24
  // Single-flight guard (M1): the directory's registration reply frames (dkg_ready /
@@ -107,6 +108,81 @@ export function registerRegisterHandler(deps) {
107
108
  // load-bearing: an empty roster (consortium configured but unreachable) must REFUSE in
108
109
  // registration-manager, NOT downgrade to single-node (code-reviewer B1 / fallback-finder).
109
110
  const currentManifest = manifestProvider?.getCurrentManifest();
111
+ /**
112
+ * DOD-M15-EXPIRY-CONSUMER-POLICY-1 — this consumer PROCEEDS on a lapsed manifest, and that is
113
+ * now a decision rather than an omission. Written down because the split looked accidental:
114
+ * `signal-submission` REFUSES on expiry while this, the higher-stakes consumer, did not even
115
+ * look.
116
+ *
117
+ * **Why it proceeds.** Startup already fails closed on an expired manifest, so a lapsed one
118
+ * exists only inside a LONG-RUNNING daemon. Refusing here sends the operator to the one remedy
119
+ * `signal-submission`'s own guidance warns against — *"a restart without a REPLACEMENT does not
120
+ * reload anything: the daemon refuses to come back and every agent goes offline."* So refusing
121
+ * would brick a running operator to close a window that needs a roster CHANGE to be
122
+ * exploitable at all: the risk is dealing a share to a validator removed since the manifest
123
+ * lapsed, not expiry itself.
124
+ *
125
+ * **Why `signal-submission` is different, and why "make them consistent" would be wrong.** It
126
+ * uses the manifest's PORTAL INTAKE KEY, and a rotated key means a message the portal cannot
127
+ * open and cannot attribute — unattributable poison, its own word, with no error anywhere.
128
+ * Different field, different failure, different answer.
129
+ *
130
+ * **What was actually missing was not the gate — it was the RECORD.** `cello_status` already
131
+ * reports an expired manifest, so the STATE was visible; nothing said a FROST share had been
132
+ * dealt against one. That is what this event is.
133
+ */
134
+ const manifestValidity = classifyManifestValidity(currentManifest ?? null, Date.now());
135
+ /**
136
+ * ⚠️ NOT ONLY `expired` — review F7. `unreadable_window` (a window field that does not parse)
137
+ * and `not_yet_valid` (a wrong clock, or a manifest rotated in early) both reached the DKG
138
+ * with no event at all. `unreadable_window` matters more than it looks: since the startup gate
139
+ * was hardened it cannot start a daemon, but a manifest POLLED IN after startup can still put
140
+ * a running daemon into it.
141
+ */
142
+ const lapsed = manifestValidity.state === "expired"
143
+ || manifestValidity.state === "unreadable_window"
144
+ || manifestValidity.state === "not_yet_valid";
145
+ if (lapsed) {
146
+ logger.warn("registration.manifest.lapsed", {
147
+ agent: name,
148
+ state: manifestValidity.state,
149
+ window: manifestValidity.state === "expired" ? manifestValidity.expires : manifestValidity.notBefore,
150
+ validators: currentManifest ? validatorNodes(currentManifest.nodes).length : 0,
151
+ /**
152
+ * ⚠️ THIS USED TO SAY "a share MAY BE DEALT to a node that is no longer authorized", and
153
+ * that over-claimed in the very case it named. Review traced the path: a validator removed
154
+ * since the lapse is either unreachable — dropped at the dial layer by the peerId
155
+ * cross-check against the signed manifest — or reachable but absent from the DIRECTORY's
156
+ * current manifest, in which case the roster/participants counts disagree and registration
157
+ * REFUSES with `dkg_below_threshold`. **Dealing a share to a de-authorized node is not
158
+ * reachable through this path.** The event was about to be emitted alongside a FAILED
159
+ * registration while telling the operator a share may have gone somewhere.
160
+ *
161
+ * What it says now is what is actually true, and it is still worth saying: this event is
162
+ * emitted immediately before that refusal, so it is the line that explains an otherwise
163
+ * bare `dkg_below_threshold` — which names an exit point and not a cause.
164
+ */
165
+ /**
166
+ * ⚠️ ONE CAUSE OF A MULTI-CAUSE EXIT — pass 2, and the previous wording inverted the
167
+ * redundancy invariant in prose. `dkg_below_threshold` comes from a single comparison
168
+ * (`roster.length !== participants`) whose own comment names TWO causes: a node we reported
169
+ * is now unreachable, OR a manifest version skew. **An unreachable node is the routine
170
+ * one** — under the sovereign-node design a node being down is the expected steady state,
171
+ * not the exception. Saying "THIS is the cause" and "replace the trust anchor rather than
172
+ * retrying" told the operator to replace a threshold-signed anchor in the case where the
173
+ * correct move is to retry.
174
+ */
175
+ impact: "the consortium roster this registration works from came from a manifest whose validity " +
176
+ "window is not currently open. This is ONE possible cause of a subsequent " +
177
+ "dkg_below_threshold — a directory node being momentarily unreachable is the more common " +
178
+ "one, and is expected rather than exceptional.",
179
+ guidance: "Registration was NOT blocked here — blocking it would strand a running daemon, since a " +
180
+ "restart without a replacement manifest does not come back. If it then fails with " +
181
+ "dkg_below_threshold: RETRY FIRST, because an unreachable node is the usual cause. " +
182
+ "Replace the trust anchor only if cello_status shows the manifest window is the " +
183
+ "discrepancy.",
184
+ });
185
+ }
110
186
  const consortiumRoster = currentManifest
111
187
  ? await manifestNodesToEndpoints(validatorNodes(currentManifest.nodes), { logger })
112
188
  : null;
@@ -1 +1 @@
1
- {"version":3,"file":"register-handler.js","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register-handler.js","sourceRoot":"","sources":["../src/register-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * CELLO Daemon — relay-only routing (`DOD-M15-RELAYONLY-1`).
3
+ *
4
+ * The feature half of the IP disclosure. A direct session reveals the operator's IP permanently;
5
+ * relay routing is the mitigation, and until now it was a footnote in an architecture document
6
+ * rather than something an operator could switch on.
7
+ *
8
+ * ─── ⚠️ WHY THIS IS NOT A `transport_mode` SETTING ─────────────────────────────────────────────
9
+ *
10
+ * `transport_mode` DOES NOT CONTROL WHETHER A DIRECT CONNECTION HAPPENS, and a setting that wrote it
11
+ * would be a privacy control that does not protect privacy:
12
+ *
13
+ * - The directory already defaults the label to relay (`requestedTransportMode ?? "relay"`), so in
14
+ * the ordinary case the label ALREADY reads "relay".
15
+ * - And the client dials directly anyway — the gate is `counterparty_session_addrs.length > 0`,
16
+ * *"regardless of the transport_mode LABEL"*, in `initiate-session-handler.ts`'s own words.
17
+ *
18
+ * So the IP is exposed today on a path whose label already claims otherwise, and an operator who set
19
+ * a label-only flag would be told they were protected while they were not.
20
+ *
21
+ * ─── The two halves, and why the second is the one that makes it a control ────────────────────
22
+ *
23
+ * A direct connection leaks the IP in BOTH directions:
24
+ *
25
+ * 1. **We dial only their CIRCUIT** — `dialableAddrs`. Dialling their direct address hands them
26
+ * ours; dialling the circuit terminates at the relay and reveals nothing.
27
+ * 2. **We publish only our own CIRCUIT** — `publishableEndpoint`. The only route they hold points
28
+ * at the relay, which protects the operator **even against a counterparty who ignores the flag**.
29
+ *
30
+ * The second is load-bearing: *a control that depends on the other side honouring it is not a
31
+ * control.* The first alone would leave us reachable by anyone who kept our address.
32
+ *
33
+ * ⚠️ **AND NEITHER HALF IS SUFFICIENT WHILE libp2p CAN SPEAK FOR US.** These functions filter what
34
+ * the DIRECTORY is told. `identify` hands a peer our listen addresses on the first relayed
35
+ * connection, and `dcutr` actively hole-punches a relayed connection into a direct one — the inbound
36
+ * side starts that upgrade, and a relay-only responder IS the inbound side. Both bypass everything
37
+ * here, peer-to-peer. `createNode`'s `holePunch: { enabled: false }` closes the second; the announce
38
+ * filter closes the first. **Without those, this file filters the paperwork and leaves the wire
39
+ * open** — see `DOD-M15-RELAYONLY-1`.
40
+ *
41
+ * `publishableEndpoint` is applied INSIDE `getStandingReceiverInfo` — the single method both publish
42
+ * paths draw from — rather than at its call sites. Suppressing at call sites would be a hand-kept
43
+ * list, and a fourth publish path added later would leak while every test stayed green. At the choke
44
+ * point a new caller inherits the protection instead of having to be told about it.
45
+ */
46
+ /** The per-agent settings key. Lower-snake, dotted namespace, per `agent-settings-keys.ts`. */
47
+ export declare const RELAY_ONLY_KEY = "transport.relay_only";
48
+ /**
49
+ * Is relay-only routing ON for this agent?
50
+ *
51
+ * ⚠️ THE FAILURE DIRECTION IS CHOSEN, not incidental. **Only the exact string `"true"` is ON.**
52
+ * Unset reads OFF because the daemon must run correctly on defaults alone; a corrupt or unparseable
53
+ * value also reads OFF, because reading a value nobody validated as ON would silently break every
54
+ * ordinary direct session.
55
+ *
56
+ * That leaves one hazard — a typo'd value that the operator believes turned the control on — and it
57
+ * is closed at the WRITE boundary instead: `validateSettingValue` refuses anything but `"true"` and
58
+ * `"false"`, loudly, so a mistyped value can never be stored to be misread here.
59
+ */
60
+ export declare function isRelayOnly(getSetting: (key: string) => string | null): boolean;
61
+ /**
62
+ * The setting's state when the read itself may fail — `"on" | "off" | "unknown"`.
63
+ *
64
+ * ⚠️ **"THE DATABASE IS GONE" IS NOT A VALUE, AND TREATING IT AS ONE FAILS TOWARD DISCLOSURE.**
65
+ * `getSetting` returns `null` both for *unset* and for *no database*, and `isRelayOnly` reads both
66
+ * as OFF. Unset-means-off is right; **db-gone-means-off is not** — the standing receiver outlives
67
+ * the database during shutdown, so an offer arriving in that window would publish the operator's
68
+ * real addresses with relay-only switched on.
69
+ *
70
+ * A read that THROWS is also `"unknown"` rather than an escaping exception: this sits on a ceremony
71
+ * path with no catch, where a throw becomes an unhandled rejection and the offer vanishes with no
72
+ * local log — the initiator then sees `counterparty_did_not_accept` and blames its own subsystem.
73
+ *
74
+ * The caller decides what `"unknown"` costs. For publishing, it must cost a refusal, never a guess.
75
+ */
76
+ export declare function relayOnlyState(getSetting: (key: string) => string | null, readable: boolean): "on" | "off" | "unknown";
77
+ /** A session-transport endpoint as published to a counterparty. */
78
+ export interface PublishableEndpoint {
79
+ peerId: string;
80
+ addrs: string[];
81
+ }
82
+ /**
83
+ * A relay-CIRCUIT multiaddr — the address that discloses nothing about the operator.
84
+ *
85
+ * ⚠️ THIS IS THE DISTINCTION THE WHOLE UNIT TURNS ON, and getting it wrong the first time took the
86
+ * operator OFF THE NETWORK rather than making them private. A `/p2p-circuit` address names the
87
+ * **RELAY's** address and our peer id. It terminates at the relay. Publishing one tells a
88
+ * counterparty how to reach us *through* the relay and tells them nothing about where we are;
89
+ * dialing one reveals us to the relay we already chose, not to them.
90
+ *
91
+ * So relay-only is not "no addresses". It is "circuit addresses only".
92
+ */
93
+ export declare function isCircuitAddr(addr: string): boolean;
94
+ /**
95
+ * The endpoint as it may leave this machine.
96
+ *
97
+ * ⚠️ **AN EMPTY ADDRESS ARRAY IS NOT A PRIVATE FRAME, IT IS A MALFORMED ONE.** The first build of
98
+ * this published `addrs: []` and the directory refuses exactly that on both sides — a
99
+ * `session_request` whose `initiator_session_addrs` is empty is rejected outright, and a
100
+ * `session_offer_accept` is only folded in `if (counterparty_session_addrs.length > 0)`, **with no
101
+ * `else`**, so the accept was silently dropped and the offer waiter never resolved. The operator
102
+ * switched on a privacy control and was told their counterparty was offline.
103
+ *
104
+ * So we publish the **circuit-only subset**: enough for the directory to build a real assignment and
105
+ * for the counterparty to reach us over the relay, and nothing that points at the operator.
106
+ *
107
+ * A genuinely empty result is meaningful and is NOT silently published — see `relayOnlyReachable`.
108
+ * A null endpoint stays null: "no standing receiver" and "a receiver at no address" are different
109
+ * facts, and collapsing them would let a caller advertise an endpoint that does not exist.
110
+ */
111
+ export declare function publishableEndpoint<T extends PublishableEndpoint>(endpoint: T | null, relayOnly: boolean): T | PublishableEndpoint | null;
112
+ /**
113
+ * Can a relay-only agent actually be reached with what it is about to publish?
114
+ *
115
+ * FALSE means it holds **no relay reservation yet**, so the circuit-only subset is empty. That must
116
+ * become a LOUD LOCAL REFUSAL rather than an empty publish: an empty publish is refused by the
117
+ * directory as malformed and surfaces to the operator as "the counterparty is offline", which is a
118
+ * lie about someone else's state caused by a setting on this machine.
119
+ */
120
+ export declare function relayOnlyReachable(endpoint: PublishableEndpoint | null, relayOnly: boolean): boolean;
121
+ /**
122
+ * Which of the counterparty's advertised addresses may we dial?
123
+ *
124
+ * ⚠️ Returns the FILTERED LIST, not a boolean, because "relay-only" does not mean "do not connect" —
125
+ * it means "connect only over the circuit". The first build refused every address including the
126
+ * `/p2p-circuit` one, which is the relay route this setting exists to force everything onto, so it
127
+ * dropped every session onto the store-and-forward backstop.
128
+ *
129
+ * The counterparty may not be relay-only themselves, so they will still advertise direct addresses:
130
+ * those are dropped, because dialing one hands them our IP with our own setting switched on.
131
+ */
132
+ export declare function dialableAddrs(addrs: readonly string[], relayOnly: boolean): string[];
133
+ //# sourceMappingURL=relay-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-only.d.ts","sourceRoot":"","sources":["../src/relay-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,+FAA+F;AAC/F,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAE/E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAC1C,QAAQ,EAAE,OAAO,GAChB,IAAI,GAAG,KAAK,GAAG,SAAS,CAO1B;AAED,mEAAmE;AACnE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA4BnD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,EAC/D,QAAQ,EAAE,CAAC,GAAG,IAAI,EAClB,SAAS,EAAE,OAAO,GACjB,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAIhC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAIpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,CAGpF"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * CELLO Daemon — relay-only routing (`DOD-M15-RELAYONLY-1`).
3
+ *
4
+ * The feature half of the IP disclosure. A direct session reveals the operator's IP permanently;
5
+ * relay routing is the mitigation, and until now it was a footnote in an architecture document
6
+ * rather than something an operator could switch on.
7
+ *
8
+ * ─── ⚠️ WHY THIS IS NOT A `transport_mode` SETTING ─────────────────────────────────────────────
9
+ *
10
+ * `transport_mode` DOES NOT CONTROL WHETHER A DIRECT CONNECTION HAPPENS, and a setting that wrote it
11
+ * would be a privacy control that does not protect privacy:
12
+ *
13
+ * - The directory already defaults the label to relay (`requestedTransportMode ?? "relay"`), so in
14
+ * the ordinary case the label ALREADY reads "relay".
15
+ * - And the client dials directly anyway — the gate is `counterparty_session_addrs.length > 0`,
16
+ * *"regardless of the transport_mode LABEL"*, in `initiate-session-handler.ts`'s own words.
17
+ *
18
+ * So the IP is exposed today on a path whose label already claims otherwise, and an operator who set
19
+ * a label-only flag would be told they were protected while they were not.
20
+ *
21
+ * ─── The two halves, and why the second is the one that makes it a control ────────────────────
22
+ *
23
+ * A direct connection leaks the IP in BOTH directions:
24
+ *
25
+ * 1. **We dial only their CIRCUIT** — `dialableAddrs`. Dialling their direct address hands them
26
+ * ours; dialling the circuit terminates at the relay and reveals nothing.
27
+ * 2. **We publish only our own CIRCUIT** — `publishableEndpoint`. The only route they hold points
28
+ * at the relay, which protects the operator **even against a counterparty who ignores the flag**.
29
+ *
30
+ * The second is load-bearing: *a control that depends on the other side honouring it is not a
31
+ * control.* The first alone would leave us reachable by anyone who kept our address.
32
+ *
33
+ * ⚠️ **AND NEITHER HALF IS SUFFICIENT WHILE libp2p CAN SPEAK FOR US.** These functions filter what
34
+ * the DIRECTORY is told. `identify` hands a peer our listen addresses on the first relayed
35
+ * connection, and `dcutr` actively hole-punches a relayed connection into a direct one — the inbound
36
+ * side starts that upgrade, and a relay-only responder IS the inbound side. Both bypass everything
37
+ * here, peer-to-peer. `createNode`'s `holePunch: { enabled: false }` closes the second; the announce
38
+ * filter closes the first. **Without those, this file filters the paperwork and leaves the wire
39
+ * open** — see `DOD-M15-RELAYONLY-1`.
40
+ *
41
+ * `publishableEndpoint` is applied INSIDE `getStandingReceiverInfo` — the single method both publish
42
+ * paths draw from — rather than at its call sites. Suppressing at call sites would be a hand-kept
43
+ * list, and a fourth publish path added later would leak while every test stayed green. At the choke
44
+ * point a new caller inherits the protection instead of having to be told about it.
45
+ */
46
+ /** The per-agent settings key. Lower-snake, dotted namespace, per `agent-settings-keys.ts`. */
47
+ export const RELAY_ONLY_KEY = "transport.relay_only";
48
+ /**
49
+ * Is relay-only routing ON for this agent?
50
+ *
51
+ * ⚠️ THE FAILURE DIRECTION IS CHOSEN, not incidental. **Only the exact string `"true"` is ON.**
52
+ * Unset reads OFF because the daemon must run correctly on defaults alone; a corrupt or unparseable
53
+ * value also reads OFF, because reading a value nobody validated as ON would silently break every
54
+ * ordinary direct session.
55
+ *
56
+ * That leaves one hazard — a typo'd value that the operator believes turned the control on — and it
57
+ * is closed at the WRITE boundary instead: `validateSettingValue` refuses anything but `"true"` and
58
+ * `"false"`, loudly, so a mistyped value can never be stored to be misread here.
59
+ */
60
+ export function isRelayOnly(getSetting) {
61
+ return getSetting(RELAY_ONLY_KEY) === "true";
62
+ }
63
+ /**
64
+ * The setting's state when the read itself may fail — `"on" | "off" | "unknown"`.
65
+ *
66
+ * ⚠️ **"THE DATABASE IS GONE" IS NOT A VALUE, AND TREATING IT AS ONE FAILS TOWARD DISCLOSURE.**
67
+ * `getSetting` returns `null` both for *unset* and for *no database*, and `isRelayOnly` reads both
68
+ * as OFF. Unset-means-off is right; **db-gone-means-off is not** — the standing receiver outlives
69
+ * the database during shutdown, so an offer arriving in that window would publish the operator's
70
+ * real addresses with relay-only switched on.
71
+ *
72
+ * A read that THROWS is also `"unknown"` rather than an escaping exception: this sits on a ceremony
73
+ * path with no catch, where a throw becomes an unhandled rejection and the offer vanishes with no
74
+ * local log — the initiator then sees `counterparty_did_not_accept` and blames its own subsystem.
75
+ *
76
+ * The caller decides what `"unknown"` costs. For publishing, it must cost a refusal, never a guess.
77
+ */
78
+ export function relayOnlyState(getSetting, readable) {
79
+ if (!readable)
80
+ return "unknown";
81
+ try {
82
+ return getSetting(RELAY_ONLY_KEY) === "true" ? "on" : "off";
83
+ }
84
+ catch {
85
+ return "unknown";
86
+ }
87
+ }
88
+ /**
89
+ * A relay-CIRCUIT multiaddr — the address that discloses nothing about the operator.
90
+ *
91
+ * ⚠️ THIS IS THE DISTINCTION THE WHOLE UNIT TURNS ON, and getting it wrong the first time took the
92
+ * operator OFF THE NETWORK rather than making them private. A `/p2p-circuit` address names the
93
+ * **RELAY's** address and our peer id. It terminates at the relay. Publishing one tells a
94
+ * counterparty how to reach us *through* the relay and tells them nothing about where we are;
95
+ * dialing one reveals us to the relay we already chose, not to them.
96
+ *
97
+ * So relay-only is not "no addresses". It is "circuit addresses only".
98
+ */
99
+ export function isCircuitAddr(addr) {
100
+ // ⚠️ PARSED, never substring-matched. `addr.includes("/p2p-circuit")` was defeatable by the
101
+ // COUNTERPARTY, who controls these strings — the directory copies them verbatim and the FROST
102
+ // signature attests that the quorum agreed on the assignment, NOT that its contents are circuits.
103
+ //
104
+ // /dns4/p2p-circuit.attacker.example/tcp/443/p2p/12D3KooWTheirs
105
+ //
106
+ // contains the literal text, resolves through the DNS transport, and would have been dialled
107
+ // directly — handing over the operator's IP with relay-only switched ON, while the suppression log
108
+ // reported `suppressed: 0`. A control a peer can defeat by naming a host is precisely what this
109
+ // line rules out.
110
+ //
111
+ // EXACT SEGMENT match on the multiaddr's own `/`-delimited components. `p2p-circuit` is a
112
+ // standalone protocol with no value, so it appears as a whole segment; a hostname that merely
113
+ // CONTAINS the text appears as `p2p-circuit.attacker.example`, which is a different segment and is
114
+ // correctly rejected.
115
+ //
116
+ // Deliberately NOT `multiaddr().protoNames()`, which would be the stricter parse: that lives in
117
+ // `@multiformats/multiaddr`, a dependency `core/daemon` does not have. Reaching for it here would
118
+ // add a package to the daemon to make one boolean stricter, and this client is installed on
119
+ // operators' machines where install weight is a user-facing cost. The exact-segment test defeats
120
+ // the demonstrated bypass with no new dependency.
121
+ //
122
+ // ⚠️ RESIDUAL, stated rather than left implied: this proves the address CLAIMS a circuit hop, not
123
+ // that the circuit runs through a relay we chose. A peer could name a relay we hold no reservation
124
+ // with. Binding the embedded relay peer id to our own reservations is the stronger check and is
125
+ // NOT done here.
126
+ return addr.split("/").includes("p2p-circuit");
127
+ }
128
+ /**
129
+ * The endpoint as it may leave this machine.
130
+ *
131
+ * ⚠️ **AN EMPTY ADDRESS ARRAY IS NOT A PRIVATE FRAME, IT IS A MALFORMED ONE.** The first build of
132
+ * this published `addrs: []` and the directory refuses exactly that on both sides — a
133
+ * `session_request` whose `initiator_session_addrs` is empty is rejected outright, and a
134
+ * `session_offer_accept` is only folded in `if (counterparty_session_addrs.length > 0)`, **with no
135
+ * `else`**, so the accept was silently dropped and the offer waiter never resolved. The operator
136
+ * switched on a privacy control and was told their counterparty was offline.
137
+ *
138
+ * So we publish the **circuit-only subset**: enough for the directory to build a real assignment and
139
+ * for the counterparty to reach us over the relay, and nothing that points at the operator.
140
+ *
141
+ * A genuinely empty result is meaningful and is NOT silently published — see `relayOnlyReachable`.
142
+ * A null endpoint stays null: "no standing receiver" and "a receiver at no address" are different
143
+ * facts, and collapsing them would let a caller advertise an endpoint that does not exist.
144
+ */
145
+ export function publishableEndpoint(endpoint, relayOnly) {
146
+ if (endpoint === null)
147
+ return null;
148
+ if (!relayOnly)
149
+ return endpoint;
150
+ return { peerId: endpoint.peerId, addrs: endpoint.addrs.filter(isCircuitAddr) };
151
+ }
152
+ /**
153
+ * Can a relay-only agent actually be reached with what it is about to publish?
154
+ *
155
+ * FALSE means it holds **no relay reservation yet**, so the circuit-only subset is empty. That must
156
+ * become a LOUD LOCAL REFUSAL rather than an empty publish: an empty publish is refused by the
157
+ * directory as malformed and surfaces to the operator as "the counterparty is offline", which is a
158
+ * lie about someone else's state caused by a setting on this machine.
159
+ */
160
+ export function relayOnlyReachable(endpoint, relayOnly) {
161
+ if (!relayOnly)
162
+ return true;
163
+ if (endpoint === null)
164
+ return false;
165
+ return endpoint.addrs.some(isCircuitAddr);
166
+ }
167
+ /**
168
+ * Which of the counterparty's advertised addresses may we dial?
169
+ *
170
+ * ⚠️ Returns the FILTERED LIST, not a boolean, because "relay-only" does not mean "do not connect" —
171
+ * it means "connect only over the circuit". The first build refused every address including the
172
+ * `/p2p-circuit` one, which is the relay route this setting exists to force everything onto, so it
173
+ * dropped every session onto the store-and-forward backstop.
174
+ *
175
+ * The counterparty may not be relay-only themselves, so they will still advertise direct addresses:
176
+ * those are dropped, because dialing one hands them our IP with our own setting switched on.
177
+ */
178
+ export function dialableAddrs(addrs, relayOnly) {
179
+ if (!relayOnly)
180
+ return [...addrs];
181
+ return addrs.filter(isCircuitAddr);
182
+ }
183
+ //# sourceMappingURL=relay-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-only.js","sourceRoot":"","sources":["../src/relay-only.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,UAA0C;IACpE,OAAO,UAAU,CAAC,cAAc,CAAC,KAAK,MAAM,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAC5B,UAA0C,EAC1C,QAAiB;IAEjB,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,cAAc,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,4FAA4F;IAC5F,8FAA8F;IAC9F,kGAAkG;IAClG,EAAE;IACF,oEAAoE;IACpE,EAAE;IACF,6FAA6F;IAC7F,mGAAmG;IACnG,gGAAgG;IAChG,kBAAkB;IAClB,EAAE;IACF,0FAA0F;IAC1F,8FAA8F;IAC9F,mGAAmG;IACnG,sBAAsB;IACtB,EAAE;IACF,gGAAgG;IAChG,kGAAkG;IAClG,4FAA4F;IAC5F,iGAAiG;IACjG,kDAAkD;IAClD,EAAE;IACF,kGAAkG;IAClG,mGAAmG;IACnG,gGAAgG;IAChG,iBAAiB;IACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAkB,EAClB,SAAkB;IAElB,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;AAClF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAoC,EAAE,SAAkB;IACzF,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,KAAwB,EAAE,SAAkB;IACxE,IAAI,CAAC,SAAS;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACrC,CAAC"}