@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.
- package/dist/bin/cello-daemon.js +5 -1
- package/dist/bin/cello-daemon.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +176 -12
- package/dist/daemon.js.map +1 -1
- package/dist/directory-bootstrap.d.ts +65 -0
- package/dist/directory-bootstrap.d.ts.map +1 -1
- package/dist/directory-bootstrap.js +105 -2
- package/dist/directory-bootstrap.js.map +1 -1
- package/dist/seal-frontier-verify.d.ts +45 -0
- package/dist/seal-frontier-verify.d.ts.map +1 -1
- package/dist/seal-frontier-verify.js +49 -0
- package/dist/seal-frontier-verify.js.map +1 -1
- package/dist/seal-receipt-upgrade.d.ts +30 -0
- package/dist/seal-receipt-upgrade.d.ts.map +1 -0
- package/dist/seal-receipt-upgrade.js +49 -0
- package/dist/seal-receipt-upgrade.js.map +1 -0
- package/dist/session-node-manager.d.ts +11 -0
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +21 -0
- package/dist/session-node-manager.js.map +1 -1
- package/package.json +2 -2
package/dist/bin/cello-daemon.js
CHANGED
|
@@ -100,7 +100,11 @@ async function main() {
|
|
|
100
100
|
// discovers the directory endpoint via GET ${CELLO_DIRECTORY_URL}/bootstrap (the
|
|
101
101
|
// proven M6 path); startDaemon builds the real signalingConnect from it + the
|
|
102
102
|
// primary agent identity.
|
|
103
|
-
|
|
103
|
+
// FINDING-4: this resolver is wrapped by the daemon's roster-aware failover resolver, which owns
|
|
104
|
+
// ALL fallback semantics (roster + sticky). staleFallback:false makes it report a dead primary as
|
|
105
|
+
// null on a fresh /bootstrap failure — WITHOUT it, the wrapper would keep receiving the stale dead
|
|
106
|
+
// endpoint and never fail over (the exact live kill-primary bug). The roster is the real fallback.
|
|
107
|
+
const directoryEndpointResolver = createDirectoryEndpointResolver({ logger, staleFallback: false });
|
|
104
108
|
// M7 J-AUTH (DOD-AUTH-1/2): the consortium-manifest hardening is OPT-IN. When the
|
|
105
109
|
// operator (or the live harness) configures a manifest, the daemon loads + verifies
|
|
106
110
|
// it (threshold officer signatures + validity window) and verifies the directory's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cello-daemon.js","sourceRoot":"","sources":["../../src/bin/cello-daemon.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cello-daemon.js","sourceRoot":"","sources":["../../src/bin/cello-daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EASrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EASrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAM/G,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA0InF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;;;;;OAQG;IACH,gBAAgB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;CACtC;AAyCD,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAwwI7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -45,6 +45,7 @@ import { DbRegistrationPersistence, DbIdentityStore } from "./db-identity-store.
|
|
|
45
45
|
import { DbManifestVersionStore } from "./manifest-version-store-db.js";
|
|
46
46
|
import { verify as ed25519Verify, sealToRecipient, generateKLocalSeed, InMemoryKeyProvider, hash as cryptoHash } from "@cello-protocol/crypto";
|
|
47
47
|
import { attemptSealUpgrade as attemptSealUpgradeImpl, verifyUpgradeConfirmedCert } from "./seal-upgrade.js";
|
|
48
|
+
import { upgradeAbsentToRecovered, hasAbsentParticipant } from "./seal-receipt-upgrade.js";
|
|
48
49
|
// CELLO-M7-MSG-001 (AC-013/AC-018): the single application content-size cap, enforced
|
|
49
50
|
// at the send point here (the receive point lives in the transport content decode).
|
|
50
51
|
import { MAX_CONTENT_BYTES, computeGenesisPrevRoot, buildAgentRevocationTbs } from "@cello-protocol/protocol-types";
|
|
@@ -52,10 +53,10 @@ import { resolveCelloEnv, createTransportSelector, isProductionVariant, } from "
|
|
|
52
53
|
import { selectAdvertisedAddress } from "./transport-selector.js";
|
|
53
54
|
import { parseSessionAssignment, sessionRequestErrorReason } from "./session-assignment-parser.js";
|
|
54
55
|
import { wireSessionCeremonyHandler, wireSessionOfferHandler, wireSealCeremonyHandler, verifyUnilateralCertificate, verifyBilateralSealCertificate, runAgentRefresh } from "./session-ceremony.js";
|
|
55
|
-
import { reDeriveFrontiers, findInflatedFrontier } from "./seal-frontier-verify.js";
|
|
56
|
+
import { reDeriveFrontiers, findInflatedFrontier, checkUnilateralFrontier } from "./seal-frontier-verify.js";
|
|
56
57
|
import { LocalAutoNatStub } from "@cello-protocol/transport";
|
|
57
58
|
import { startHttpManifestPoll } from "./http-manifest-poll.js";
|
|
58
|
-
import { resolveDirectoryUrl, manifestNodesToEndpoints } from "./directory-bootstrap.js";
|
|
59
|
+
import { resolveDirectoryUrl, manifestNodesToEndpoints, createRosterAwareEndpointResolver, } from "./directory-bootstrap.js";
|
|
59
60
|
/**
|
|
60
61
|
* M7-SESSION-001 (H-1): canonical byte encoding of a SEAL-INTERRUPTED leaf for
|
|
61
62
|
* Ed25519 signing/verification. Field order is fixed and deterministic. Both the
|
|
@@ -330,6 +331,25 @@ export async function startDaemon(config) {
|
|
|
330
331
|
const m = manifestProvider?.getCurrentManifest();
|
|
331
332
|
return m ? await manifestNodesToEndpoints(m.nodes, { logger }) : null;
|
|
332
333
|
};
|
|
334
|
+
// FINDING-4: roster-aware directory failover (bootstrap SPOF fix). The injected
|
|
335
|
+
// directoryEndpointResolver only ever probes the single configured node (CELLO_DIRECTORY_URL),
|
|
336
|
+
// so a down primary stranded the client at startup even though it held the other nodes'
|
|
337
|
+
// addresses. Wrap it with the consortium roster so the signaling dialer — and the ceremony
|
|
338
|
+
// endpoint that shares this same instance — route AROUND a down primary (primary-first,
|
|
339
|
+
// sticky-until-fail, randomized fallback), honoring the sovereign-node REDUNDANCY invariant.
|
|
340
|
+
// ONE instance → shared sticky state so signaling + ceremonies stay on the SAME directory node
|
|
341
|
+
// and fail over together. Undefined on the in-process test path (no directoryEndpointResolver),
|
|
342
|
+
// where the shared manager uses an injected signalingConnect instead.
|
|
343
|
+
const failoverEndpointResolver = directoryEndpointResolver
|
|
344
|
+
? createRosterAwareEndpointResolver({
|
|
345
|
+
primaryResolver: directoryEndpointResolver,
|
|
346
|
+
getConsortiumRoster: resolveConsortiumRoster,
|
|
347
|
+
logger,
|
|
348
|
+
})
|
|
349
|
+
: undefined;
|
|
350
|
+
// Null-safe accessor for the ceremony/handler getDirectoryEndpoint sites (mirrors the old
|
|
351
|
+
// `directoryEndpointResolver ? ... : null` wrapper, now routed through the failover resolver).
|
|
352
|
+
const getFailoverEndpoint = async () => failoverEndpointResolver ? await failoverEndpointResolver() : null;
|
|
333
353
|
// CELLO-M7-CONN-001 (DOD-CONN-3): start the daemon-level HTTP manifest poll. It fetches
|
|
334
354
|
// ${directoryHttpUrl}/manifest, verifies the threshold signature against the locally-pinned
|
|
335
355
|
// root keys, applies anti-rollback + expiry, and adopts a newer manifest — independent of any
|
|
@@ -484,7 +504,10 @@ export async function startDaemon(config) {
|
|
|
484
504
|
if (!directoryEndpointResolver) {
|
|
485
505
|
throw new Error("getAgentSignaling: no directory endpoint resolver configured (and no shared manager)");
|
|
486
506
|
}
|
|
487
|
-
|
|
507
|
+
// FINDING-4: dial through the roster-aware failover resolver so this agent's signaling
|
|
508
|
+
// stream routes around a down primary node. (failoverEndpointResolver is defined here
|
|
509
|
+
// because it is built iff directoryEndpointResolver is — guarded non-null just above.)
|
|
510
|
+
const resolver = failoverEndpointResolver ?? directoryEndpointResolver;
|
|
488
511
|
let nodeRef = null;
|
|
489
512
|
const connect = createSignalingConnect({
|
|
490
513
|
getDirectoryEndpoint: resolver,
|
|
@@ -513,7 +536,7 @@ export async function startDaemon(config) {
|
|
|
513
536
|
persistence: getPersistence(agentName),
|
|
514
537
|
agentPubkeyHex,
|
|
515
538
|
getNode: entry.getNode,
|
|
516
|
-
getDirectoryEndpoint:
|
|
539
|
+
getDirectoryEndpoint: getFailoverEndpoint,
|
|
517
540
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
518
541
|
signaling: mgr,
|
|
519
542
|
logger,
|
|
@@ -524,7 +547,7 @@ export async function startDaemon(config) {
|
|
|
524
547
|
persistence: getPersistence(agentName),
|
|
525
548
|
agentPubkeyHex,
|
|
526
549
|
getNode: entry.getNode,
|
|
527
|
-
getDirectoryEndpoint:
|
|
550
|
+
getDirectoryEndpoint: getFailoverEndpoint,
|
|
528
551
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
529
552
|
signaling: mgr,
|
|
530
553
|
logger,
|
|
@@ -591,7 +614,7 @@ export async function startDaemon(config) {
|
|
|
591
614
|
persistence: getPersistence(agent.name),
|
|
592
615
|
agentPubkeyHex: agent.pubkey,
|
|
593
616
|
getNode: getDirectoryNode,
|
|
594
|
-
getDirectoryEndpoint:
|
|
617
|
+
getDirectoryEndpoint: getFailoverEndpoint,
|
|
595
618
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
596
619
|
signaling: mgr,
|
|
597
620
|
logger,
|
|
@@ -601,7 +624,7 @@ export async function startDaemon(config) {
|
|
|
601
624
|
persistence: getPersistence(agent.name),
|
|
602
625
|
agentPubkeyHex: agent.pubkey,
|
|
603
626
|
getNode: getDirectoryNode,
|
|
604
|
-
getDirectoryEndpoint:
|
|
627
|
+
getDirectoryEndpoint: getFailoverEndpoint,
|
|
605
628
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
606
629
|
signaling: mgr,
|
|
607
630
|
logger,
|
|
@@ -1444,9 +1467,16 @@ export async function startDaemon(config) {
|
|
|
1444
1467
|
registrationInProgress = true;
|
|
1445
1468
|
try {
|
|
1446
1469
|
// Resolve the directory endpoint once for this registration (the context's
|
|
1447
|
-
// getDirectoryEndpoint is synchronous; the daemon's resolver is async
|
|
1448
|
-
//
|
|
1449
|
-
//
|
|
1470
|
+
// getDirectoryEndpoint is synchronous; the daemon's resolver is async).
|
|
1471
|
+
// FINDING-4 scope note: this uses the PRIMARY resolver directly (not the roster-aware
|
|
1472
|
+
// failover resolver — registration is deliberately out of FINDING-4's "signaling +
|
|
1473
|
+
// ceremony" scope). Because that primary is now built with staleFallback:false (so the
|
|
1474
|
+
// failover wrapper sees a dead primary as null), a transient /bootstrap blip here resolves
|
|
1475
|
+
// to null → directory_unreachable rather than riding through on a stale last-known-good;
|
|
1476
|
+
// registration is a rare, manual, retryable op, so failing fast (retry) is acceptable. With
|
|
1477
|
+
// a manifest configured the DKG fans out over the independently-probed roster regardless of
|
|
1478
|
+
// this endpoint. The endpoint is stable for one registration — if it changed mid-flow the
|
|
1479
|
+
// DKG streams would break anyway.
|
|
1450
1480
|
const ep = await directoryEndpointResolver();
|
|
1451
1481
|
if (!ep || !ep.multiaddr) {
|
|
1452
1482
|
// FROST DKG must dial the directory's /cello/frost/1.0.0 — a dialable
|
|
@@ -1769,6 +1799,84 @@ export async function startDaemon(config) {
|
|
|
1769
1799
|
// seal still completes — surfaced loudly so this can never masquerade as a produced receipt.
|
|
1770
1800
|
const rootHex = Buffer.from(sealedRoot).toString("hex");
|
|
1771
1801
|
const legibility = normalizeLegibility(frame["legibility"]);
|
|
1802
|
+
// M8B FINDING-5 (SI-002): before persisting, INDEPENDENTLY re-derive each CLIENT-VERIFIABLE
|
|
1803
|
+
// ('live', the present party) frontier from the signed frontier_leaves and OVERRIDE an inflated
|
|
1804
|
+
// directory-published value DOWN to the provable one (the directory cannot forge signed leaves,
|
|
1805
|
+
// so the re-derived value is truth). We OVERRIDE, never reject — the unilateral seal has a
|
|
1806
|
+
// directory-side dedup guard that makes a client rejection unrecoverable (a retry close is
|
|
1807
|
+
// silently ignored → no receipt ever, worse than FINDING-3; cascade-2 reviewer Critical 2). The
|
|
1808
|
+
// absent party's frontier stays directory-attested (its remainder is not re-derivable here). No
|
|
1809
|
+
// frontier_leaves (pre-FINDING-5 directory) → the cert stays directory-attested (FINDING-3).
|
|
1810
|
+
// A receipt is ALWAYS persisted; the close never dead-ends here.
|
|
1811
|
+
if (legibility !== undefined) {
|
|
1812
|
+
const rawParticipants = legibility.participants ?? [];
|
|
1813
|
+
const guardParticipants = rawParticipants
|
|
1814
|
+
.filter((p) => typeof p.pubkey === "string" && typeof p.attestation_mode === "string")
|
|
1815
|
+
.map((p) => ({
|
|
1816
|
+
pubkey: p.pubkey,
|
|
1817
|
+
content_frontier_seq: typeof p.content_frontier_seq === "number" ? p.content_frontier_seq : 0,
|
|
1818
|
+
attestation_mode: p.attestation_mode,
|
|
1819
|
+
}));
|
|
1820
|
+
const frontierLeavesRaw = frame["frontier_leaves"];
|
|
1821
|
+
const toU8f = (v) => (v instanceof Uint8Array ? v : new Uint8Array(v));
|
|
1822
|
+
const parsedFrontierLeaves = Array.isArray(frontierLeavesRaw) && frontierLeavesRaw.length > 0
|
|
1823
|
+
? frontierLeavesRaw.map((l) => {
|
|
1824
|
+
const o = l;
|
|
1825
|
+
return {
|
|
1826
|
+
structure1_cbor: toU8f(o["structure1_cbor"]),
|
|
1827
|
+
sender_pubkey: toU8f(o["sender_pubkey"]),
|
|
1828
|
+
sender_signature: toU8f(o["sender_signature"]),
|
|
1829
|
+
};
|
|
1830
|
+
})
|
|
1831
|
+
: undefined;
|
|
1832
|
+
const check = checkUnilateralFrontier(guardParticipants, parsedFrontierLeaves, sessionId);
|
|
1833
|
+
// Apply any frontier corrections to the object we persist — override inflated 'live'
|
|
1834
|
+
// frontier(s) DOWN to the provable value, so the stored receipt never claims more than the
|
|
1835
|
+
// signed leaves support. Runs for both 'corrected' (valid leaves) and 'leaves_invalid'
|
|
1836
|
+
// (forged leaves → corrected to 0). Never rejects → the close never dead-ends.
|
|
1837
|
+
if (check.corrections.size > 0) {
|
|
1838
|
+
for (const p of rawParticipants) {
|
|
1839
|
+
if (typeof p.pubkey === "string" && check.corrections.has(p.pubkey.toLowerCase())) {
|
|
1840
|
+
p.content_frontier_seq = check.corrections.get(p.pubkey.toLowerCase());
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
if (check.status === "corrected") {
|
|
1845
|
+
logger.error("seal.certificate.frontier.overridden", {
|
|
1846
|
+
sessionId: sidHex,
|
|
1847
|
+
corrections: [...check.corrections.entries()].map(([party, seq]) => ({ party, correctedTo: seq })),
|
|
1848
|
+
path: "unilateral",
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
else if (check.status === "verified") {
|
|
1852
|
+
logger.info("seal.certificate.frontier.verified", {
|
|
1853
|
+
sessionId: sidHex,
|
|
1854
|
+
parties: guardParticipants.filter((p) => p.attestation_mode === "live").length,
|
|
1855
|
+
path: "unilateral",
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
else if (check.status === "leaves_invalid") {
|
|
1859
|
+
// Forged / cross-session leaves — a tamper signal. The 'live' frontier(s) have been
|
|
1860
|
+
// corrected to 0 above (zero trustworthy evidence); persist that (never reject → never
|
|
1861
|
+
// dead-end). Surfaced loudly for audit.
|
|
1862
|
+
logger.error("seal.certificate.frontier.leaves_invalid", {
|
|
1863
|
+
sessionId: sidHex,
|
|
1864
|
+
reason: check.reason,
|
|
1865
|
+
corrections: [...check.corrections.entries()].map(([party, seq]) => ({ party, correctedTo: seq })),
|
|
1866
|
+
path: "unilateral",
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
else {
|
|
1870
|
+
// directory_attested: no frontier_leaves shipped (pre-FINDING-5 directory). Frontiers stay
|
|
1871
|
+
// DIRECTORY-attested (already marked per-participant) — visible/auditable, never silently
|
|
1872
|
+
// presented as client-verified.
|
|
1873
|
+
logger.warn("seal.certificate.frontier.directory_attested", {
|
|
1874
|
+
sessionId: sidHex,
|
|
1875
|
+
reason: "no_frontier_leaves",
|
|
1876
|
+
path: "unilateral",
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1772
1880
|
if (legibility !== undefined) {
|
|
1773
1881
|
try {
|
|
1774
1882
|
sessionNodeManager.recordSealCertificate(agentName, sidHex, rootHex, JSON.stringify(legibility));
|
|
@@ -1819,7 +1927,7 @@ export async function startDaemon(config) {
|
|
|
1819
1927
|
return;
|
|
1820
1928
|
sealUpgradeInFlight.add(key);
|
|
1821
1929
|
try {
|
|
1822
|
-
await attemptSealUpgradeImpl({
|
|
1930
|
+
const result = await attemptSealUpgradeImpl({
|
|
1823
1931
|
logger, agentName, agentPubkeyHex,
|
|
1824
1932
|
getReadiness: (a, s) => sessionNodeManager.getSealUpgradeReadiness(a, s),
|
|
1825
1933
|
getContentLeafCount: (a, s) => sessionNodeManager.getSessionTree(a, s).size(),
|
|
@@ -1827,6 +1935,44 @@ export async function startDaemon(config) {
|
|
|
1827
1935
|
getKeyProvider: (a) => keyProviders.get(a),
|
|
1828
1936
|
sendRaw: (f) => signaling.sendRaw(f),
|
|
1829
1937
|
}, sidHex, frame);
|
|
1938
|
+
// M8B FINDING-6 (3b): the ABSENT party (B) persists its UNILATERAL receipt from the
|
|
1939
|
+
// notification's legibility — but ONLY after the KERNEL content-recovery/verify gate passed.
|
|
1940
|
+
// `result.sent` is true iff attemptSealUpgradeImpl recovered + integrity-verified the content
|
|
1941
|
+
// behind R1 and sent the ratification request; a tampered/unrecoverable/incomplete case returns
|
|
1942
|
+
// sent:false → NO receipt (never a receipt for content B could not verify). B may hold no local
|
|
1943
|
+
// `sessions` row (recordSealCertificateEnsuringRow inserts a stub, counterparty = A's pubkey).
|
|
1944
|
+
// The notification carries no frontier_leaves (FINDING-5 ships those only on the present party's
|
|
1945
|
+
// confirm frame), so B's legibility is directory-attested — consistent with FINDING-5's
|
|
1946
|
+
// directory_attested path; B trusts its own KERNEL-verified content, not a re-derivation.
|
|
1947
|
+
if (result.sent) {
|
|
1948
|
+
try {
|
|
1949
|
+
// ONE-WAY RATCHET (cascade-2 FINDING-6 review): a re-delivered seal_unilateral_notification
|
|
1950
|
+
// (reconnect burst) re-runs this path and would re-persist the notification's ORIGINAL
|
|
1951
|
+
// legibility (counterparty 'absent'). If a prior upgrade already flipped the stored receipt
|
|
1952
|
+
// to 'recovered' (no 'absent' participant), re-persisting would REGRESS it — and no later
|
|
1953
|
+
// event restores 'recovered' (the directory dedups the duplicate as already_bilateral →
|
|
1954
|
+
// seal_upgrade_rejected, which only logs). So skip the re-persist once the cert is upgraded.
|
|
1955
|
+
const existing = sessionNodeManager.getSealCertificate(agentName, sidHex);
|
|
1956
|
+
if (existing && !hasAbsentParticipant(existing.legibility)) {
|
|
1957
|
+
logger.debug("session.unilateral.receipt.persist.skipped", { sessionId: sidHex, reason: "already_upgraded" });
|
|
1958
|
+
}
|
|
1959
|
+
else {
|
|
1960
|
+
const legibility = normalizeLegibility(frame["legibility"]);
|
|
1961
|
+
const rootHex = frameValueToHex(frame["sealed_root"]);
|
|
1962
|
+
const counterpartyHex = frameValueToHex(frame["present_pubkey"]); // A — the present party
|
|
1963
|
+
if (legibility !== undefined && rootHex && counterpartyHex) {
|
|
1964
|
+
sessionNodeManager.recordSealCertificateEnsuringRow(agentName, sidHex, counterpartyHex, rootHex, JSON.stringify(legibility));
|
|
1965
|
+
logger.info("session.unilateral.receipt.persisted", { sessionId: sidHex, sealedRoot: rootHex, party: "absent" });
|
|
1966
|
+
}
|
|
1967
|
+
else if (legibility === undefined) {
|
|
1968
|
+
logger.warn("session.unilateral.receipt.absent", { sessionId: sidHex, reason: "no_legibility_on_notification" });
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
catch (error) {
|
|
1973
|
+
logger.warn("seal.certificate.persist.failed", { sessionId: sidHex, reason: error instanceof Error ? error.message : String(error) });
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1830
1976
|
}
|
|
1831
1977
|
finally {
|
|
1832
1978
|
// Clear the guard so a later reconnect can retry if the request never reached the directory;
|
|
@@ -1844,6 +1990,24 @@ export async function startDaemon(config) {
|
|
|
1844
1990
|
if (!result.ok)
|
|
1845
1991
|
return; // cert.invalid already logged inside; do NOT accept as bilateral.
|
|
1846
1992
|
logger.info("session.seal.upgraded", { sessionId: sidHex, agentName, party: result.party });
|
|
1993
|
+
// M8B FINDING-6 (3a): the seal is now BILATERAL (verified) — upgrade THIS party's own stored
|
|
1994
|
+
// receipt so the counterparty recorded 'absent' becomes 'recovered'. Client-side: the directory
|
|
1995
|
+
// ships no bilateral legibility at upgrade time (the seal leaves aren't persisted there), so each
|
|
1996
|
+
// party rebuilds from the cert it already holds — the present party's from its unilateral close
|
|
1997
|
+
// (FINDING-3), the returning party's from the notification it persisted after the KERNEL gate
|
|
1998
|
+
// (3b). The seal signatures do not bind the (unsigned) legibility, so mutating it is sound; only
|
|
1999
|
+
// the attestation flips (frontiers unchanged — never overstated). No-op if no cert is stored yet.
|
|
2000
|
+
const stored = sessionNodeManager.getSealCertificate(agentName, sidHex);
|
|
2001
|
+
if (stored) {
|
|
2002
|
+
try {
|
|
2003
|
+
const upgraded = upgradeAbsentToRecovered(stored.legibility);
|
|
2004
|
+
sessionNodeManager.recordSealCertificate(agentName, sidHex, stored.sealed_root, JSON.stringify(upgraded));
|
|
2005
|
+
logger.info("session.seal.receipt.upgraded", { sessionId: sidHex, agentName, party: result.party });
|
|
2006
|
+
}
|
|
2007
|
+
catch (error) {
|
|
2008
|
+
logger.warn("seal.certificate.persist.failed", { sessionId: sidHex, reason: error instanceof Error ? error.message : String(error) });
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
1847
2011
|
void sessionNodeManager.destroySessionNode(agentName, sidHex, "sealed");
|
|
1848
2012
|
}
|
|
1849
2013
|
/**
|
|
@@ -1901,7 +2065,7 @@ export async function startDaemon(config) {
|
|
|
1901
2065
|
persistence: getPersistence(agentName),
|
|
1902
2066
|
agentPubkeyHex: loaded.pubkey,
|
|
1903
2067
|
getNode: entry.getNode,
|
|
1904
|
-
getDirectoryEndpoint:
|
|
2068
|
+
getDirectoryEndpoint: getFailoverEndpoint,
|
|
1905
2069
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
1906
2070
|
signaling: entry.signaling,
|
|
1907
2071
|
logger,
|