@cello-protocol/gateway 0.0.1

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 (105) hide show
  1. package/dist/bin/cello-gateway.d.ts +3 -0
  2. package/dist/bin/cello-gateway.d.ts.map +1 -0
  3. package/dist/bin/cello-gateway.js +174 -0
  4. package/dist/bin/cello-gateway.js.map +1 -0
  5. package/dist/client.d.ts +16 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +182 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/config/config-store.d.ts +42 -0
  10. package/dist/config/config-store.d.ts.map +1 -0
  11. package/dist/config/config-store.js +198 -0
  12. package/dist/config/config-store.js.map +1 -0
  13. package/dist/detect/deberta-model-manifest.d.ts +54 -0
  14. package/dist/detect/deberta-model-manifest.d.ts.map +1 -0
  15. package/dist/detect/deberta-model-manifest.js +17 -0
  16. package/dist/detect/deberta-model-manifest.js.map +1 -0
  17. package/dist/detect/exfil.d.ts +14 -0
  18. package/dist/detect/exfil.d.ts.map +1 -0
  19. package/dist/detect/exfil.js +69 -0
  20. package/dist/detect/exfil.js.map +1 -0
  21. package/dist/detect/gitleaks-rules.d.ts +18 -0
  22. package/dist/detect/gitleaks-rules.d.ts.map +1 -0
  23. package/dist/detect/gitleaks-rules.js +229 -0
  24. package/dist/detect/gitleaks-rules.js.map +1 -0
  25. package/dist/detect/injection-patterns.d.ts +10 -0
  26. package/dist/detect/injection-patterns.d.ts.map +1 -0
  27. package/dist/detect/injection-patterns.js +53 -0
  28. package/dist/detect/injection-patterns.js.map +1 -0
  29. package/dist/detect/injection-scanner.d.ts +44 -0
  30. package/dist/detect/injection-scanner.d.ts.map +1 -0
  31. package/dist/detect/injection-scanner.js +45 -0
  32. package/dist/detect/injection-scanner.js.map +1 -0
  33. package/dist/detect/language.d.ts +37 -0
  34. package/dist/detect/language.d.ts.map +1 -0
  35. package/dist/detect/language.js +85 -0
  36. package/dist/detect/language.js.map +1 -0
  37. package/dist/detect/linear-regex.d.ts +20 -0
  38. package/dist/detect/linear-regex.d.ts.map +1 -0
  39. package/dist/detect/linear-regex.js +70 -0
  40. package/dist/detect/linear-regex.js.map +1 -0
  41. package/dist/detect/model-installer.d.ts +32 -0
  42. package/dist/detect/model-installer.d.ts.map +1 -0
  43. package/dist/detect/model-installer.js +94 -0
  44. package/dist/detect/model-installer.js.map +1 -0
  45. package/dist/detect/pii.d.ts +27 -0
  46. package/dist/detect/pii.d.ts.map +1 -0
  47. package/dist/detect/pii.js +119 -0
  48. package/dist/detect/pii.js.map +1 -0
  49. package/dist/detect/rate-limit.d.ts +44 -0
  50. package/dist/detect/rate-limit.d.ts.map +1 -0
  51. package/dist/detect/rate-limit.js +56 -0
  52. package/dist/detect/rate-limit.js.map +1 -0
  53. package/dist/detect/sanitize.d.ts +50 -0
  54. package/dist/detect/sanitize.d.ts.map +1 -0
  55. package/dist/detect/sanitize.js +211 -0
  56. package/dist/detect/sanitize.js.map +1 -0
  57. package/dist/detect/secrets.d.ts +20 -0
  58. package/dist/detect/secrets.d.ts.map +1 -0
  59. package/dist/detect/secrets.js +104 -0
  60. package/dist/detect/secrets.js.map +1 -0
  61. package/dist/index.d.ts +38 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +25 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/passthrough.d.ts +18 -0
  66. package/dist/passthrough.d.ts.map +1 -0
  67. package/dist/passthrough.js +21 -0
  68. package/dist/passthrough.js.map +1 -0
  69. package/dist/protocol.d.ts +53 -0
  70. package/dist/protocol.d.ts.map +1 -0
  71. package/dist/protocol.js +52 -0
  72. package/dist/protocol.js.map +1 -0
  73. package/dist/records/record-store.d.ts +28 -0
  74. package/dist/records/record-store.d.ts.map +1 -0
  75. package/dist/records/record-store.js +134 -0
  76. package/dist/records/record-store.js.map +1 -0
  77. package/dist/screen/inbound.d.ts +29 -0
  78. package/dist/screen/inbound.d.ts.map +1 -0
  79. package/dist/screen/inbound.js +127 -0
  80. package/dist/screen/inbound.js.map +1 -0
  81. package/dist/screen/inbound.test.d.ts +2 -0
  82. package/dist/screen/inbound.test.d.ts.map +1 -0
  83. package/dist/screen/inbound.test.js +49 -0
  84. package/dist/screen/inbound.test.js.map +1 -0
  85. package/dist/screen/outbound.d.ts +57 -0
  86. package/dist/screen/outbound.d.ts.map +1 -0
  87. package/dist/screen/outbound.js +183 -0
  88. package/dist/screen/outbound.js.map +1 -0
  89. package/dist/screen/outbound.test.d.ts +2 -0
  90. package/dist/screen/outbound.test.d.ts.map +1 -0
  91. package/dist/screen/outbound.test.js +62 -0
  92. package/dist/screen/outbound.test.js.map +1 -0
  93. package/dist/server.d.ts +34 -0
  94. package/dist/server.d.ts.map +1 -0
  95. package/dist/server.js +129 -0
  96. package/dist/server.js.map +1 -0
  97. package/dist/spawn.d.ts +32 -0
  98. package/dist/spawn.d.ts.map +1 -0
  99. package/dist/spawn.js +84 -0
  100. package/dist/spawn.js.map +1 -0
  101. package/dist/types.d.ts +121 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +39 -0
  104. package/dist/types.js.map +1 -0
  105. package/package.json +42 -0
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @cello-protocol/gateway — the security gateway contract.
3
+ *
4
+ * The gateway is a SEPARATE program from the daemon (M9-CORE-001 / V3 split-deployment).
5
+ * The daemon holds ONLY this interface and its two call sites; all detection lives in the
6
+ * gateway program. The same interface backs both the local sidecar (Phase 1) and the
7
+ * remote mTLS gateway (Phase 2) — Phase 2 is a transport swap behind `SecurityGatewayClient`,
8
+ * not a rewrite.
9
+ *
10
+ * M9-CORE-001 implements the seam with a pass-through: every message is screened (the call
11
+ * happens at the two fixed points) but the verdict is always `allow`, except the fail-closed
12
+ * `block` a configured-but-unreachable gateway returns. Detectors and the redact/warn
13
+ * dispositions arrive in later stories (M9-IN-*, M9-OUT-*, M9-FEED-001).
14
+ */
15
+ /** Which direction the content is flowing relative to the daemon. */
16
+ export type ScreenDirection = "outbound" | "inbound";
17
+ /**
18
+ * What the gateway decided to do with a message.
19
+ *
20
+ * - `allow` — deliver/send as-is (or as transformed via `content`).
21
+ * - `block` — do not deliver/send. M9-CORE-001 uses this only for fail-closed
22
+ * (`gateway_unavailable`); detectors add real blocks later.
23
+ * - `redact` — deliver/send a transformed `content` (M9-OUT-* / M9-FEED-001).
24
+ * - `warn` — held pending an explicit governance decision (M9-FEED-001).
25
+ *
26
+ * M9-CORE-001 only ever returns `allow` or `block`; `redact`/`warn` are declared here so the
27
+ * seam code that switches on the disposition is complete from the start.
28
+ */
29
+ export type ScreenDisposition = "allow" | "block" | "redact" | "warn";
30
+ /** The per-stage governance disposition (the §6 model: advisory, mutating, needs-decision, blocking). */
31
+ export type GovernanceDisposition = "observe" | "redact" | "block" | "warn";
32
+ /**
33
+ * A governance decision the agent attaches to a re-send to resolve a warned item (M9-FEED-001 §6):
34
+ * - `redact` — send with a typed placeholder. Always available (the agent's autonomous lever).
35
+ * - `allow_once` — send the value verbatim THIS once. Honored ONLY when `autonomous_override` is
36
+ * ON; OFF (default) → rejected + re-warned (the operator must whitelist).
37
+ * - `allow_always` — persist the value to the whitelist (a config loosening → a human action:
38
+ * WebAuthn-confirmed + attested). Autonomous mode degrades to `allow_once` for
39
+ * THIS send and raises an operator whitelist-add request; OFF → rejected.
40
+ */
41
+ export type GovernanceDecision = "redact" | "allow_once" | "allow_always";
42
+ /**
43
+ * One governance finding published by a screen stage (§6). The verdict aggregates these; the daemon
44
+ * renders them to the agent (M9-FEED-001) — as the transformations on a redact, the reasons on a
45
+ * block, or the flagged items (with `flagId`) on a warn.
46
+ */
47
+ export interface GovernanceEvent {
48
+ stage: string;
49
+ disposition: GovernanceDisposition;
50
+ category: string;
51
+ reason: string;
52
+ /** Deterministic handle the agent passes on a governance re-send (warn items). */
53
+ flagId?: string;
54
+ }
55
+ /** Context the daemon passes with each screen request. Identity-scoped, never content-derived. */
56
+ export interface ScreenContext {
57
+ direction: ScreenDirection;
58
+ agentName: string;
59
+ sessionId: string;
60
+ /** The async-flow correlation id, threaded through every event in this send/receive (INV-7). */
61
+ correlationId?: string;
62
+ /**
63
+ * The agent's per-item decisions on a governance RE-SEND (M9-FEED-001 §6), keyed by the `flagId`
64
+ * the prior `warn` verdict returned. Stateless: the gateway re-scans the (full) content, re-derives
65
+ * the same deterministic flagIds, and applies these decisions. A flagId that no longer matches
66
+ * (content changed) is ignored and that item re-warns/redacts — a decision can never mis-apply to
67
+ * different content (SI-002). Omitted flags default to `redact`. Outbound only.
68
+ */
69
+ governanceDecisions?: Record<string, GovernanceDecision>;
70
+ }
71
+ /**
72
+ * A screening verdict.
73
+ *
74
+ * `content` is the bytes the daemon should act on: for `allow` it equals the input; for
75
+ * `redact` it is the transformed form; for `block`/`warn` it is absent (nothing is
76
+ * delivered/sent). `reason` is a stable machine code; `guidance` is actionable text the
77
+ * agent sees on a non-allow outcome (INV-7).
78
+ */
79
+ export interface ScreenVerdict {
80
+ disposition: ScreenDisposition;
81
+ content?: Uint8Array;
82
+ reason?: string;
83
+ guidance?: string;
84
+ /** The governance findings behind this verdict (M9-FEED-001 renders them to the agent). */
85
+ events?: GovernanceEvent[];
86
+ /**
87
+ * Set on a `block` whose cause is the CONTENT itself — a detector rejected these exact bytes
88
+ * (inbound: a confident non-allowlisted language, a high-score injection; outbound likewise).
89
+ * Such a block is TERMINAL: redelivering the identical bytes would be rejected identically, so the
90
+ * inbound daemon must record the leaf + acknowledge (the sender stops) while never delivering it,
91
+ * NOT leave it un-acked for redelivery. A fail-closed block (`gateway_unavailable` /
92
+ * `governance_timeout`) and an internal `screen_error` are TRANSIENT — `terminal` is left unset so
93
+ * the daemon holds the content un-acked and the sender redelivers once the gateway recovers.
94
+ */
95
+ terminal?: boolean;
96
+ }
97
+ /**
98
+ * The narrow interface the daemon holds. Two methods, two seams:
99
+ * - `screenOutbound` runs in `cello_send` before `sessionNodeManager.sendContent`.
100
+ * - `screenInbound` runs in the inbound funnel before content enters the receive buffer.
101
+ *
102
+ * Implementations MUST be non-hanging: every call resolves to a terminal verdict within a
103
+ * deadline. A timeout or unreachable gateway resolves to a fail-closed `block`
104
+ * (`gateway_unavailable`), never a rejected/never-settling promise (INV-6 / SI-001).
105
+ */
106
+ export interface SecurityGatewayClient {
107
+ screenOutbound(content: Uint8Array, ctx: ScreenContext): Promise<ScreenVerdict>;
108
+ screenInbound(content: Uint8Array, ctx: ScreenContext): Promise<ScreenVerdict>;
109
+ }
110
+ /** The reason code a fail-closed verdict carries when the gateway cannot be reached. */
111
+ export declare const GATEWAY_UNAVAILABLE = "gateway_unavailable";
112
+ /** The reason a fail-closed verdict carries when the gateway is reachable but the screening
113
+ * deadline was exceeded — a timeout is a verdict, not a hang (INV-6 / FEED-001 AC-005). */
114
+ export declare const GOVERNANCE_TIMEOUT = "governance_timeout";
115
+ /**
116
+ * Build the fail-closed verdict (SI-001 / DB-001 / INV-6): never deliver/send ungated content, never
117
+ * hang. `reason` distinguishes "could not connect" (`gateway_unavailable`) from "connected but the
118
+ * screening deadline elapsed" (`governance_timeout`).
119
+ */
120
+ export declare function failClosedVerdict(direction: ScreenDirection, reason?: string): ScreenVerdict;
121
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtE,yGAAyG;AACzG,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,qBAAqB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC1D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAChF,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAChF;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD;4FAC4F;AAC5F,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,GAAE,MAA4B,GAAG,aAAa,CAcjH"}
package/dist/types.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @cello-protocol/gateway — the security gateway contract.
3
+ *
4
+ * The gateway is a SEPARATE program from the daemon (M9-CORE-001 / V3 split-deployment).
5
+ * The daemon holds ONLY this interface and its two call sites; all detection lives in the
6
+ * gateway program. The same interface backs both the local sidecar (Phase 1) and the
7
+ * remote mTLS gateway (Phase 2) — Phase 2 is a transport swap behind `SecurityGatewayClient`,
8
+ * not a rewrite.
9
+ *
10
+ * M9-CORE-001 implements the seam with a pass-through: every message is screened (the call
11
+ * happens at the two fixed points) but the verdict is always `allow`, except the fail-closed
12
+ * `block` a configured-but-unreachable gateway returns. Detectors and the redact/warn
13
+ * dispositions arrive in later stories (M9-IN-*, M9-OUT-*, M9-FEED-001).
14
+ */
15
+ /** The reason code a fail-closed verdict carries when the gateway cannot be reached. */
16
+ export const GATEWAY_UNAVAILABLE = "gateway_unavailable";
17
+ /** The reason a fail-closed verdict carries when the gateway is reachable but the screening
18
+ * deadline was exceeded — a timeout is a verdict, not a hang (INV-6 / FEED-001 AC-005). */
19
+ export const GOVERNANCE_TIMEOUT = "governance_timeout";
20
+ /**
21
+ * Build the fail-closed verdict (SI-001 / DB-001 / INV-6): never deliver/send ungated content, never
22
+ * hang. `reason` distinguishes "could not connect" (`gateway_unavailable`) from "connected but the
23
+ * screening deadline elapsed" (`governance_timeout`).
24
+ */
25
+ export function failClosedVerdict(direction, reason = GATEWAY_UNAVAILABLE) {
26
+ const cause = reason === GOVERNANCE_TIMEOUT
27
+ ? "the security gateway did not return a verdict within the screening deadline"
28
+ : "the security gateway could not be reached";
29
+ return {
30
+ disposition: "block",
31
+ reason,
32
+ guidance: direction === "outbound"
33
+ ? `Fail-closed: ${cause}, so this message was NOT sent. Nothing left the machine. ` +
34
+ "Check that the gateway sidecar is running, then retry."
35
+ : `Fail-closed: ${cause}, so inbound content was not delivered to the agent. It was left ` +
36
+ "unacknowledged, so the sender redelivers it on a later attempt — screened once the gateway responds.",
37
+ };
38
+ }
39
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyGH,wFAAwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AACzD;4FAC4F;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAA0B,EAAE,SAAiB,mBAAmB;IAChG,MAAM,KAAK,GAAG,MAAM,KAAK,kBAAkB;QACzC,CAAC,CAAC,6EAA6E;QAC/E,CAAC,CAAC,2CAA2C,CAAC;IAChD,OAAO;QACL,WAAW,EAAE,OAAO;QACpB,MAAM;QACN,QAAQ,EACN,SAAS,KAAK,UAAU;YACtB,CAAC,CAAC,gBAAgB,KAAK,4DAA4D;gBACjF,wDAAwD;YAC1D,CAAC,CAAC,gBAAgB,KAAK,mEAAmE;gBACxF,sGAAsG;KAC7G,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@cello-protocol/gateway",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=24"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "bin": {
22
+ "cello-gateway": "./dist/bin/cello-gateway.js"
23
+ },
24
+ "files": [
25
+ "dist/",
26
+ "package.json"
27
+ ],
28
+ "dependencies": {
29
+ "re2-wasm": "^1.0.2"
30
+ },
31
+ "optionalDependencies": {
32
+ "re2": "^1.25.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^25.6.2",
36
+ "tsx": "^4.22.4"
37
+ },
38
+ "scripts": {
39
+ "typecheck": "tsc --build",
40
+ "test": "vitest run"
41
+ }
42
+ }