@cello-protocol/daemon 0.0.23 → 0.0.24

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.
@@ -86,6 +86,17 @@ export interface DirectoryEndpointResolverOptions {
86
86
  directoryUrl?: string;
87
87
  /** Injectable fetch for testing. */
88
88
  fetchFn?: typeof fetch;
89
+ /**
90
+ * Whether a fresh /bootstrap failure falls back to the last known-good endpoint (default true).
91
+ *
92
+ * FINDING-4: set FALSE when this resolver is used as the PRIMARY probe inside
93
+ * createRosterAwareEndpointResolver. There, the stale-last-known-good fallback is HARMFUL — it
94
+ * masks a dead primary (a fresh failure returns the cached dead endpoint, so the wrapper never
95
+ * observes the primary as "down" and never fails over to the roster). With staleFallback:false a
96
+ * fresh failure returns null, and the roster becomes the real (and only) fallback. The default
97
+ * (true) preserves the M6/single-node backward-compat behavior for callers that are NOT wrapped.
98
+ */
99
+ staleFallback?: boolean;
89
100
  }
90
101
  /**
91
102
  * Build an async `getDirectoryEndpoint` for createSignalingConnect.
@@ -97,4 +108,58 @@ export interface DirectoryEndpointResolverOptions {
97
108
  * known-good endpoint so a transient /bootstrap blip doesn't strand a working daemon.
98
109
  */
99
110
  export declare function createDirectoryEndpointResolver(opts: DirectoryEndpointResolverOptions): () => Promise<DirectoryEndpoint | null>;
111
+ export interface RosterAwareResolverOptions {
112
+ /**
113
+ * Resolve the PRIMARY (configured) directory endpoint — typically the result of
114
+ * createDirectoryEndpointResolver (probes CELLO_DIRECTORY_URL's /bootstrap).
115
+ */
116
+ primaryResolver: () => Promise<DirectoryEndpoint | null>;
117
+ /**
118
+ * Resolve the CURRENTLY-REACHABLE consortium roster. Each member returned has already
119
+ * had its /bootstrap probed (manifestNodesToEndpoints skips unreachable nodes), so a
120
+ * member's presence in the returned array IS its reachability. NULL on the M6/M7
121
+ * back-compat path (no consortium manifest configured) → no failover, primary-only.
122
+ */
123
+ getConsortiumRoster: () => Promise<ConsortiumEndpoint[] | null>;
124
+ logger: Logger;
125
+ /**
126
+ * Test seam: order the fallback candidates. Production defaults to a Fisher-Yates
127
+ * shuffle so clients don't stampede one node when the primary goes down (CLAUDE.md
128
+ * redundancy invariant). Tests inject an identity shuffle for deterministic ordering.
129
+ */
130
+ shuffle?: <T>(items: T[]) => T[];
131
+ }
132
+ /**
133
+ * Wrap a single-node primary resolver with the consortium roster so the signaling
134
+ * dialer (and the ceremony endpoint that shares this instance) route AROUND a down
135
+ * primary directory node instead of retrying the single primary URL forever — the
136
+ * FINDING-4 bootstrap SPOF fix, honoring the sovereign-node REDUNDANCY invariant.
137
+ *
138
+ * Selection policy, per getDirectoryEndpoint() call:
139
+ * 1. Sticky-until-fail — while riding a non-primary fallback, KEEP it as long as it's
140
+ * still in the reachable roster. Do NOT churn back to the primary when it recovers
141
+ * (no flapping / reconnect storm). The fallback's multiaddr is refreshed from the
142
+ * fresh roster match each call.
143
+ * 2. Primary-first — otherwise try the configured node. This is also the healthy
144
+ * steady state: when the primary resolves, we return WITHOUT probing the roster
145
+ * (no per-connect roster cost while everything is nominal).
146
+ * 3. Fallback — if the primary is down, fail over to a reachable roster member. The
147
+ * order is randomized (across the members other than the dead primary) so clients
148
+ * spread across the survivors. Emits directory.bootstrap.failover on a change so an
149
+ * operator sees the client is now running on a non-home node.
150
+ * 4. Return null only when NOTHING resolves (primary down AND roster empty/absent) —
151
+ * the unchanged all-nodes-down failure mode, no crash.
152
+ *
153
+ * ONE instance is shared across the daemon's signaling connect and its ceremony
154
+ * getDirectoryEndpoint so signaling + ceremonies stay on the SAME directory node and
155
+ * fail over together (a coherent per-daemon directory selection).
156
+ *
157
+ * Scope note (FINDING-4 sufficiency, unproven): stickiness here is by ROSTER
158
+ * REACHABILITY, not by observed connect success — the resolver is not told whether a
159
+ * dial/auth against the returned endpoint actually succeeded. A node whose /bootstrap
160
+ * resolves is served by that same node, so resolvable ≈ connectable in practice; the
161
+ * live kill-primary failover test is the real proof that presence resolution, relay
162
+ * assignment, and the FROST ceremony all work against a non-home directory.
163
+ */
164
+ export declare function createRosterAwareEndpointResolver(opts: RosterAwareResolverOptions): () => Promise<DirectoryEndpoint | null>;
100
165
  //# sourceMappingURL=directory-bootstrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory-bootstrap.d.ts","sourceRoot":"","sources":["../src/directory-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,2CAA2C,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAEjG;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKzE;AAID,0FAA0F;AAC1F,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1E;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAgC/B;AAED,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,gCAAgC,GACrC,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA4BzC"}
1
+ {"version":3,"file":"directory-bootstrap.d.ts","sourceRoot":"","sources":["../src/directory-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,2CAA2C,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAEjG;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKzE;AAID,0FAA0F;AAC1F,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1E;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAgC/B;AAED,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,gCAAgC,GACrC,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA+BzC;AAID,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;IAChE,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;CAClC;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,0BAA0B,GAC/B,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA8DzC"}
@@ -136,6 +136,7 @@ export async function manifestNodesToEndpoints(nodes, opts) {
136
136
  export function createDirectoryEndpointResolver(opts) {
137
137
  const directoryUrl = opts.directoryUrl ?? resolveDirectoryUrl();
138
138
  const fetchFn = opts.fetchFn ?? fetch;
139
+ const staleFallback = opts.staleFallback ?? true;
139
140
  let lastGood = null;
140
141
  return async function getDirectoryEndpoint() {
141
142
  const multiaddr = await fetchBootstrapMultiaddr(directoryUrl, fetchFn);
@@ -154,12 +155,114 @@ export function createDirectoryEndpointResolver(opts) {
154
155
  else {
155
156
  opts.logger.warn("directory.bootstrap.unavailable", { directoryUrl });
156
157
  }
157
- // Fresh resolution failed — reuse the last known-good endpoint if we have one.
158
- if (lastGood) {
158
+ // Fresh resolution failed — reuse the last known-good endpoint if we have one AND stale fallback
159
+ // is enabled. When disabled (the failover-wrapper's primary probe), a fresh failure is reported
160
+ // as null so the roster can take over instead of the caller looping on a dead endpoint.
161
+ if (staleFallback && lastGood) {
159
162
  opts.logger.warn("directory.bootstrap.using_last_known", { directoryUrl, peerId: lastGood.peerId });
160
163
  return lastGood;
161
164
  }
162
165
  return null;
163
166
  };
164
167
  }
168
+ /** In-place-safe Fisher-Yates shuffle returning a NEW array (never mutates the input). */
169
+ function fisherYatesShuffle(items) {
170
+ const out = items.slice();
171
+ for (let i = out.length - 1; i > 0; i--) {
172
+ const j = Math.floor(Math.random() * (i + 1));
173
+ [out[i], out[j]] = [out[j], out[i]];
174
+ }
175
+ return out;
176
+ }
177
+ /**
178
+ * Wrap a single-node primary resolver with the consortium roster so the signaling
179
+ * dialer (and the ceremony endpoint that shares this instance) route AROUND a down
180
+ * primary directory node instead of retrying the single primary URL forever — the
181
+ * FINDING-4 bootstrap SPOF fix, honoring the sovereign-node REDUNDANCY invariant.
182
+ *
183
+ * Selection policy, per getDirectoryEndpoint() call:
184
+ * 1. Sticky-until-fail — while riding a non-primary fallback, KEEP it as long as it's
185
+ * still in the reachable roster. Do NOT churn back to the primary when it recovers
186
+ * (no flapping / reconnect storm). The fallback's multiaddr is refreshed from the
187
+ * fresh roster match each call.
188
+ * 2. Primary-first — otherwise try the configured node. This is also the healthy
189
+ * steady state: when the primary resolves, we return WITHOUT probing the roster
190
+ * (no per-connect roster cost while everything is nominal).
191
+ * 3. Fallback — if the primary is down, fail over to a reachable roster member. The
192
+ * order is randomized (across the members other than the dead primary) so clients
193
+ * spread across the survivors. Emits directory.bootstrap.failover on a change so an
194
+ * operator sees the client is now running on a non-home node.
195
+ * 4. Return null only when NOTHING resolves (primary down AND roster empty/absent) —
196
+ * the unchanged all-nodes-down failure mode, no crash.
197
+ *
198
+ * ONE instance is shared across the daemon's signaling connect and its ceremony
199
+ * getDirectoryEndpoint so signaling + ceremonies stay on the SAME directory node and
200
+ * fail over together (a coherent per-daemon directory selection).
201
+ *
202
+ * Scope note (FINDING-4 sufficiency, unproven): stickiness here is by ROSTER
203
+ * REACHABILITY, not by observed connect success — the resolver is not told whether a
204
+ * dial/auth against the returned endpoint actually succeeded. A node whose /bootstrap
205
+ * resolves is served by that same node, so resolvable ≈ connectable in practice; the
206
+ * live kill-primary failover test is the real proof that presence resolution, relay
207
+ * assignment, and the FROST ceremony all work against a non-home directory.
208
+ */
209
+ export function createRosterAwareEndpointResolver(opts) {
210
+ const shuffle = opts.shuffle ?? fisherYatesShuffle;
211
+ // The endpoint we last returned, and whether it is a non-primary fallback we're riding.
212
+ let current = null;
213
+ let stuckToFallback = false;
214
+ // The primary's own identity, learned whenever the primary last resolved. Used to EXCLUDE the
215
+ // primary from the fallback set even when `current` no longer points at it — a flapping primary
216
+ // whose independent roster probe still lists it must never be re-picked as its own fallback.
217
+ let primaryPeerId = null;
218
+ return async function getDirectoryEndpoint() {
219
+ // 1. Sticky-until-fail: keep the current fallback while it is still reachable.
220
+ if (stuckToFallback && current) {
221
+ const roster = await opts.getConsortiumRoster();
222
+ const match = roster?.find((e) => e.peerId === current.peerId);
223
+ if (match) {
224
+ // Refresh the multiaddr from the fresh roster resolution; identity is unchanged.
225
+ current = { peerId: match.peerId, multiaddr: match.multiaddr };
226
+ return current;
227
+ }
228
+ // The fallback fell out of the reachable roster → re-select below.
229
+ opts.logger.warn("directory.bootstrap.failover.lost", { peerId: current.peerId });
230
+ }
231
+ // 2. Primary-first (and the healthy steady state — no roster probe when it resolves).
232
+ const primary = await opts.primaryResolver();
233
+ if (primary) {
234
+ if (stuckToFallback) {
235
+ opts.logger.info("directory.bootstrap.failover", { to: primary.peerId, restored: true });
236
+ }
237
+ current = primary;
238
+ primaryPeerId = primary.peerId;
239
+ stuckToFallback = false;
240
+ return primary;
241
+ }
242
+ // 3. Primary is down → fail over to a reachable roster member (randomized order).
243
+ const roster = await opts.getConsortiumRoster();
244
+ if (roster && roster.length > 0) {
245
+ // Exclude the (now-dead/flapping) primary and the current pointer; any OTHER reachable member
246
+ // is valid. Falls back to the full roster only if excluding leaves nothing (all members are
247
+ // the excluded ones — e.g. the roster is just the primary itself).
248
+ const excluded = new Set([current?.peerId, primaryPeerId].filter((p) => !!p));
249
+ const others = roster.filter((e) => !excluded.has(e.peerId));
250
+ const ordered = shuffle(others.length > 0 ? others : roster);
251
+ const chosen = ordered[0];
252
+ const next = { peerId: chosen.peerId, multiaddr: chosen.multiaddr };
253
+ if (!current || current.peerId !== chosen.peerId) {
254
+ opts.logger.warn("directory.bootstrap.failover", {
255
+ from: current?.peerId ?? null,
256
+ to: chosen.peerId,
257
+ nodeId: chosen.nodeId,
258
+ });
259
+ }
260
+ current = next;
261
+ stuckToFallback = true;
262
+ return next;
263
+ }
264
+ // 4. Nothing resolves.
265
+ return null;
266
+ };
267
+ }
165
268
  //# sourceMappingURL=directory-bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory-bootstrap.js","sourceRoot":"","sources":["../src/directory-bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directory-bootstrap.js","sourceRoot":"","sources":["../src/directory-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,wBAAwB,GAAG,wCAAwC,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0C,OAAO,CAAC,GAAG;IACvF,OAAO,GAAG,CAAC,qBAAqB,CAAC,IAAI,wBAAwB,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAoB,EACpB,UAAwB,KAAK;IAE7B,MAAM,YAAY,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC;IACpE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;QAC5D,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3E,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAAiB;IACxD,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAgBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAC;IACpF,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAgC,EAChC,IAA4B;IAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAsC,EAAE;QAC3D,MAAM,IAAI,GAAG,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,4EAA4E;YAC5E,+EAA+E;YAC/E,6DAA6D;YAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4CAA4C,EAAE;gBAC9D,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE;gBACvD,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAC9F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACzE,CAAC,CAAC,CACH,CAAC;IACF,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAA2B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AACrE,CAAC;AAqBD;;;;;;;;GAQG;AACH,MAAM,UAAU,+BAA+B,CAC7C,IAAsC;IAEtC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,EAAE,CAAC;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IACjD,IAAI,QAAQ,GAA6B,IAAI,CAAC;IAE9C,OAAO,KAAK,UAAU,oBAAoB;QACxC,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACvE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,MAAM,EAAE,CAAC;gBACX,mFAAmF;gBACnF,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;oBAClD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC7E,CAAC;gBACD,QAAQ,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBACjC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;QACnF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,iGAAiG;QACjG,gGAAgG;QAChG,wFAAwF;QACxF,IAAI,aAAa,IAAI,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACpG,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AA0BD,0FAA0F;AAC1F,SAAS,kBAAkB,CAAI,KAAU;IACvC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,iCAAiC,CAC/C,IAAgC;IAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAC;IACnD,wFAAwF;IACxF,IAAI,OAAO,GAA6B,IAAI,CAAC;IAC7C,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,8FAA8F;IAC9F,gGAAgG;IAChG,6FAA6F;IAC7F,IAAI,aAAa,GAAkB,IAAI,CAAC;IAExC,OAAO,KAAK,UAAU,oBAAoB;QACxC,+EAA+E;QAC/E,IAAI,eAAe,IAAI,OAAO,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAQ,CAAC,MAAM,CAAC,CAAC;YAChE,IAAI,KAAK,EAAE,CAAC;gBACV,iFAAiF;gBACjF,OAAO,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC/D,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,mEAAmE;YACnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,sFAAsF;QACtF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO,GAAG,OAAO,CAAC;YAClB,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;YAC/B,eAAe,GAAG,KAAK,CAAC;YACxB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,kFAAkF;QAClF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAChD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,8FAA8F;YAC9F,4FAA4F;YAC5F,mEAAmE;YACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAsB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;YACvF,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;oBAC/C,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI;oBAC7B,EAAE,EAAE,MAAM,CAAC,MAAM;oBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,uBAAuB;QACvB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
@@ -55,4 +55,49 @@ export declare function findInflatedFrontier(participants: ReadonlyArray<{
55
55
  publishedFrontier: number;
56
56
  derivedFrontier: number;
57
57
  } | null;
58
+ export interface UnilateralFrontierParticipant {
59
+ pubkey: string;
60
+ content_frontier_seq: number;
61
+ attestation_mode: string;
62
+ }
63
+ export interface UnilateralFrontierCheck {
64
+ /**
65
+ * - verified: leaves present, no CLIENT-VERIFIABLE ('live') frontier exceeded its leaves.
66
+ * - corrected: leaves present, one or more 'live' frontiers were inflated and overridden
67
+ * DOWN to the re-derived value (see `corrections`).
68
+ * - directory_attested: no frontier_leaves shipped (a pre-FINDING-5 directory) — the cert stays
69
+ * directory-attested (FINDING-3 behavior). No correction possible.
70
+ * - leaves_invalid: frontier_leaves are forged / cross-session (reDeriveFrontiers failed) — a
71
+ * tamper signal; persist the directory-attested frontiers, log loudly. NEVER
72
+ * rejected (the unilateral dedup guard makes rejection an unrecoverable
73
+ * dead-end — cascade-2 reviewer Critical 2).
74
+ */
75
+ status: "verified" | "corrected" | "directory_attested" | "leaves_invalid";
76
+ /** lowercased pubkey → corrected content_frontier_seq, for inflated 'live' parties. The caller
77
+ * lowers the persisted frontier to this before recording the receipt. Empty unless status is 'corrected'. */
78
+ corrections: Map<string, number>;
79
+ reason?: string;
80
+ }
81
+ /**
82
+ * FINDING-5 — the present party independently re-verifies (and CORRECTS) the UNILATERAL receipt's
83
+ * frontiers. OVERRIDE, never reject.
84
+ *
85
+ * The unilateral legibility is FROST-notarized by the directory but the frontier VALUES are NOT bound
86
+ * into the seal signature (unlike the bilateral seal, whose signer binds the legibility hash), so the
87
+ * client must not trust them blindly. Because the directory-side dedup guard makes a client REJECTION
88
+ * of a unilateral cert unrecoverable (a retry close is silently ignored — no receipt ever produced,
89
+ * worse than FINDING-3), the client CORRECTS rather than rejects:
90
+ * - CLIENT-VERIFIABLE ('live') party: the present (submitting) party carries all its own signed
91
+ * leaves, so its content_frontier_seq is fully re-derivable. The directory cannot forge signed
92
+ * leaves, so the re-derived value is the provable truth → an inflated published value is OVERRIDDEN
93
+ * DOWN to it (inflation neutralized, receipt still persisted).
94
+ * - DIRECTORY-ATTESTED ('absent' / anything not 'live') party: its received-frontier remainder
95
+ * (acks of the present party's content) lives with the absent party and was never provided, so a
96
+ * published value ABOVE what the present party can derive is not provably inflation — left
97
+ * untouched, directory-attested (already marked per-participant).
98
+ *
99
+ * The caller applies `corrections` to the persisted legibility and logs per `status`; it ALWAYS
100
+ * persists a receipt (never dead-ends the close).
101
+ */
102
+ export declare function checkUnilateralFrontier(participants: ReadonlyArray<UnilateralFrontierParticipant>, frontierLeaves: SealFrontierLeaf[] | undefined, sessionId: Uint8Array): UnilateralFrontierCheck;
58
103
  //# sourceMappingURL=seal-frontier-verify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seal-frontier-verify.d.ts","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,UAAU,CAAC;IAC5B,aAAa,EAAE,UAAU,CAAC;IAC1B,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,wBAAwB,GAAG,gBAAgB,GAAG,uBAAuB,CAAA;CAAE,CAAC;AAQjG;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,iBAAiB,EAAE,UAAU,GAAG,cAAc,CA0B3G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7E,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ9E"}
1
+ {"version":3,"file":"seal-frontier-verify.d.ts","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,UAAU,CAAC;IAC5B,aAAa,EAAE,UAAU,CAAC;IAC1B,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,wBAAwB,GAAG,gBAAgB,GAAG,uBAAuB,CAAA;CAAE,CAAC;AAQjG;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,iBAAiB,EAAE,UAAU,GAAG,cAAc,CA0B3G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7E,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ9E;AAID,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;OAUG;IACH,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;IAC3E;kHAC8G;IAC9G,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,aAAa,CAAC,6BAA6B,CAAC,EAC1D,cAAc,EAAE,gBAAgB,EAAE,GAAG,SAAS,EAC9C,SAAS,EAAE,UAAU,GACpB,uBAAuB,CAyBzB"}
@@ -84,4 +84,53 @@ export function findInflatedFrontier(participants, derived) {
84
84
  }
85
85
  return null;
86
86
  }
87
+ /**
88
+ * FINDING-5 — the present party independently re-verifies (and CORRECTS) the UNILATERAL receipt's
89
+ * frontiers. OVERRIDE, never reject.
90
+ *
91
+ * The unilateral legibility is FROST-notarized by the directory but the frontier VALUES are NOT bound
92
+ * into the seal signature (unlike the bilateral seal, whose signer binds the legibility hash), so the
93
+ * client must not trust them blindly. Because the directory-side dedup guard makes a client REJECTION
94
+ * of a unilateral cert unrecoverable (a retry close is silently ignored — no receipt ever produced,
95
+ * worse than FINDING-3), the client CORRECTS rather than rejects:
96
+ * - CLIENT-VERIFIABLE ('live') party: the present (submitting) party carries all its own signed
97
+ * leaves, so its content_frontier_seq is fully re-derivable. The directory cannot forge signed
98
+ * leaves, so the re-derived value is the provable truth → an inflated published value is OVERRIDDEN
99
+ * DOWN to it (inflation neutralized, receipt still persisted).
100
+ * - DIRECTORY-ATTESTED ('absent' / anything not 'live') party: its received-frontier remainder
101
+ * (acks of the present party's content) lives with the absent party and was never provided, so a
102
+ * published value ABOVE what the present party can derive is not provably inflation — left
103
+ * untouched, directory-attested (already marked per-participant).
104
+ *
105
+ * The caller applies `corrections` to the persisted legibility and logs per `status`; it ALWAYS
106
+ * persists a receipt (never dead-ends the close).
107
+ */
108
+ export function checkUnilateralFrontier(participants, frontierLeaves, sessionId) {
109
+ const corrections = new Map();
110
+ const haveLeaves = Array.isArray(frontierLeaves) && frontierLeaves.length > 0;
111
+ // Pre-FINDING-5 directory (no leaves): keep FINDING-3's directory-attested behavior. Never reject —
112
+ // rejecting would regress the shipped FINDING-3 receipt and break unilateral seals against a
113
+ // not-yet-upgraded directory during rollout.
114
+ if (!haveLeaves)
115
+ return { status: "directory_attested", corrections };
116
+ const rederived = reDeriveFrontiers(frontierLeaves, sessionId);
117
+ // Forged / cross-session leaves are the STRONGEST tamper evidence, so they get the strongest
118
+ // correction — treat them as ZERO trustworthy evidence (an empty derived map), which drives any
119
+ // 'live' frontier > 0 down to 0. (Leaving the published value untouched would make malformed leaves
120
+ // an EASIER inflation bypass than shipping none — cascade-2 re-review.) We still never REJECT
121
+ // (the directory dedup guard makes rejection an unrecoverable dead-end); the caller logs loudly.
122
+ const derived = rederived.ok ? rederived.frontiers : new Map();
123
+ // Only CLIENT-VERIFIABLE ('live') parties are re-derivable; override any value above the provable
124
+ // one DOWN to it. The absent party is directory-attested (its remainder is not re-derivable here).
125
+ for (const p of participants) {
126
+ if (p.attestation_mode !== "live")
127
+ continue;
128
+ const d = derived.get(p.pubkey.toLowerCase()) ?? 0;
129
+ if (p.content_frontier_seq > d)
130
+ corrections.set(p.pubkey.toLowerCase(), d);
131
+ }
132
+ if (!rederived.ok)
133
+ return { status: "leaves_invalid", corrections, reason: rederived.reason };
134
+ return { status: corrections.size > 0 ? "corrected" : "verified", corrections };
135
+ }
87
136
  //# sourceMappingURL=seal-frontier-verify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seal-frontier-verify.js","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seal-frontier-verify.js","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * M8B FINDING-6 (cascade-2) — client-side bilateral upgrade of a stored seal receipt.
3
+ *
4
+ * When the previously-absent party (B) ratifies a unilateral seal and the directory confirms the
5
+ * upgrade to bilateral (seal_upgrade_confirmed, cryptographically verified via verifyUpgradeConfirmedCert),
6
+ * BOTH parties upgrade their OWN already-persisted unilateral receipt: the counterparty that was
7
+ * recorded 'absent' becomes 'recovered' (it has now ratified + proved content possession via the
8
+ * KERNEL gate). This is done CLIENT-SIDE — the directory does not persist the seal leaves/legibility
9
+ * anywhere reachable at upgrade time, so there is nothing new to ship; the bilateral receipt is built
10
+ * from the cert each party already holds. The seal signatures do NOT bind the legibility, so mutating
11
+ * the stored (unsigned) legibility invalidates nothing.
12
+ *
13
+ * Never overstates: only the attestation_mode flips (absent → recovered); frontiers are unchanged
14
+ * (the honest floor). Attestation modes: 'live' | 'recovered' | 'absent' (seal-legibility-tbs.ts).
15
+ */
16
+ /**
17
+ * Return the legibility with every participant marked 'absent' re-marked 'recovered'. Mutates in place
18
+ * and returns the same reference. Tolerant: a null/undefined/malformed legibility is returned unchanged
19
+ * rather than throwing (the caller persists whatever it had).
20
+ */
21
+ export declare function upgradeAbsentToRecovered(legibility: unknown): unknown;
22
+ /**
23
+ * True if the legibility still has any 'absent' participant — i.e. it has NOT yet been upgraded to
24
+ * bilateral (upgradeAbsentToRecovered flips the sole absent party to 'recovered'). The absent-party
25
+ * 3b persist uses this as a ONE-WAY RATCHET: a re-delivered seal_unilateral_notification (reconnect
26
+ * burst) must not overwrite an already-'recovered' stored receipt back to the stale 'absent' snapshot.
27
+ * A malformed/missing legibility returns false (nothing to protect; let the caller persist).
28
+ */
29
+ export declare function hasAbsentParticipant(legibility: unknown): boolean;
30
+ //# sourceMappingURL=seal-receipt-upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seal-receipt-upgrade.d.ts","sourceRoot":"","sources":["../src/seal-receipt-upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAUrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAOjE"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * M8B FINDING-6 (cascade-2) — client-side bilateral upgrade of a stored seal receipt.
3
+ *
4
+ * When the previously-absent party (B) ratifies a unilateral seal and the directory confirms the
5
+ * upgrade to bilateral (seal_upgrade_confirmed, cryptographically verified via verifyUpgradeConfirmedCert),
6
+ * BOTH parties upgrade their OWN already-persisted unilateral receipt: the counterparty that was
7
+ * recorded 'absent' becomes 'recovered' (it has now ratified + proved content possession via the
8
+ * KERNEL gate). This is done CLIENT-SIDE — the directory does not persist the seal leaves/legibility
9
+ * anywhere reachable at upgrade time, so there is nothing new to ship; the bilateral receipt is built
10
+ * from the cert each party already holds. The seal signatures do NOT bind the legibility, so mutating
11
+ * the stored (unsigned) legibility invalidates nothing.
12
+ *
13
+ * Never overstates: only the attestation_mode flips (absent → recovered); frontiers are unchanged
14
+ * (the honest floor). Attestation modes: 'live' | 'recovered' | 'absent' (seal-legibility-tbs.ts).
15
+ */
16
+ /**
17
+ * Return the legibility with every participant marked 'absent' re-marked 'recovered'. Mutates in place
18
+ * and returns the same reference. Tolerant: a null/undefined/malformed legibility is returned unchanged
19
+ * rather than throwing (the caller persists whatever it had).
20
+ */
21
+ export function upgradeAbsentToRecovered(legibility) {
22
+ if (!legibility || typeof legibility !== "object")
23
+ return legibility;
24
+ const participants = legibility.participants;
25
+ if (!Array.isArray(participants))
26
+ return legibility;
27
+ for (const p of participants) {
28
+ if (p && typeof p === "object" && p.attestation_mode === "absent") {
29
+ p.attestation_mode = "recovered";
30
+ }
31
+ }
32
+ return legibility;
33
+ }
34
+ /**
35
+ * True if the legibility still has any 'absent' participant — i.e. it has NOT yet been upgraded to
36
+ * bilateral (upgradeAbsentToRecovered flips the sole absent party to 'recovered'). The absent-party
37
+ * 3b persist uses this as a ONE-WAY RATCHET: a re-delivered seal_unilateral_notification (reconnect
38
+ * burst) must not overwrite an already-'recovered' stored receipt back to the stale 'absent' snapshot.
39
+ * A malformed/missing legibility returns false (nothing to protect; let the caller persist).
40
+ */
41
+ export function hasAbsentParticipant(legibility) {
42
+ if (!legibility || typeof legibility !== "object")
43
+ return false;
44
+ const participants = legibility.participants;
45
+ if (!Array.isArray(participants))
46
+ return false;
47
+ return participants.some((p) => p && typeof p === "object" && p.attestation_mode === "absent");
48
+ }
49
+ //# sourceMappingURL=seal-receipt-upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seal-receipt-upgrade.js","sourceRoot":"","sources":["../src/seal-receipt-upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAmB;IAC1D,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC;IACrE,MAAM,YAAY,GAAI,UAAyC,CAAC,YAAY,CAAC;IAC7E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAAE,OAAO,UAAU,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAAoC,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YACrG,CAAkC,CAAC,gBAAgB,GAAG,WAAW,CAAC;QACrE,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAmB;IACtD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,YAAY,GAAI,UAAyC,CAAC,YAAY,CAAC;IAC7E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,YAAY,CAAC,IAAI,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAAoC,CAAC,gBAAgB,KAAK,QAAQ,CACzG,CAAC;AACJ,CAAC"}
@@ -341,6 +341,17 @@ export declare class SessionNodeManager {
341
341
  * live return path. The legibility content is identical regardless of delivery timing.
342
342
  */
343
343
  recordSealCertificate(agentName: string, sessionId: string, sealedRootHex: string, legibilityJson: string): void;
344
+ /**
345
+ * M8B FINDING-6 (cascade-2): persist a seal certificate for a session that may have NO local
346
+ * `sessions` row. recordSealCertificate above is an `UPDATE ... WHERE` — a SILENT no-op when the
347
+ * row is absent (the exact trap the cascade-2 reviewer flagged). The ABSENT party (B), learning of
348
+ * a seal on reconnect via seal_unilateral_notification, may never have persisted a row for this
349
+ * session. This ensures a minimal stub row first (INSERT OR IGNORE — a no-op if a row already
350
+ * exists, e.g. an 'interrupted' row after a restart) so B's receipt is actually durable + retrievable
351
+ * via cello_get_sealed_receipt. The counterparty pubkey is required by the schema (NOT NULL); B
352
+ * derives it from the notification's present_pubkey.
353
+ */
354
+ recordSealCertificateEnsuringRow(agentName: string, sessionId: string, counterpartyPubkeyHex: string, sealedRootHex: string, legibilityJson: string): void;
344
355
  /**
345
356
  * M7 legibility-TBS-binding (responder verify): record the counterparty's FROST primary (group)
346
357
  * pubkey from the FROST-signed SessionAssignment, so the responder can VERIFY the bilateral seal
@@ -1 +1 @@
1
- {"version":3,"file":"session-node-manager.d.ts","sourceRoot":"","sources":["../src/session-node-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-node-manager.d.ts","sourceRoot":"","sources":["../src/session-node-manager.ts"],"names":[],"mappings":"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"}
@@ -1267,6 +1267,27 @@ export class SessionNodeManager {
1267
1267
  .prepare("UPDATE sessions SET seal_legibility = ?, sealed_root_hex = ?, updated_at = ? WHERE agent_name = ? AND session_id = ?")
1268
1268
  .run(legibilityJson, sealedRootHex, Date.now(), agentName, sessionId);
1269
1269
  }
1270
+ /**
1271
+ * M8B FINDING-6 (cascade-2): persist a seal certificate for a session that may have NO local
1272
+ * `sessions` row. recordSealCertificate above is an `UPDATE ... WHERE` — a SILENT no-op when the
1273
+ * row is absent (the exact trap the cascade-2 reviewer flagged). The ABSENT party (B), learning of
1274
+ * a seal on reconnect via seal_unilateral_notification, may never have persisted a row for this
1275
+ * session. This ensures a minimal stub row first (INSERT OR IGNORE — a no-op if a row already
1276
+ * exists, e.g. an 'interrupted' row after a restart) so B's receipt is actually durable + retrievable
1277
+ * via cello_get_sealed_receipt. The counterparty pubkey is required by the schema (NOT NULL); B
1278
+ * derives it from the notification's present_pubkey.
1279
+ */
1280
+ recordSealCertificateEnsuringRow(agentName, sessionId, counterpartyPubkeyHex, sealedRootHex, legibilityJson) {
1281
+ if (!this.#db)
1282
+ return;
1283
+ const now = Date.now();
1284
+ this.#db
1285
+ .prepare(`INSERT OR IGNORE INTO sessions
1286
+ (session_id, agent_name, counterparty_pubkey, status, created_at, updated_at)
1287
+ VALUES (?, ?, ?, ?, ?, ?)`)
1288
+ .run(sessionId, agentName, counterpartyPubkeyHex, "sealed", now, now);
1289
+ this.recordSealCertificate(agentName, sessionId, sealedRootHex, legibilityJson);
1290
+ }
1270
1291
  /**
1271
1292
  * M7 legibility-TBS-binding (responder verify): record the counterparty's FROST primary (group)
1272
1293
  * pubkey from the FROST-signed SessionAssignment, so the responder can VERIFY the bilateral seal