@cello-protocol/daemon 0.0.35 → 0.0.37
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/daemon.d.ts.map +1 -1
- package/dist/daemon.js +32 -7
- package/dist/daemon.js.map +1 -1
- package/dist/network-directory-node.d.ts +6 -1
- package/dist/network-directory-node.d.ts.map +1 -1
- package/dist/network-directory-node.js +40 -5
- package/dist/network-directory-node.js.map +1 -1
- package/dist/registration-manager.d.ts.map +1 -1
- package/dist/registration-manager.js +1 -0
- package/dist/registration-manager.js.map +1 -1
- package/dist/session-ceremony.d.ts +6 -0
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +2 -1
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-node-manager.d.ts +3 -2
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +8 -3
- package/dist/session-node-manager.js.map +1 -1
- package/package.json +3 -3
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,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAO/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;AA2CD,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAsB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAO/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;AA2CD,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAw9K7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -559,6 +559,7 @@ export async function startDaemon(config) {
|
|
|
559
559
|
agentName,
|
|
560
560
|
persistence: getPersistence(agentName),
|
|
561
561
|
agentPubkeyHex,
|
|
562
|
+
keyProvider: agentKeyProvider,
|
|
562
563
|
getNode: entry.getNode,
|
|
563
564
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
564
565
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -570,6 +571,7 @@ export async function startDaemon(config) {
|
|
|
570
571
|
agentName,
|
|
571
572
|
persistence: getPersistence(agentName),
|
|
572
573
|
agentPubkeyHex,
|
|
574
|
+
keyProvider: agentKeyProvider,
|
|
573
575
|
getNode: entry.getNode,
|
|
574
576
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
575
577
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -637,6 +639,7 @@ export async function startDaemon(config) {
|
|
|
637
639
|
agentName: agent.name,
|
|
638
640
|
persistence: getPersistence(agent.name),
|
|
639
641
|
agentPubkeyHex: agent.pubkey,
|
|
642
|
+
keyProvider: agent.keyProvider,
|
|
640
643
|
getNode: getDirectoryNode,
|
|
641
644
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
642
645
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -647,6 +650,7 @@ export async function startDaemon(config) {
|
|
|
647
650
|
agentName: agent.name,
|
|
648
651
|
persistence: getPersistence(agent.name),
|
|
649
652
|
agentPubkeyHex: agent.pubkey,
|
|
653
|
+
keyProvider: agent.keyProvider,
|
|
650
654
|
getNode: getDirectoryNode,
|
|
651
655
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
652
656
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -1143,6 +1147,7 @@ export async function startDaemon(config) {
|
|
|
1143
1147
|
agentName,
|
|
1144
1148
|
persistence: getPersistence(agentName),
|
|
1145
1149
|
agentPubkeyHex,
|
|
1150
|
+
keyProvider: agentKeyProvider,
|
|
1146
1151
|
getNode: () => nodeRef,
|
|
1147
1152
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
1148
1153
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -1159,6 +1164,7 @@ export async function startDaemon(config) {
|
|
|
1159
1164
|
agentName,
|
|
1160
1165
|
persistence: getPersistence(agentName),
|
|
1161
1166
|
agentPubkeyHex,
|
|
1167
|
+
keyProvider: agentKeyProvider,
|
|
1162
1168
|
getNode: () => nodeRef,
|
|
1163
1169
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
1164
1170
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -1559,13 +1565,19 @@ export async function startDaemon(config) {
|
|
|
1559
1565
|
// no background timer). A session the standing receiver opened from an inbound offer the initiator
|
|
1560
1566
|
// ABANDONED stays "active" forever (the counterparty never joins), clutters the open/active lists, and
|
|
1561
1567
|
// its normal close fires an unsealable bilateral seal. Mark such a session terminal ("abandoned") once
|
|
1562
|
-
// it is PROVABLY dead:
|
|
1563
|
-
//
|
|
1564
|
-
//
|
|
1568
|
+
// it is PROVABLY dead: counterparty never established (liveness != "alive" AND 0 RECEIVED messages —
|
|
1569
|
+
// message_count alone counts our own auto-"Dispatched." ack, so it is NOT the signal) + age past the
|
|
1570
|
+
// grace TTL (a genuinely fresh session still setting up must survive).
|
|
1571
|
+
// CC-10 (live 2026-07-08 Phase-2 block): scan 'interrupted' too, not just 'active'. A daemon restart
|
|
1572
|
+
// flips dead half-opens to 'interrupted'; those classify as "failed" (invisible in every list) yet
|
|
1573
|
+
// still count toward the unknown-sender acceptance bound (D18 deliberately counts 'interrupted') — so
|
|
1574
|
+
// a stranger whose first handshakes died was silently locked out FOREVER. Reaping only 0-RECEIVED
|
|
1575
|
+
// ghosts keeps D18 intact: the disconnect-evasion attacker's sessions always carry received content.
|
|
1565
1576
|
const HALF_OPEN_TTL_MS = Number(process.env["CELLO_HALF_OPEN_TTL_MS"]) || 5 * 60 * 1000;
|
|
1566
1577
|
function reapDeadHalfOpenSessions(agentName) {
|
|
1567
1578
|
const now = Date.now();
|
|
1568
|
-
|
|
1579
|
+
const candidates = [...sessionNodeManager.getSessionsByStatus("active"), ...sessionNodeManager.getSessionsByStatus("interrupted")];
|
|
1580
|
+
for (const row of candidates) {
|
|
1569
1581
|
if (agentName !== undefined && row.agent_name !== agentName)
|
|
1570
1582
|
continue;
|
|
1571
1583
|
if (now - row.created_at <= HALF_OPEN_TTL_MS)
|
|
@@ -1575,11 +1587,18 @@ export async function startDaemon(config) {
|
|
|
1575
1587
|
if (sessionNodeManager.countReceivedMessages(row.agent_name, row.session_id) > 0)
|
|
1576
1588
|
continue; // counterparty spoke
|
|
1577
1589
|
// Non-awaited: abandonSession flips the DB status synchronously (before its first await), so THIS
|
|
1578
|
-
// read reflects it; the async node teardown finishes in the background.
|
|
1579
|
-
|
|
1590
|
+
// read reflects it; the async node teardown finishes in the background. CC-10 reviewer LOW: only
|
|
1591
|
+
// log "reaped" if the status flip actually wrote — a swallowed write failure already logs
|
|
1592
|
+
// session.status.write.failed, and reporting success over it would hide a still-counting ghost.
|
|
1593
|
+
void sessionNodeManager.abandonSession(row.agent_name, row.session_id)
|
|
1594
|
+
.then((flipped) => {
|
|
1595
|
+
if (flipped) {
|
|
1596
|
+
logger.info("session.half_open.reaped", { agentName: row.agent_name, sessionId: row.session_id, priorStatus: row.status, ageMs: now - row.created_at });
|
|
1597
|
+
}
|
|
1598
|
+
})
|
|
1599
|
+
.catch((err) => {
|
|
1580
1600
|
logger.warn("session.half_open.reap.failed", { agentName: row.agent_name, sessionId: row.session_id, reason: err instanceof Error ? err.message : String(err) });
|
|
1581
1601
|
});
|
|
1582
|
-
logger.info("session.half_open.reaped", { agentName: row.agent_name, sessionId: row.session_id, ageMs: now - row.created_at });
|
|
1583
1602
|
}
|
|
1584
1603
|
}
|
|
1585
1604
|
// M8B F16: per-session liveness for ACTIVE sessions, shared by both status surfaces
|
|
@@ -2707,6 +2726,7 @@ export async function startDaemon(config) {
|
|
|
2707
2726
|
agentName,
|
|
2708
2727
|
persistence: getPersistence(agentName),
|
|
2709
2728
|
agentPubkeyHex: loaded.pubkey,
|
|
2729
|
+
keyProvider: loaded.keyProvider,
|
|
2710
2730
|
getNode: entry.getNode,
|
|
2711
2731
|
getDirectoryEndpoint: getFailoverEndpoint,
|
|
2712
2732
|
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
@@ -4044,6 +4064,11 @@ export async function startDaemon(config) {
|
|
|
4044
4064
|
// senders — a per-sender cap (many sessions from ONE stranger) and a global cap (many
|
|
4045
4065
|
// sessions across ALL strangers combined). Known contacts are exempt ("bounded only by
|
|
4046
4066
|
// disk" — DoD). Checked FIRST, before any standing-receiver work, so a refusal is cheap.
|
|
4067
|
+
// CC-10: reap provably-dead ghosts for THIS agent before counting — otherwise invisible
|
|
4068
|
+
// interrupted 0-received sessions (post-restart shape) consume the sender's budget forever
|
|
4069
|
+
// and lock the stranger out with no list read ever clearing them. Safe here: abandonSession
|
|
4070
|
+
// flips the DB status synchronously, so the bound query below sees the reaped state.
|
|
4071
|
+
reapDeadHalfOpenSessions(agentName);
|
|
4047
4072
|
const bound = sessionNodeManager.checkUnknownSenderAcceptanceBound(agentName, parsed.participantAPubkeyHex);
|
|
4048
4073
|
if (!bound.ok) {
|
|
4049
4074
|
logger.warn("session.inbound.accept.failed", {
|