@cello-protocol/daemon 0.0.181 → 0.0.182

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 (164) hide show
  1. package/dist/agent-id-migration.d.ts +9 -0
  2. package/dist/agent-id-migration.d.ts.map +1 -1
  3. package/dist/agent-id-migration.js +73 -1
  4. package/dist/agent-id-migration.js.map +1 -1
  5. package/dist/agent-selection.d.ts +73 -0
  6. package/dist/agent-selection.d.ts.map +1 -0
  7. package/dist/agent-selection.js +80 -0
  8. package/dist/agent-selection.js.map +1 -0
  9. package/dist/assignment-verify.d.ts +62 -0
  10. package/dist/assignment-verify.d.ts.map +1 -0
  11. package/dist/assignment-verify.js +185 -0
  12. package/dist/assignment-verify.js.map +1 -0
  13. package/dist/backup-restore.d.ts +102 -0
  14. package/dist/backup-restore.d.ts.map +1 -0
  15. package/dist/backup-restore.js +340 -0
  16. package/dist/backup-restore.js.map +1 -0
  17. package/dist/bin/cello-daemon.js +91 -49
  18. package/dist/bin/cello-daemon.js.map +1 -1
  19. package/dist/close-commitment.d.ts +67 -0
  20. package/dist/close-commitment.d.ts.map +1 -0
  21. package/dist/close-commitment.js +78 -0
  22. package/dist/close-commitment.js.map +1 -0
  23. package/dist/close-session-handler.d.ts +20 -0
  24. package/dist/close-session-handler.d.ts.map +1 -1
  25. package/dist/close-session-handler.js +351 -58
  26. package/dist/close-session-handler.js.map +1 -1
  27. package/dist/consortium-bootstrap.d.ts +2 -0
  28. package/dist/consortium-bootstrap.d.ts.map +1 -1
  29. package/dist/consortium-bootstrap.js +65 -7
  30. package/dist/consortium-bootstrap.js.map +1 -1
  31. package/dist/content-park.d.ts.map +1 -1
  32. package/dist/content-park.js +141 -10
  33. package/dist/content-park.js.map +1 -1
  34. package/dist/daemon.d.ts +13 -1
  35. package/dist/daemon.d.ts.map +1 -1
  36. package/dist/daemon.js +866 -122
  37. package/dist/daemon.js.map +1 -1
  38. package/dist/delivery-session-suspects.d.ts.map +1 -1
  39. package/dist/delivery-session-suspects.js +5 -0
  40. package/dist/delivery-session-suspects.js.map +1 -1
  41. package/dist/directory-auth-posture.d.ts +87 -0
  42. package/dist/directory-auth-posture.d.ts.map +1 -0
  43. package/dist/directory-auth-posture.js +134 -0
  44. package/dist/directory-auth-posture.js.map +1 -0
  45. package/dist/directory-bootstrap.d.ts +66 -3
  46. package/dist/directory-bootstrap.d.ts.map +1 -1
  47. package/dist/directory-bootstrap.js +133 -7
  48. package/dist/directory-bootstrap.js.map +1 -1
  49. package/dist/document-delivery-transport.d.ts +22 -2
  50. package/dist/document-delivery-transport.d.ts.map +1 -1
  51. package/dist/document-delivery-transport.js +11 -3
  52. package/dist/document-delivery-transport.js.map +1 -1
  53. package/dist/inbound-sessions.d.ts +31 -1
  54. package/dist/inbound-sessions.d.ts.map +1 -1
  55. package/dist/inbound-sessions.js +276 -16
  56. package/dist/inbound-sessions.js.map +1 -1
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +3 -0
  60. package/dist/index.js.map +1 -1
  61. package/dist/ipc-server.d.ts +5 -1
  62. package/dist/ipc-server.d.ts.map +1 -1
  63. package/dist/ipc-server.js +19 -3
  64. package/dist/ipc-server.js.map +1 -1
  65. package/dist/manifest-validity.d.ts +151 -0
  66. package/dist/manifest-validity.d.ts.map +1 -0
  67. package/dist/manifest-validity.js +268 -0
  68. package/dist/manifest-validity.js.map +1 -0
  69. package/dist/notification-handlers.d.ts.map +1 -1
  70. package/dist/notification-handlers.js +15 -0
  71. package/dist/notification-handlers.js.map +1 -1
  72. package/dist/outbound-sessions.d.ts +31 -0
  73. package/dist/outbound-sessions.d.ts.map +1 -1
  74. package/dist/outbound-sessions.js +198 -17
  75. package/dist/outbound-sessions.js.map +1 -1
  76. package/dist/park-envelope.d.ts +72 -1
  77. package/dist/park-envelope.d.ts.map +1 -1
  78. package/dist/park-envelope.js +119 -4
  79. package/dist/park-envelope.js.map +1 -1
  80. package/dist/refusal-reasons.d.ts +72 -0
  81. package/dist/refusal-reasons.d.ts.map +1 -0
  82. package/dist/refusal-reasons.js +69 -0
  83. package/dist/refusal-reasons.js.map +1 -0
  84. package/dist/registration-manager.d.ts.map +1 -1
  85. package/dist/registration-manager.js +20 -1
  86. package/dist/registration-manager.js.map +1 -1
  87. package/dist/restart-seal-resolver.d.ts.map +1 -1
  88. package/dist/restart-seal-resolver.js +6 -0
  89. package/dist/restart-seal-resolver.js.map +1 -1
  90. package/dist/retry-queue.d.ts +23 -1
  91. package/dist/retry-queue.d.ts.map +1 -1
  92. package/dist/retry-queue.js +37 -9
  93. package/dist/retry-queue.js.map +1 -1
  94. package/dist/roster-freshness.d.ts +169 -0
  95. package/dist/roster-freshness.d.ts.map +1 -0
  96. package/dist/roster-freshness.js +249 -0
  97. package/dist/roster-freshness.js.map +1 -0
  98. package/dist/seal-certificate-pull.d.ts +17 -1
  99. package/dist/seal-certificate-pull.d.ts.map +1 -1
  100. package/dist/seal-certificate-pull.js +37 -3
  101. package/dist/seal-certificate-pull.js.map +1 -1
  102. package/dist/seal-coordinator.d.ts +17 -1
  103. package/dist/seal-coordinator.d.ts.map +1 -1
  104. package/dist/seal-coordinator.js +71 -0
  105. package/dist/seal-coordinator.js.map +1 -1
  106. package/dist/seal-failure-store.d.ts +104 -0
  107. package/dist/seal-failure-store.d.ts.map +1 -0
  108. package/dist/seal-failure-store.js +126 -0
  109. package/dist/seal-failure-store.js.map +1 -0
  110. package/dist/seal-flows.d.ts.map +1 -1
  111. package/dist/seal-flows.js +35 -6
  112. package/dist/seal-flows.js.map +1 -1
  113. package/dist/seal-upgrade.d.ts +20 -5
  114. package/dist/seal-upgrade.d.ts.map +1 -1
  115. package/dist/seal-upgrade.js +28 -5
  116. package/dist/seal-upgrade.js.map +1 -1
  117. package/dist/session-assignment-parser.d.ts +41 -5
  118. package/dist/session-assignment-parser.d.ts.map +1 -1
  119. package/dist/session-assignment-parser.js +77 -14
  120. package/dist/session-assignment-parser.js.map +1 -1
  121. package/dist/session-ceremony.d.ts +29 -0
  122. package/dist/session-ceremony.d.ts.map +1 -1
  123. package/dist/session-ceremony.js +71 -0
  124. package/dist/session-ceremony.js.map +1 -1
  125. package/dist/session-connection-gater.d.ts +46 -7
  126. package/dist/session-connection-gater.d.ts.map +1 -1
  127. package/dist/session-connection-gater.js +163 -12
  128. package/dist/session-connection-gater.js.map +1 -1
  129. package/dist/session-content-handlers.d.ts.map +1 -1
  130. package/dist/session-content-handlers.js +110 -4
  131. package/dist/session-content-handlers.js.map +1 -1
  132. package/dist/session-node-manager.d.ts +406 -36
  133. package/dist/session-node-manager.d.ts.map +1 -1
  134. package/dist/session-node-manager.js +3025 -245
  135. package/dist/session-node-manager.js.map +1 -1
  136. package/dist/session-read-handlers.d.ts +27 -0
  137. package/dist/session-read-handlers.d.ts.map +1 -1
  138. package/dist/session-read-handlers.js +112 -6
  139. package/dist/session-read-handlers.js.map +1 -1
  140. package/dist/session-relay-client.d.ts +61 -2
  141. package/dist/session-relay-client.d.ts.map +1 -1
  142. package/dist/session-relay-client.js +170 -11
  143. package/dist/session-relay-client.js.map +1 -1
  144. package/dist/session-salt-agreement.d.ts +284 -0
  145. package/dist/session-salt-agreement.d.ts.map +1 -0
  146. package/dist/session-salt-agreement.js +371 -0
  147. package/dist/session-salt-agreement.js.map +1 -0
  148. package/dist/signal-submission.d.ts.map +1 -1
  149. package/dist/signal-submission.js +10 -1
  150. package/dist/signal-submission.js.map +1 -1
  151. package/dist/signaling-connect.d.ts.map +1 -1
  152. package/dist/signaling-connect.js +42 -5
  153. package/dist/signaling-connect.js.map +1 -1
  154. package/dist/types.d.ts +54 -0
  155. package/dist/types.d.ts.map +1 -1
  156. package/dist/types.js.map +1 -1
  157. package/dist/vocabulary.d.ts.map +1 -1
  158. package/dist/vocabulary.js +10 -0
  159. package/dist/vocabulary.js.map +1 -1
  160. package/dist/wire-content-hash.d.ts +56 -0
  161. package/dist/wire-content-hash.d.ts.map +1 -1
  162. package/dist/wire-content-hash.js +71 -0
  163. package/dist/wire-content-hash.js.map +1 -1
  164. package/package.json +5 -5
@@ -41,6 +41,15 @@
41
41
  */
42
42
  import type { Logger } from "./types.js";
43
43
  import { type DaemonDatabase } from "./sqlcipher-db.js";
44
+ /**
45
+ * The tables this migration rebuilds, derived from `REKEY_TARGETS` rather than written out again.
46
+ *
47
+ * Exported for the guards (`dod-m15-migration-guard-1`), which must cover exactly what the
48
+ * migration touches. A hand-typed copy over there would silently get SHORTER than this list the day
49
+ * an eighth table is added — so the one table nobody remembered to guard would be the one table
50
+ * nobody checks, which is the shape of every escape this migration has already had.
51
+ */
52
+ export declare const REKEYED_TABLES: readonly string[];
44
53
  export interface AgentIdMigrationResult {
45
54
  readonly migrated: boolean;
46
55
  /** Rows copied, per rebuilt table. Absent tables are omitted. */
@@ -1 +1 @@
1
- {"version":3,"file":"agent-id-migration.d.ts","sourceRoot":"","sources":["../src/agent-id-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAwK5E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD;AAyDD;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAyIxG"}
1
+ {"version":3,"file":"agent-id-migration.d.ts","sourceRoot":"","sources":["../src/agent-id-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAuO5E;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAsC,CAAC;AAEnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD;AAyDD;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAyIxG"}
@@ -79,6 +79,21 @@ const REKEY_TARGETS = [
79
79
  interrupted_by TEXT,
80
80
  restart_seal_gave_up_at INTEGER,
81
81
  restart_seal_gave_up_reason TEXT,
82
+ -- DOD-M15-DIVERGE-DURABLE-1. Omitting it here would delete the flag on the one boot a
83
+ -- legacy database upgrades, and a dropped divergence reads as HEALTHY — exactly the
84
+ -- failure the column was added to prevent, reintroduced by the migration that carries it.
85
+ diverged_at INTEGER,
86
+ -- Decisions Carried #8 — the session salt. Omitting it here drops the salt on the one boot
87
+ -- a legacy database upgrades, and a dropped salt is WORSE than no salt: every leaf hashed
88
+ -- under it becomes unverifiable, and the "does this session already have one?" lookup then
89
+ -- mints a fresh salt and splits the transcript silently. Same trap as diverged_at above.
90
+ content_salt BLOB,
91
+ -- DOD-M15-FREEZE-STATUS-1, carried for CELLO_Support's lane. Dropping these on upgrade would
92
+ -- un-freeze a session frozen because a party signed with a key that was not the
93
+ -- counterparty's — the failure that column exists to survive, reintroduced by the migration
94
+ -- that carries it.
95
+ frozen_at INTEGER,
96
+ frozen_reason TEXT,
82
97
  PRIMARY KEY (agent_id, session_id)
83
98
  )`,
84
99
  indexSql: () => [],
@@ -126,6 +141,14 @@ const REKEY_TARGETS = [
126
141
  direction TEXT NOT NULL,
127
142
  blob BLOB NOT NULL,
128
143
  created_at INTEGER NOT NULL,
144
+ -- DOD-M15-SEALWIRE-1 bullet 5. THE SECOND ENTRY. session-node-manager adds these by
145
+ -- inline ALTER before this rebuild runs, and the rebuild copies only the INTERSECTION --
146
+ -- so omitting them here DELETES a message's authorship proof on the one boot a legacy
147
+ -- database upgrades, then re-adds the columns empty. A transcript that silently stops
148
+ -- proving who wrote what is worse than one that never claimed to.
149
+ sender_pubkey TEXT,
150
+ sender_sig BLOB,
151
+ attribution TEXT NOT NULL DEFAULT 'local_session_state',
129
152
  PRIMARY KEY (agent_id, session_id, sequence, direction)
130
153
  )`,
131
154
  indexSql: () => [],
@@ -170,6 +193,43 @@ const REKEY_TARGETS = [
170
193
  // old semantics for them while giving each agent its own namespace.
171
194
  table: "retry_queue",
172
195
  backfill: "nullable",
196
+ /**
197
+ * ⚠️ THREE COLUMNS WERE MISSING FROM THE DDL BELOW. NOTHING WAS EVER LOST — AND WHAT KEPT IT
198
+ * THAT WAY IS THE ORDER OF TWO CALLS, NOT A CHECK.
199
+ *
200
+ * ⚠️ THIS COMMENT PREVIOUSLY CALLED IT *"a live data-loss bug"*, and that was WRONG. The other
201
+ * lane disproved it against git history and I verified it independently rather than take it:
202
+ * this re-key shipped 2026-07-10, `structure1_cbor` / `structure2_cbor` arrived in
203
+ * `retry-queue.ts` on 2026-08-05, and the re-key is one-shot. Every database that has ever run
204
+ * it did so a month before the columns existed, so there was never an ordering record present to
205
+ * drop. Recording the correction here because a comment stating a live bug that is not live is
206
+ * exactly the artifact this milestone keeps finding — one with the FORM of a verified finding
207
+ * and no verification behind it.
208
+ *
209
+ * **The real property, which is narrower and more fragile than the claim it replaces.** The
210
+ * rebuild copies the INTERSECTION of the two column lists, so omitting a column here does drop
211
+ * it — that mechanism is real and is what the header at the top of this file warns about. It is
212
+ * unreachable for this table only because `RetryQueue`'s constructor, which owns those
213
+ * `ALTER TABLE`s, runs AFTER `initialize()` — so at the moment this DDL executes, the columns do
214
+ * not exist to be copied. `daemon.ts` builds the queue roughly 1,400 lines after it calls
215
+ * `initialize()`, and nothing enforces that distance but a comment saying not to reorder.
216
+ *
217
+ * So the columns are listed here anyway. They cost nothing while the order holds, and they are
218
+ * the difference between a silent loss and no loss on the day someone moves the construction up.
219
+ *
220
+ * What that loss WOULD cost, if it ever became reachable: those two columns are the relay's
221
+ * signed ordering record, carried so a parked entry is self-ordering on recovery. Without it the
222
+ * recipient places the content at its ARRIVAL index rather than its witnessed sequence, the two
223
+ * trees part, and the session can no longer seal bilaterally.
224
+ *
225
+ * `content_hash_alg` is `DOD-M15-SEALWIRE-1` part B2b's own column, added here in the same edit
226
+ * as the two it would otherwise have joined. It is why the omission was found at all.
227
+ *
228
+ * The existing guard could not see any of it: `dod-agent-id-joinkey-migration` replays the inline
229
+ * ALTERs in the real boot order, but only the `sessions` ones — `retry_queue`'s live in a
230
+ * different file and run from a different constructor. `DOD-M15-MIGRATION-GUARD-1` is what now
231
+ * covers the cross-file case.
232
+ */
173
233
  createSql: (t) => `
174
234
  CREATE TABLE ${t} (
175
235
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -181,7 +241,10 @@ const REKEY_TARGETS = [
181
241
  attempts INTEGER NOT NULL DEFAULT 1,
182
242
  position INTEGER NOT NULL,
183
243
  awaiting_ack INTEGER NOT NULL DEFAULT 0,
184
- content_hash_hex TEXT
244
+ content_hash_hex TEXT,
245
+ structure1_cbor BLOB,
246
+ structure2_cbor BLOB,
247
+ content_hash_alg TEXT
185
248
  )`,
186
249
  indexSql: (t) => [
187
250
  `CREATE INDEX IF NOT EXISTS retry_queue_by_session_position ON ${t}(session_id, position ASC)`,
@@ -189,6 +252,15 @@ const REKEY_TARGETS = [
189
252
  ],
190
253
  },
191
254
  ];
255
+ /**
256
+ * The tables this migration rebuilds, derived from `REKEY_TARGETS` rather than written out again.
257
+ *
258
+ * Exported for the guards (`dod-m15-migration-guard-1`), which must cover exactly what the
259
+ * migration touches. A hand-typed copy over there would silently get SHORTER than this list the day
260
+ * an eighth table is added — so the one table nobody remembered to guard would be the one table
261
+ * nobody checks, which is the shape of every escape this migration has already had.
262
+ */
263
+ export const REKEYED_TABLES = REKEY_TARGETS.map((t) => t.table);
192
264
  function columnsOf(db, table) {
193
265
  return db.prepare(`PRAGMA table_info(${table})`).all().map((c) => c.name);
194
266
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-id-migration.js","sourceRoot":"","sources":["../src/agent-id-migration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-id-migration.js","sourceRoot":"","sources":["../src/agent-id-migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Which agent a call acts as, and HOW that was decided — `DOD-M15-SELECTION-1`,
3
+ * `DOD-M15-IPCVISIBLE-1`.
4
+ *
5
+ * ─── The defect this is extracted from ─────────────────────────────────────────────────────────
6
+ *
7
+ * This logic was four lines inside `daemon.ts`, ending in:
8
+ *
9
+ * if (onlineAgents.size === 1) return [...onlineAgents][0];
10
+ *
11
+ * A connection that had selected nothing therefore acted as whichever agent happened to be the only
12
+ * one online. On a shared daemon that can be a DIFFERENT operator's agent, which is how it was
13
+ * found: after a restart a released agent was silently reinstated under someone else's name.
14
+ *
15
+ * ─── Why the fallback is worse than it looks even when it picks the "right" agent ──────────────
16
+ *
17
+ * It produces a HALF-ATTENDED state. Tools resolve a subject and work; the notification dispatcher
18
+ * routes doorbells by the connection's REGISTERED current agent, which this never sets. So the
19
+ * session sends and receives on request but never wakes — and an operator reads that as the
20
+ * protocol dropping messages, not as a selection that was never made.
21
+ *
22
+ * ─── AND WHY IT IS STILL HERE ──────────────────────────────────────────────────────────────────
23
+ *
24
+ * My first version switched the fallback OFF for MCP on that reasoning, and four tests said no. CC-3
25
+ * added it deliberately, to fix "the post-/mcp-reconnect papercut": a reconnected session with
26
+ * exactly one agent online used to hard-fail `no_current_agent`.
27
+ *
28
+ * `DOD-M15-SELECTION-1`'s answer is narrower than removal — *"if a fallback is wanted it is EXPLICIT
29
+ * in the response, not announced as an accomplished fact"* — and it sequences the work: *"diagnosis
30
+ * first… with the trigger field from DOD-M15-IPCVISIBLE-1 distinguishing replay from fallback in one
31
+ * run."* So this module makes the decision ATTRIBUTABLE, which is the precondition, and changing
32
+ * what the fallback DOES waits for the diagnosis that attribution makes possible.
33
+ *
34
+ * ─── Every path reports how it got there ───────────────────────────────────────────────────────
35
+ *
36
+ * Two agent switches fired one second after a reconnect on 2026-08-09 and neither could be
37
+ * attributed, because an operator's explicit selection and the shim's reconnect replay arrive
38
+ * identically. `fallback` is the third value `DOD-M15-IPCVISIBLE-1` asks for, and the one that was
39
+ * invisible.
40
+ */
41
+ /** How a call's acting agent was arrived at. Every branch reports one. */
42
+ export type SelectionTrigger =
43
+ /** The caller named an agent on this call. */
44
+ "explicit"
45
+ /** The connection had selected one earlier with `cello_use_agent`. */
46
+ | "selected"
47
+ /** Nothing was selected and one agent was online — a CLI convenience, never for a live session. */
48
+ | "fallback"
49
+ /**
50
+ * The connection's choice was TAKEN AWAY — the agent was shut down or removed underneath it.
51
+ *
52
+ * NOT a voluntary release. `cello_stop_using_agent` deliberately does not set this: the operator
53
+ * choosing to hold nothing stays eligible for the sole-online fallback, whereas a connection whose
54
+ * agent vanished must not have a replacement guessed for it.
55
+ */
56
+ | "cleared"
57
+ /** No agent could be determined. */
58
+ | "none";
59
+ export interface SelectionConnState {
60
+ currentAgent: string | null;
61
+ /** Set by `cello_stop_using_agent`: this connection HAD an intent and gave it up. */
62
+ clearedAgent?: string;
63
+ /** `"mcp"` is a live session; anything else is treated as an ephemeral CLI invocation. */
64
+ clientType?: string;
65
+ }
66
+ export declare function resolveCurrentAgentFor(opts: {
67
+ connState: SelectionConnState | undefined;
68
+ onlineAgents: ReadonlySet<string>;
69
+ explicitAgent?: string;
70
+ /** Called exactly once with the outcome, so the decision is attributable in the log. */
71
+ onResolved?: (agent: string | null, trigger: SelectionTrigger) => void;
72
+ }): string | null;
73
+ //# sourceMappingURL=agent-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-selection.d.ts","sourceRoot":"","sources":["../src/agent-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB;AAC1B,8CAA8C;AAC5C,UAAU;AACZ,sEAAsE;GACpE,UAAU;AACZ,mGAAmG;GACjG,UAAU;AACZ;;;;;;GAMG;GACD,SAAS;AACX,oCAAoC;GAClC,MAAM,CAAC;AAEX,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,SAAS,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC1C,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACxE,GAAG,MAAM,GAAG,IAAI,CAsChB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Which agent a call acts as, and HOW that was decided — `DOD-M15-SELECTION-1`,
3
+ * `DOD-M15-IPCVISIBLE-1`.
4
+ *
5
+ * ─── The defect this is extracted from ─────────────────────────────────────────────────────────
6
+ *
7
+ * This logic was four lines inside `daemon.ts`, ending in:
8
+ *
9
+ * if (onlineAgents.size === 1) return [...onlineAgents][0];
10
+ *
11
+ * A connection that had selected nothing therefore acted as whichever agent happened to be the only
12
+ * one online. On a shared daemon that can be a DIFFERENT operator's agent, which is how it was
13
+ * found: after a restart a released agent was silently reinstated under someone else's name.
14
+ *
15
+ * ─── Why the fallback is worse than it looks even when it picks the "right" agent ──────────────
16
+ *
17
+ * It produces a HALF-ATTENDED state. Tools resolve a subject and work; the notification dispatcher
18
+ * routes doorbells by the connection's REGISTERED current agent, which this never sets. So the
19
+ * session sends and receives on request but never wakes — and an operator reads that as the
20
+ * protocol dropping messages, not as a selection that was never made.
21
+ *
22
+ * ─── AND WHY IT IS STILL HERE ──────────────────────────────────────────────────────────────────
23
+ *
24
+ * My first version switched the fallback OFF for MCP on that reasoning, and four tests said no. CC-3
25
+ * added it deliberately, to fix "the post-/mcp-reconnect papercut": a reconnected session with
26
+ * exactly one agent online used to hard-fail `no_current_agent`.
27
+ *
28
+ * `DOD-M15-SELECTION-1`'s answer is narrower than removal — *"if a fallback is wanted it is EXPLICIT
29
+ * in the response, not announced as an accomplished fact"* — and it sequences the work: *"diagnosis
30
+ * first… with the trigger field from DOD-M15-IPCVISIBLE-1 distinguishing replay from fallback in one
31
+ * run."* So this module makes the decision ATTRIBUTABLE, which is the precondition, and changing
32
+ * what the fallback DOES waits for the diagnosis that attribution makes possible.
33
+ *
34
+ * ─── Every path reports how it got there ───────────────────────────────────────────────────────
35
+ *
36
+ * Two agent switches fired one second after a reconnect on 2026-08-09 and neither could be
37
+ * attributed, because an operator's explicit selection and the shim's reconnect replay arrive
38
+ * identically. `fallback` is the third value `DOD-M15-IPCVISIBLE-1` asks for, and the one that was
39
+ * invisible.
40
+ */
41
+ export function resolveCurrentAgentFor(opts) {
42
+ const report = (agent, trigger) => {
43
+ opts.onResolved?.(agent, trigger);
44
+ return agent;
45
+ };
46
+ if (opts.explicitAgent)
47
+ return report(opts.explicitAgent, "explicit");
48
+ if (opts.connState?.currentAgent)
49
+ return report(opts.connState.currentAgent, "selected");
50
+ /**
51
+ * AN INVOLUNTARY CLEAR BLOCKS THE FALLBACK. Pre-existing behaviour, preserved.
52
+ *
53
+ * `clearedAgent` means the connection's agent was shut down or removed underneath it — do not
54
+ * guess a replacement. A VOLUNTARY release (`cello_stop_using_agent`) deliberately does not set
55
+ * it, because the operator choosing to hold nothing is not the same as having the choice taken,
56
+ * and they stay eligible for the fallback.
57
+ */
58
+ if (opts.connState?.clearedAgent)
59
+ return report(null, "cleared");
60
+ /**
61
+ * THE SOLE-ONLINE FALLBACK — behaviour UNCHANGED, visibility added.
62
+ *
63
+ * `DOD-M15-SELECTION-1` names this as the place a live MCP session gets bound to an identity it
64
+ * never asked for, and the instinct is to switch it off for MCP. That is wrong, and the tests say
65
+ * why: CC-3 introduced it deliberately to fix "the post-/mcp-reconnect papercut", where a
66
+ * reconnected session hard-failed `no_current_agent` with exactly one agent online.
67
+ *
68
+ * The line's own answer is narrower than removal: *"if a fallback is wanted it is EXPLICIT in the
69
+ * response, not announced as an accomplished fact."* And it sequences the work — *"diagnosis
70
+ * first… with the trigger field from DOD-M15-IPCVISIBLE-1 distinguishing replay from fallback in
71
+ * one run."* So this reports itself, and changing what it DOES waits for that diagnosis.
72
+ *
73
+ * Exactly one, never a guess between two: choosing between identities is a coin flip with the
74
+ * operator's name on it, not a convenience.
75
+ */
76
+ if (opts.onlineAgents.size === 1)
77
+ return report([...opts.onlineAgents][0], "fallback");
78
+ return report(null, "none");
79
+ }
80
+ //# sourceMappingURL=agent-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-selection.js","sourceRoot":"","sources":["../src/agent-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AA6BH,MAAM,UAAU,sBAAsB,CAAC,IAMtC;IACC,MAAM,MAAM,GAAG,CAAC,KAAoB,EAAE,OAAyB,EAAiB,EAAE;QAChF,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,IAAI,IAAI,CAAC,aAAa;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,SAAS,EAAE,YAAY;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAEzF;;;;;;;OAOG;IACH,IAAI,IAAI,CAAC,SAAS,EAAE,YAAY;QAAE,OAAO,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEjE;;;;;;;;;;;;;;;OAeG;IACH,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAE,EAAE,UAAU,CAAC,CAAC;IAExF,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,62 @@
1
+ import type { SessionAssignment } from "@cello-protocol/protocol-types";
2
+ import type { DbRegistrationPersistence } from "./db-identity-store.js";
3
+ import type { Logger } from "./types.js";
4
+ /**
5
+ * DOD-M15-ASSIGN-1 — verify a session assignment's signature before anything trusts it.
6
+ *
7
+ * REFUSES, never logs-and-continues. The whole finding here is a comment naming a verification the
8
+ * tree does not perform, so a check that ran and then let the session proceed anyway would be the
9
+ * same defect with more code. `DOD-M15-ASSIGN-1`'s receiver gate reads this assignment; gating on a
10
+ * document nobody verified relocates trust rather than closing it.
11
+ */
12
+ export declare function verifyAssignmentSignature(assignment: SessionAssignment, persistence: DbRegistrationPersistence, logger: Logger, agentName: string, correlationId: string): Promise<{
13
+ ok: true;
14
+ } | {
15
+ ok: false;
16
+ reason: string;
17
+ guidance: string;
18
+ }>;
19
+ /**
20
+ * DOD-M15-RESPONDER-VERIFY-1 — the RESPONDER's half, which until now did not exist.
21
+ *
22
+ * The initiator verifies its assignment against its own threshold group key (above). The responder
23
+ * did not verify at all: it logged `session.inbound.assignment.unverified` and proceeded, so every
24
+ * field it then acted on — the dialer it opens its receiver to, the `signer_pubkey` it persists as
25
+ * the seal trust anchor — was whatever the directory said.
26
+ *
27
+ * ─── Why this could not simply reuse the function above ────────────────────────────────────────
28
+ *
29
+ * That one compares `signer_pubkey` against the agent's OWN persisted `primaryPubkey`. The responder
30
+ * is not the signer — the assignment is signed by the INITIATOR's quorum — so it has no equivalent
31
+ * value, and verifying a frame's signature against a key from the same frame is circular: mint a
32
+ * key, sign with it, name it. That circularity is why the check was deferred rather than written.
33
+ *
34
+ * ─── What breaks the circle ────────────────────────────────────────────────────────────────────
35
+ *
36
+ * The TOFU pin. For a counterparty this agent has completed a session with, `expectedSignerHex` is
37
+ * what THIS daemon recorded then — a value no directory can retroactively change. Verifying against
38
+ * that is a real check: a compromised directory can produce a signature, but not one that verifies
39
+ * under a key it does not hold.
40
+ *
41
+ * ─── Two modes, and the weaker one is honest about being weaker ────────────────────────────────
42
+ *
43
+ * PINNED (`expectedSignerHex` given): the signature must verify under the PINNED key. Non-circular.
44
+ * This is the mode that matters, and it covers every repeat counterparty.
45
+ *
46
+ * UNPINNED (first contact): there is nothing independent to verify against, so this checks INTERNAL
47
+ * CONSISTENCY only — the signature verifies over the TBS recomputed from the assignment's own
48
+ * contents, under the key the frame names. That does NOT authenticate the directory, and it is not
49
+ * claimed to. What it does catch is a TAMPERED or garbage assignment — one whose fields were altered
50
+ * after signing, or whose signature is noise — which today reaches the seal path unchallenged and
51
+ * gets PINNED, poisoning every later session with that counterparty. Refusing it here is what stops
52
+ * a bad first contact becoming a permanent one.
53
+ */
54
+ export declare function verifyInboundAssignment(assignment: SessionAssignment, expectedSignerHex: string | null): {
55
+ ok: true;
56
+ mode: "pinned" | "internal";
57
+ } | {
58
+ ok: false;
59
+ reason: string;
60
+ detail: string;
61
+ };
62
+ //# sourceMappingURL=assignment-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignment-verify.d.ts","sourceRoot":"","sources":["../src/assignment-verify.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,yBAAyB,EACtC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0GzE;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,iBAAiB,EAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAsD3F"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * assignment-verify.ts — DOD-M15-ASSIGN-1.
3
+ *
4
+ * `session-assignment-parser.ts` shape-validates a session assignment. Its header said the
5
+ * signature "is verified downstream by the transport/session layer against the directory's pinned
6
+ * key" — and that site did not exist: `buildSessionEstablishmentTbs` was called to SIGN, and
7
+ * nowhere to verify. This module is the downstream the comment promised.
8
+ *
9
+ * SEPARATE FROM THE PARSER on purpose. Parsing answers "is this the right shape"; verifying answers
10
+ * "did the right party say it". Keeping them apart means the second cannot be quietly skipped by a
11
+ * caller that only wanted the first — which is how the gap existed.
12
+ */
13
+ // `verify` (plain Ed25519) is deliberately NOT imported: the single-key branch that used it was
14
+ // removed with the downgrade refusal (review F1). Verifying `directory_signature` against the
15
+ // `directory_pubkey` riding beside it in the same unsigned frame checks a key against itself, and
16
+ // having that call available is how a future edit reintroduces the bypass.
17
+ import { verifyFrostSignature, CONTEXT_SESSION_ESTABLISHMENT } from "@cello-protocol/crypto";
18
+ import { buildSessionEstablishmentTbs, computeGenesisPrevRoot } from "@cello-protocol/protocol-types";
19
+ /**
20
+ * DOD-M15-ASSIGN-1 — verify a session assignment's signature before anything trusts it.
21
+ *
22
+ * REFUSES, never logs-and-continues. The whole finding here is a comment naming a verification the
23
+ * tree does not perform, so a check that ran and then let the session proceed anyway would be the
24
+ * same defect with more code. `DOD-M15-ASSIGN-1`'s receiver gate reads this assignment; gating on a
25
+ * document nobody verified relocates trust rather than closing it.
26
+ */
27
+ export async function verifyAssignmentSignature(assignment, persistence, logger, agentName, correlationId) {
28
+ // RECOMPUTED, not taken from the frame — and that is a strengthening rather than a workaround.
29
+ // `genesis_prev_root` is not on the wire at all: the directory derives it from
30
+ // (pubA, pubB, session_id, timestamp) and so must we. A value we derive cannot be chosen for us,
31
+ // so the TBS we verify against is anchored to the assignment's own participants and id.
32
+ const genesisPrevRoot = computeGenesisPrevRoot(assignment.participant_a.pubkey, assignment.participant_b.pubkey, assignment.session_id, assignment.session_timestamp);
33
+ const tbs = buildSessionEstablishmentTbs(assignment.session_id, assignment.participant_a.pubkey, assignment.participant_b.pubkey, genesisPrevRoot, assignment.session_timestamp, assignment.initiator_session_peer_id, assignment.initiator_session_addrs, assignment.counterparty_session_peer_id, assignment.counterparty_session_addrs, assignment.transport_mode);
34
+ /**
35
+ * LOAD THE REGISTRATION BEFORE BRANCHING ON `signature_type` — review F1, and this ordering is
36
+ * the entire fix.
37
+ *
38
+ * `signature_type` rides in the frame and is covered by no signature. The parser reads any value
39
+ * that is not the string "frost" — including an ABSENT field — as "single". So while this load
40
+ * lived inside the frost branch, a hostile directory disabled every check below by omitting one
41
+ * field: it put its own freshly-minted key in `directory_pubkey`, signed a TBS naming an
42
+ * impostor as the counterparty, and the single-key branch verified that signature against that
43
+ * same key and returned ok. The anti-circularity comparison, the threshold verify and the
44
+ * fail-closed were all simply stepped over.
45
+ *
46
+ * Reading the registration first closes it: an agent that HAS a threshold registration knows its
47
+ * assignments are FROST-signed, so a non-FROST one is a downgrade attempt and is refused by
48
+ * name — never quietly routed to a weaker check.
49
+ */
50
+ const reg = await persistence.loadRegistrationState();
51
+ if (!reg) {
52
+ // FAIL CLOSED. Without our own registration we cannot know whose quorum should have signed,
53
+ // so the signature is unverifiable — which is not the same as valid.
54
+ logger.warn("session.assignment.verify.no_identity", {
55
+ agentName, correlationId,
56
+ impact: "this agent has no persisted registration, so the signer of its own session assignment cannot be established; the session was refused rather than accepted unverified",
57
+ });
58
+ return {
59
+ ok: false,
60
+ reason: "assignment_unverifiable_no_registration",
61
+ guidance: "This agent has no registration on record, so the directory's session assignment cannot be checked against the key that should have signed it. Re-register with cello register-agent, then try again.",
62
+ };
63
+ }
64
+ if (assignment.signature_type !== "frost") {
65
+ /**
66
+ * THE DOWNGRADE REFUSAL. Checked against the producer, not assumed: the directory constructs
67
+ * `signature_type: "frost"` unconditionally at a single site (`directory-node.ts`), with no
68
+ * branch that can emit anything else. There is no legitimate producer of a single-key session
69
+ * assignment for a registered agent, so this is not a compatibility path being closed — it is
70
+ * a shape that only an attacker or a broken directory can send.
71
+ */
72
+ logger.error("session.assignment.signature_type_downgraded", {
73
+ agentName, correlationId,
74
+ offeredType: assignment.signature_type,
75
+ impact: "the assignment claimed a weaker signature type than this agent's registration can produce, which would have routed it to a check that verifies a key against itself; it was refused, and no session was established",
76
+ });
77
+ return {
78
+ ok: false,
79
+ reason: "assignment_signature_type_downgraded",
80
+ guidance: "The directory returned a session assignment that does not carry a threshold signature, though this agent is registered with one. Nothing was established and no message was sent. Retry the session; if it repeats, the directory you reached is not producing valid assignments and cello status will show which one that is.",
81
+ };
82
+ }
83
+ {
84
+ // THE ANTI-CIRCULARITY CHECK. `signer_pubkey` comes from the frame; `reg.primaryPubkey` comes
85
+ // from this machine's own registration. Comparing them is what makes verifying against
86
+ // `signer_pubkey` mean anything at all.
87
+ const expected = reg.primaryPubkey.toLowerCase();
88
+ const offered = Buffer.from(assignment.signer_pubkey).toString("hex").toLowerCase();
89
+ if (offered !== expected) {
90
+ logger.error("session.assignment.signer_mismatch", {
91
+ agentName, correlationId,
92
+ expectedPrefix: expected.slice(0, 16), offeredPrefix: offered.slice(0, 16),
93
+ impact: "the assignment was signed by a key that is not this agent's own threshold group key; it was refused, and no session was established",
94
+ });
95
+ return {
96
+ ok: false,
97
+ reason: "assignment_signer_not_this_agent",
98
+ guidance: "The directory returned a session assignment signed by a key that is not this agent's own. Nothing was established and no message was sent. This is refused rather than reported as an error because the observation cannot distinguish a directory fault from an attempt to broker a session on your behalf; cause undetermined.",
99
+ };
100
+ }
101
+ if (!verifyFrostSignature(assignment.directory_signature, tbs, CONTEXT_SESSION_ESTABLISHMENT, assignment.signer_pubkey)) {
102
+ logger.error("session.assignment.signature_invalid", {
103
+ agentName, correlationId, signatureType: "frost",
104
+ impact: "the assignment's threshold signature did not verify over its own contents; it was refused, and no session was established",
105
+ });
106
+ return {
107
+ ok: false,
108
+ reason: "assignment_signature_invalid",
109
+ guidance: "The directory's session assignment did not verify against the key that should have signed it. Nothing was established. Retry the session; if it repeats, the directory you reached is not producing valid assignments and cello status will show which one that is.",
110
+ };
111
+ }
112
+ return { ok: true };
113
+ }
114
+ }
115
+ /**
116
+ * DOD-M15-RESPONDER-VERIFY-1 — the RESPONDER's half, which until now did not exist.
117
+ *
118
+ * The initiator verifies its assignment against its own threshold group key (above). The responder
119
+ * did not verify at all: it logged `session.inbound.assignment.unverified` and proceeded, so every
120
+ * field it then acted on — the dialer it opens its receiver to, the `signer_pubkey` it persists as
121
+ * the seal trust anchor — was whatever the directory said.
122
+ *
123
+ * ─── Why this could not simply reuse the function above ────────────────────────────────────────
124
+ *
125
+ * That one compares `signer_pubkey` against the agent's OWN persisted `primaryPubkey`. The responder
126
+ * is not the signer — the assignment is signed by the INITIATOR's quorum — so it has no equivalent
127
+ * value, and verifying a frame's signature against a key from the same frame is circular: mint a
128
+ * key, sign with it, name it. That circularity is why the check was deferred rather than written.
129
+ *
130
+ * ─── What breaks the circle ────────────────────────────────────────────────────────────────────
131
+ *
132
+ * The TOFU pin. For a counterparty this agent has completed a session with, `expectedSignerHex` is
133
+ * what THIS daemon recorded then — a value no directory can retroactively change. Verifying against
134
+ * that is a real check: a compromised directory can produce a signature, but not one that verifies
135
+ * under a key it does not hold.
136
+ *
137
+ * ─── Two modes, and the weaker one is honest about being weaker ────────────────────────────────
138
+ *
139
+ * PINNED (`expectedSignerHex` given): the signature must verify under the PINNED key. Non-circular.
140
+ * This is the mode that matters, and it covers every repeat counterparty.
141
+ *
142
+ * UNPINNED (first contact): there is nothing independent to verify against, so this checks INTERNAL
143
+ * CONSISTENCY only — the signature verifies over the TBS recomputed from the assignment's own
144
+ * contents, under the key the frame names. That does NOT authenticate the directory, and it is not
145
+ * claimed to. What it does catch is a TAMPERED or garbage assignment — one whose fields were altered
146
+ * after signing, or whose signature is noise — which today reaches the seal path unchallenged and
147
+ * gets PINNED, poisoning every later session with that counterparty. Refusing it here is what stops
148
+ * a bad first contact becoming a permanent one.
149
+ */
150
+ export function verifyInboundAssignment(assignment, expectedSignerHex) {
151
+ if (assignment.signature_type !== "frost") {
152
+ return {
153
+ ok: false,
154
+ reason: "inbound_assignment_not_frost",
155
+ detail: `signature_type was ${String(assignment.signature_type)}; the directory produces frost for every session assignment`,
156
+ };
157
+ }
158
+ const signer = assignment.signer_pubkey;
159
+ if (!signer || signer.length !== 32) {
160
+ return { ok: false, reason: "inbound_assignment_no_signer", detail: "signer_pubkey missing or not 32 bytes" };
161
+ }
162
+ // PINNED beats named. When we hold an independent value, the frame's own claim about who signed is
163
+ // not consulted at all — using it would reintroduce the circularity the pin exists to break.
164
+ const verifyAgainst = expectedSignerHex !== null ? Buffer.from(expectedSignerHex, "hex") : signer;
165
+ if (expectedSignerHex !== null && Buffer.from(signer).toString("hex").toLowerCase() !== expectedSignerHex.toLowerCase()) {
166
+ return {
167
+ ok: false,
168
+ reason: "inbound_assignment_signer_not_pinned",
169
+ detail: "the assignment names a different signer than this agent recorded for this counterparty",
170
+ };
171
+ }
172
+ const genesisPrevRoot = computeGenesisPrevRoot(assignment.participant_a.pubkey, assignment.participant_b.pubkey, assignment.session_id, assignment.session_timestamp);
173
+ const tbs = buildSessionEstablishmentTbs(assignment.session_id, assignment.participant_a.pubkey, assignment.participant_b.pubkey, genesisPrevRoot, assignment.session_timestamp, assignment.initiator_session_peer_id, assignment.initiator_session_addrs, assignment.counterparty_session_peer_id, assignment.counterparty_session_addrs, assignment.transport_mode);
174
+ if (!verifyFrostSignature(assignment.directory_signature, tbs, CONTEXT_SESSION_ESTABLISHMENT, new Uint8Array(verifyAgainst))) {
175
+ return {
176
+ ok: false,
177
+ reason: "inbound_assignment_signature_invalid",
178
+ detail: expectedSignerHex !== null
179
+ ? "the signature did not verify under the key this agent recorded for this counterparty"
180
+ : "the signature did not verify over the assignment's own recomputed contents — the frame is tampered or malformed",
181
+ };
182
+ }
183
+ return { ok: true, mode: expectedSignerHex !== null ? "pinned" : "internal" };
184
+ }
185
+ //# sourceMappingURL=assignment-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignment-verify.js","sourceRoot":"","sources":["../src/assignment-verify.ts"],"names":[],"mappings":"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"}