@cello-protocol/daemon 0.0.179 → 0.0.181

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.
@@ -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,EAOrB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAmC,KAAK,UAAU,EAAsB,MAAM,iBAAiB,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAA6C,MAAM,2BAA2B,CAAC;AAO1G,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAiB7G,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,2BAA2B,CAAC;AAS5G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA2BnF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAYlD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;;OAKG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpE;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;IACrC;;OAEG;IACH,eAAe,IAAI,YAAY,CAAC;IAChC;;;;;;;;OAQG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACxC;AAYD,qBAAa,4BAA6B,YAAW,mBAAmB;IAChE,UAAU,CAAC,MAAM,EAAE,iBAAiB;CAuC3C;AAID,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAS7E"}
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAOrB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAmC,KAAK,UAAU,EAAsB,MAAM,iBAAiB,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAA6C,MAAM,2BAA2B,CAAC;AAO1G,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAiB7G,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,2BAA2B,CAAC;AAS5G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AA6BnF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAYlD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;;OAKG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpE;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;IACrC;;OAEG;IACH,eAAe,IAAI,YAAY,CAAC;IAChC;;;;;;;;OAQG;IACH,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACxC;AAYD,qBAAa,4BAA6B,YAAW,mBAAmB;IAChE,UAAU,CAAC,MAAM,EAAE,iBAAiB;CAuC3C;AAID,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAS7E"}
package/dist/daemon.js CHANGED
@@ -68,6 +68,8 @@ import { createSealCoordinator } from "./seal-coordinator.js";
68
68
  import { createTelegramDoorbell } from "./telegram-doorbell.js";
69
69
  import { registerSessionContentHandlers } from "./session-content-handlers.js";
70
70
  import { createDocumentLayer, agentPublicKeyFromId } from "./document-layer.js";
71
+ import { isDocumentFrame } from "./document-frame-router.js";
72
+ import { INBOUND_INJECTION_BLOCKED } from "@cello-protocol/gateway";
71
73
  import { registerDocumentHandlers } from "./document-handlers.js";
72
74
  import { wireContentHash } from "./wire-content-hash.js";
73
75
  import { DocumentPublish } from "./document-publish.js";
@@ -3629,6 +3631,63 @@ async function startDaemonHoldingLock(config, singletonLock) {
3629
3631
  const documentLayer = createDocumentLayer({
3630
3632
  db: sessionNodeManager.getDb(),
3631
3633
  logger,
3634
+ // DOD-DOC-SCREEN-CONTENT-1 — the gateway, reached with TEXT for once.
3635
+ //
3636
+ // The same program that screens conversation messages, called from the document gate's shadow
3637
+ // with the readable projected text instead of the signed binary envelope the wire carries.
3638
+ //
3639
+ // ── WHICH VERDICTS REFUSE, AND WHY IT IS NOT "ALL OF THEM" ────────────────────────────────
3640
+ //
3641
+ // ONLY the injection verdict. The gateway runs its whole inbound composition, and two of its
3642
+ // other terminal blocks must not refuse a document:
3643
+ //
3644
+ // - the LANGUAGE ALLOWLIST (default: Latin only). A shared document written in Japanese,
3645
+ // Arabic or Russian is ordinary use, and every update would be refused — permanently, since
3646
+ // the same bytes are the same language on redelivery. The allowlist exists so a jailbreak
3647
+ // phrased in a low-resource language cannot dodge English-trained screening; refusing a
3648
+ // colleague's document outright is a far worse trade than that gap, and the character
3649
+ // denylist still runs on every script.
3650
+ // - the SIZE CAP, which is the sanitizer's per-message cap and not this path's limit. The
3651
+ // gate already bounds an update and the whole document by its own numbers.
3652
+ //
3653
+ // A REDACT verdict is never honoured: rewriting one holder's replica is permanent divergence
3654
+ // both sides converge on and neither can see.
3655
+ //
3656
+ // A TRANSIENT block means the gateway is DOWN or its screener faulted. The update is admitted —
3657
+ // holding document convergence hostage to an optional layer breaks a layer that degrades by
3658
+ // design — but it is LOGGED BY NAME, because a weaker guarantee that looks identical to the
3659
+ // stronger one at every surface is how this whole class of defect survives.
3660
+ screenProjected: async (text, ctx) => {
3661
+ const verdict = await config.securityGateway.screenInbound(new TextEncoder().encode(text), {
3662
+ direction: "inbound",
3663
+ agentName: ctx.ownerAgentId,
3664
+ sessionId: ctx.documentId,
3665
+ ...(ctx.correlationId !== undefined ? { correlationId: ctx.correlationId } : {}),
3666
+ });
3667
+ if (verdict.disposition !== "block")
3668
+ return { block: false };
3669
+ if (verdict.terminal !== true) {
3670
+ logger.warn("document.inbound.screen.unavailable", {
3671
+ documentId: ctx.documentId,
3672
+ senderAgentId: ctx.senderAgentId,
3673
+ reason: verdict.reason,
3674
+ consequence: "the update was admitted WITHOUT a semantic screen",
3675
+ correlationId: ctx.correlationId,
3676
+ });
3677
+ return { block: false };
3678
+ }
3679
+ if (verdict.reason !== INBOUND_INJECTION_BLOCKED) {
3680
+ logger.info("document.inbound.screen.not_applicable", {
3681
+ documentId: ctx.documentId,
3682
+ senderAgentId: ctx.senderAgentId,
3683
+ reason: verdict.reason,
3684
+ consequence: "a terminal block this path does not apply to documents — admitted",
3685
+ correlationId: ctx.correlationId,
3686
+ });
3687
+ return { block: false };
3688
+ }
3689
+ return { block: true, reason: verdict.reason };
3690
+ },
3632
3691
  // M14-D5: a remote agent's id IS its K_local pubkey hex, so this needs no lookup — and a lookup
3633
3692
  // on the critical path of every signature check is precisely what it must not have.
3634
3693
  publicKeyFor: agentPublicKeyFromId,
@@ -3694,7 +3753,9 @@ async function startDaemonHoldingLock(config, singletonLock) {
3694
3753
  return provider.sign(tbs);
3695
3754
  },
3696
3755
  });
3697
- sessionNodeManager.setOnDocumentFrame(documentLayer.onDocumentFrame);
3756
+ // The classify-only half rides the same setter so the router and the ingest cannot disagree
3757
+ // about what a document frame is (DOD-DOC-SCREEN-CLASSIFY-1).
3758
+ sessionNodeManager.setOnDocumentFrame(documentLayer.onDocumentFrame, isDocumentFrame);
3698
3759
  // M14 / DOD-DOC-DELIVERY-2 — the outbound half, wired only now that INBOUND-2 is. The ordering
3699
3760
  // constraint on the DoD line is real and this is where it is honoured: a delivery worker with no
3700
3761
  // inbound counterpart publishes envelopes nobody can answer, so every document would stall at the