@intutic/shared-types 2.1.0 → 2.3.0

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 (188) hide show
  1. package/dist/anomaly.d.ts +6 -10
  2. package/dist/anomaly.d.ts.map +1 -1
  3. package/dist/anomaly.js +0 -2
  4. package/dist/anomaly.js.map +1 -1
  5. package/dist/api-contracts.d.ts +1 -1
  6. package/dist/api-contracts.js +1 -1
  7. package/dist/attenuation.d.ts +1 -1
  8. package/dist/attenuation.js +1 -1
  9. package/dist/auth.d.ts +10 -9
  10. package/dist/auth.d.ts.map +1 -1
  11. package/dist/auth.js +3 -4
  12. package/dist/auth.js.map +1 -1
  13. package/dist/billing.d.ts +1 -1
  14. package/dist/billing.js +1 -1
  15. package/dist/destructiveSql.d.ts +48 -0
  16. package/dist/destructiveSql.d.ts.map +1 -0
  17. package/dist/destructiveSql.js +43 -0
  18. package/dist/destructiveSql.js.map +1 -0
  19. package/dist/devInventory.d.ts +120 -0
  20. package/dist/devInventory.d.ts.map +1 -0
  21. package/dist/devInventory.js +80 -0
  22. package/dist/devInventory.js.map +1 -0
  23. package/dist/enums.d.ts +18 -21
  24. package/dist/enums.d.ts.map +1 -1
  25. package/dist/enums.js +24 -28
  26. package/dist/enums.js.map +1 -1
  27. package/dist/errors.js +3 -3
  28. package/dist/errors.js.map +1 -1
  29. package/dist/finops.d.ts +14 -2
  30. package/dist/finops.d.ts.map +1 -1
  31. package/dist/finops.js +15 -1
  32. package/dist/finops.js.map +1 -1
  33. package/dist/gateDecisions.d.ts +18 -0
  34. package/dist/gateDecisions.d.ts.map +1 -0
  35. package/dist/gateDecisions.js +20 -0
  36. package/dist/gateDecisions.js.map +1 -0
  37. package/dist/gateIdentity.d.ts +23 -0
  38. package/dist/gateIdentity.d.ts.map +1 -0
  39. package/dist/gateIdentity.js +32 -0
  40. package/dist/gateIdentity.js.map +1 -0
  41. package/dist/gateKind.d.ts +172 -0
  42. package/dist/gateKind.d.ts.map +1 -0
  43. package/dist/gateKind.js +160 -0
  44. package/dist/gateKind.js.map +1 -0
  45. package/dist/gateLimits.d.ts +170 -0
  46. package/dist/gateLimits.d.ts.map +1 -0
  47. package/dist/gateLimits.js +96 -0
  48. package/dist/gateLimits.js.map +1 -0
  49. package/dist/gitRemote.d.ts +17 -0
  50. package/dist/gitRemote.d.ts.map +1 -0
  51. package/dist/gitRemote.js +71 -0
  52. package/dist/gitRemote.js.map +1 -0
  53. package/dist/governanceCoverage.d.ts +3 -3
  54. package/dist/governanceCoverage.js +3 -3
  55. package/dist/guardrailIr.d.ts +3 -3
  56. package/dist/guardrailIr.d.ts.map +1 -1
  57. package/dist/guardrailIr.js +3 -3
  58. package/dist/guardrailIr.js.map +1 -1
  59. package/dist/guardrailRender.d.ts +1 -1
  60. package/dist/guardrailRender.js +1 -1
  61. package/dist/harnessRules.d.ts +74 -0
  62. package/dist/harnessRules.d.ts.map +1 -0
  63. package/dist/harnessRules.js +142 -0
  64. package/dist/harnessRules.js.map +1 -0
  65. package/dist/holdMessages.d.ts +25 -0
  66. package/dist/holdMessages.d.ts.map +1 -0
  67. package/dist/holdMessages.js +34 -0
  68. package/dist/holdMessages.js.map +1 -0
  69. package/dist/identity.d.ts +1 -1
  70. package/dist/identity.js +2 -2
  71. package/dist/identity.js.map +1 -1
  72. package/dist/index.d.ts +36 -6
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +141 -10
  75. package/dist/index.js.map +1 -1
  76. package/dist/intelligence.d.ts +1 -2
  77. package/dist/intelligence.d.ts.map +1 -1
  78. package/dist/intelligence.js.map +1 -1
  79. package/dist/mcpBudgets.d.ts +191 -0
  80. package/dist/mcpBudgets.d.ts.map +1 -0
  81. package/dist/mcpBudgets.js +144 -0
  82. package/dist/mcpBudgets.js.map +1 -0
  83. package/dist/mcpRegistryRecord.d.ts +143 -0
  84. package/dist/mcpRegistryRecord.d.ts.map +1 -0
  85. package/dist/mcpRegistryRecord.js +229 -0
  86. package/dist/mcpRegistryRecord.js.map +1 -0
  87. package/dist/mcpToolRisk.d.ts +82 -0
  88. package/dist/mcpToolRisk.d.ts.map +1 -0
  89. package/dist/mcpToolRisk.js +334 -0
  90. package/dist/mcpToolRisk.js.map +1 -0
  91. package/dist/modelCatalog.d.ts +2 -2
  92. package/dist/modelCatalog.generated.js +1 -1
  93. package/dist/modelCatalog.generated.js.map +1 -1
  94. package/dist/modelCatalog.js +2 -2
  95. package/dist/notifications.d.ts +20 -130
  96. package/dist/notifications.d.ts.map +1 -1
  97. package/dist/notifications.js +241 -1
  98. package/dist/notifications.js.map +1 -1
  99. package/dist/phrases.d.ts +87 -0
  100. package/dist/phrases.d.ts.map +1 -0
  101. package/dist/phrases.js +241 -0
  102. package/dist/phrases.js.map +1 -0
  103. package/dist/piiDetectors.d.ts +97 -0
  104. package/dist/piiDetectors.d.ts.map +1 -0
  105. package/dist/piiDetectors.js +96 -0
  106. package/dist/piiDetectors.js.map +1 -0
  107. package/dist/piiDetectors.json +71 -0
  108. package/dist/policy.d.ts +1 -1
  109. package/dist/policy.js +1 -1
  110. package/dist/policyGuardrails.d.ts +127 -10
  111. package/dist/policyGuardrails.d.ts.map +1 -1
  112. package/dist/policyGuardrails.js +59 -6
  113. package/dist/policyGuardrails.js.map +1 -1
  114. package/dist/posturePresets.js +1 -1
  115. package/dist/posturePresets.js.map +1 -1
  116. package/dist/providerVerification.d.ts +2 -2
  117. package/dist/providerVerification.js +2 -2
  118. package/dist/providers.d.ts +4 -4
  119. package/dist/providers.d.ts.map +1 -1
  120. package/dist/providers.js +11 -6
  121. package/dist/providers.js.map +1 -1
  122. package/dist/regoBuiltins.d.ts +42 -0
  123. package/dist/regoBuiltins.d.ts.map +1 -0
  124. package/dist/regoBuiltins.js +732 -0
  125. package/dist/regoBuiltins.js.map +1 -0
  126. package/dist/regoRules.d.ts +105 -0
  127. package/dist/regoRules.d.ts.map +1 -0
  128. package/dist/regoRules.js +407 -0
  129. package/dist/regoRules.js.map +1 -0
  130. package/dist/ruleLoadFailures.d.ts +15 -0
  131. package/dist/ruleLoadFailures.d.ts.map +1 -0
  132. package/dist/ruleLoadFailures.js +26 -0
  133. package/dist/ruleLoadFailures.js.map +1 -0
  134. package/dist/scriptScan.d.ts +5 -5
  135. package/dist/scriptScan.js +3 -3
  136. package/dist/sequence.d.ts +52 -0
  137. package/dist/sequence.d.ts.map +1 -0
  138. package/dist/sequence.js +127 -0
  139. package/dist/sequence.js.map +1 -0
  140. package/dist/session.d.ts +1 -1
  141. package/dist/session.js +1 -1
  142. package/dist/skillScan.d.ts +3 -3
  143. package/dist/skillScan.d.ts.map +1 -1
  144. package/dist/skillScan.js +26 -4
  145. package/dist/skillScan.js.map +1 -1
  146. package/dist/sop.d.ts +24 -11
  147. package/dist/sop.d.ts.map +1 -1
  148. package/dist/sop.js +10 -9
  149. package/dist/sop.js.map +1 -1
  150. package/dist/sourceProviders.d.ts +1 -8
  151. package/dist/sourceProviders.d.ts.map +1 -1
  152. package/dist/sourceProviders.js +2 -9
  153. package/dist/sourceProviders.js.map +1 -1
  154. package/dist/ssoGroupClearance.d.ts +119 -0
  155. package/dist/ssoGroupClearance.d.ts.map +1 -0
  156. package/dist/ssoGroupClearance.js +196 -0
  157. package/dist/ssoGroupClearance.js.map +1 -0
  158. package/dist/sync.d.ts +42 -14
  159. package/dist/sync.d.ts.map +1 -1
  160. package/dist/sync.js +3 -3
  161. package/dist/sync.js.map +1 -1
  162. package/dist/taskManagement.d.ts +0 -2
  163. package/dist/taskManagement.d.ts.map +1 -1
  164. package/dist/taskManagement.js +0 -2
  165. package/dist/taskManagement.js.map +1 -1
  166. package/dist/toolPoison.d.ts +33 -0
  167. package/dist/toolPoison.d.ts.map +1 -0
  168. package/dist/toolPoison.js +85 -0
  169. package/dist/toolPoison.js.map +1 -0
  170. package/dist/usage.d.ts +186 -0
  171. package/dist/usage.d.ts.map +1 -1
  172. package/dist/wasmBinary.d.ts +25 -0
  173. package/dist/wasmBinary.d.ts.map +1 -0
  174. package/dist/wasmBinary.js +111 -0
  175. package/dist/wasmBinary.js.map +1 -0
  176. package/dist/wasmFuel.d.ts +52 -0
  177. package/dist/wasmFuel.d.ts.map +1 -0
  178. package/dist/wasmFuel.js +320 -0
  179. package/dist/wasmFuel.js.map +1 -0
  180. package/dist/wasmMemoryCap.d.ts +21 -0
  181. package/dist/wasmMemoryCap.d.ts.map +1 -0
  182. package/dist/wasmMemoryCap.js +58 -0
  183. package/dist/wasmMemoryCap.js.map +1 -0
  184. package/dist/workspaceSettings.d.ts +126 -17
  185. package/dist/workspaceSettings.d.ts.map +1 -1
  186. package/dist/workspaceSettings.js +21 -2
  187. package/dist/workspaceSettings.js.map +1 -1
  188. package/package.json +2 -2
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Which gate an event came from, for the one harness that installs two.
4
+ *
5
+ * A harness is one `HarnessType`: one integration that `intutic connect` sets
6
+ * up, and the unit the harness count counts. Its gate reports under the same
7
+ * id, in hook events (`harnessType`), agent reports, the AI inventory and the
8
+ * SIEM export. `antigravity` is the exception: the integration installs
9
+ * Google Antigravity's `PreToolUse` gate and Gemini CLI's `BeforeTool` gate,
10
+ * for two products a machine may have together or apart. Each reports under
11
+ * its own gate id, `antigravity` and `gemini-cli`, so the silent-gate check
12
+ * expects only the gate of the product that is there, and the inventory and
13
+ * SIEM say which product a call came through. The harness, its rules file and
14
+ * its count stay one.
15
+ *
16
+ * @module
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.GEMINI_CLI_GATE_ID = void 0;
20
+ exports.gateIdentitiesOf = gateIdentitiesOf;
21
+ exports.harnessOfGate = harnessOfGate;
22
+ /** The gate id Gemini CLI's gate reports under. */
23
+ exports.GEMINI_CLI_GATE_ID = 'gemini-cli';
24
+ /** The gate ids a harness's gates report under: its own id, or two for `antigravity`. */
25
+ function gateIdentitiesOf(harness) {
26
+ return harness === 'antigravity' ? ['antigravity', exports.GEMINI_CLI_GATE_ID] : [harness];
27
+ }
28
+ /** The harness a gate id belongs to. */
29
+ function harnessOfGate(gateId) {
30
+ return gateId === exports.GEMINI_CLI_GATE_ID ? 'antigravity' : gateId;
31
+ }
32
+ //# sourceMappingURL=gateIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateIdentity.js","sourceRoot":"","sources":["../src/gateIdentity.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAMH,4CAEC;AAGD,sCAEC;AAXD,mDAAmD;AACtC,QAAA,kBAAkB,GAAG,YAAY,CAAA;AAE9C,yFAAyF;AACzF,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,0BAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACpF,CAAC;AAED,wCAAwC;AACxC,SAAgB,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM,KAAK,0BAAkB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAA;AAC/D,CAAC"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * gateKind.ts — classifies each harness by HOW its tool calls get governed:
3
+ * for the sync daemon's agent report (`agentReporter.ts`'s `guardrails`
4
+ * facet) and AI inventory, and for the control plane's silent-gate check,
5
+ * which expects a gate only from a harness that has one of its own.
6
+ *
7
+ * # Why this exists
8
+ *
9
+ * `collectAgentReport` used to report `hook_gate: true` unconditionally for
10
+ * every harness, with the comment "the daemon writes the hook gate for every
11
+ * harness it supports." That was already false for `langgraph` — which has
12
+ * no on-disk hook, only the SDK-side `intutic_clawde.gate` — and for `aider`,
13
+ * whose only NO_GATE-registered mechanism is a post-edit, /run-blind
14
+ * pre-commit hook (see `aiderConfigMerger.ts`'s NO_GATE row in
15
+ * `__tests__/harness/gateRegistry.ts`). Wave 1 adds eight more SDK-gated
16
+ * harnesses, which would have made the lie eight times larger without this
17
+ * fix.
18
+ *
19
+ * # What this does NOT do
20
+ *
21
+ * This does not verify that a user actually pip-installed `intutic-clawde`
22
+ * and wired `guard_tools`/`IntuticMiddleware`/etc. into their process — the
23
+ * daemon cannot observe another process's imports, the same way it cannot
24
+ * observe whether a written hook file was left executable. It only reports
25
+ * which MECHANISM this harness's governance model uses (a file the daemon
26
+ * itself writes and can verify existence of, vs. an SDK the harness's own
27
+ * process must import), matching the trust level `hook_gate: true` already
28
+ * carried for file-based harnesses before this fix.
29
+ *
30
+ * # Keeping this in sync with the gate registry
31
+ *
32
+ * `services/sync-daemon/__tests__/harness/gateRegistry.ts` (the GATES/NO_GATE
33
+ * completeness registry exercised by `generatedGateBehaviour.test.ts`) is the
34
+ * authoritative decision per harness, but it is a test-only module (it
35
+ * dynamically imports every writer's compiled `.js` from a temp build dir)
36
+ * and must not be imported from daemon runtime code. `services/sync-daemon/__tests__/harness/gateKind.test.ts`
37
+ * cross-checks the two lists so this file cannot silently drift from that
38
+ * registry's own NO_GATE rows: `file: null` harnesses split between 'sdk'
39
+ * (LangGraph + the Python frameworks — the gate ships in intutic-clawde),
40
+ * 'delegated' (xirp — the gate is whichever wrapped harness's own gate is
41
+ * running), and 'bridge' (trueforge-server — the gate runs in a separate
42
+ * Intutic-operated service, not in any process this repo's writers touch),
43
+ * and 'none' (roo-code, claude-desktop — no hook system); the one non-null
44
+ * row (aiderConfigMerger.ts, "no ... exists") is 'none' too.
45
+ *
46
+ * @module
47
+ */
48
+ import { type HarnessType as HarnessTypeT } from './enums.js';
49
+ /**
50
+ * `'hook'` — the daemon writes an on-disk hook/config file this harness
51
+ * reads before running a tool call (the 19-harness majority).
52
+ * `'sdk'` — the blocking gate ships in `intutic-clawde`, imported into
53
+ * the harness's own Python process; no file for the daemon
54
+ * to write or verify (LangGraph + the eight Wave/Wave-2
55
+ * frameworks).
56
+ * `'none'` — no tool-call gate exists for this harness (aider: its only
57
+ * native hook is post-edit and /run-blind; Roo Code and
58
+ * Claude Desktop: no hook system).
59
+ * `'delegated'` — this harness has no gate mechanism of its own because it
60
+ * does not run tools itself: it wraps OTHER harnesses that
61
+ * are already `'hook'`- or `'sdk'`-gated, and a tool call
62
+ * made inside it is governed by whichever wrapped harness's
63
+ * own gate is running (Xirp, Agentic Orchestrator, and — a
64
+ * different shape of the same idea — AgentCore Runtime,
65
+ * which HOSTS a customer's already-gated framework code
66
+ * rather than spawning it as a subprocess; see
67
+ * gateRegistry.ts's NO_GATE rows for the reasoning this
68
+ * precedent sets for future orchestrator/host-shaped
69
+ * harnesses).
70
+ * Every wrapped backend of the two orchestrators has a gate of
71
+ * its own (Agentic Orchestrator's `opencode` backend through
72
+ * `openCodeHooks.ts`), so `'delegated'`
73
+ * claims exactly what happens. Distinct from
74
+ * `'none'`: `'none'` means no enforcement point exists
75
+ * ANYWHERE for this harness's tool calls; `'delegated'`
76
+ * means one exists, just not one this harness's own row
77
+ * owns or can be credited for independently — reporting it
78
+ * as `'none'` would undercount real coverage, and reporting
79
+ * it as `'hook'` would overclaim a file this daemon never
80
+ * writes for the wrapping harness itself.
81
+ * `'bridge'` — the gate runs OUT OF PROCESS, in an Intutic-operated
82
+ * service reacting to the harness's own async
83
+ * approval/event API, rather than a file this daemon writes
84
+ * (`'hook'`), an SDK imported into the harness's own process
85
+ * (`'sdk'`), no enforcement point at all (`'none'`), or
86
+ * governance credited to a wrapped harness's own gate
87
+ * (`'delegated'`) — a fifth, genuinely different shape.
88
+ * TRUEFORGE_SERVER is the first and so far only member: a
89
+ * TrueForge standalone/hosted server is a separate process
90
+ * nobody embeds an Intutic gate into (unlike TRUEFORGE,
91
+ * embedded mode, which IS `'sdk'`-gated — see that row's own
92
+ * doc), so `services/trueforge-bridge` watches its turn/event
93
+ * stream externally and answers pending approvals over HTTP.
94
+ * Distinct from `'delegated'`: a delegated harness's tool
95
+ * calls are governed by ANOTHER HARNESS's own gate running
96
+ * in that other harness's process; a bridge-gated harness's
97
+ * tool calls are governed by a service this repo ships and
98
+ * operates, running in neither the harness's process nor any
99
+ * other harness's. Distinct from `'sdk'`: no code from this
100
+ * repo ever runs inside the governed harness's own process
101
+ * at all — the harness's only obligation is to expose the
102
+ * async approval API the bridge polls/subscribes to.
103
+ */
104
+ export type GateKind = 'hook' | 'sdk' | 'none' | 'delegated' | 'bridge';
105
+ /**
106
+ * Harnesses whose blocking gate ships SDK-side, in the harness's own
107
+ * process — no on-disk hook/config file exists to point a gate at. Mirrors
108
+ * the `file: null` NO_GATE rows in `gateRegistry.ts`.
109
+ *
110
+ * MASTRA, VERCEL_AI_SDK (T2), EVE (A2), and TRUEFORGE (embedded-library mode
111
+ * only — see its own HarnessType doc) are the JS/TS-native members of this
112
+ * family: their blocking gate ships in `@intutic/gate/mastra`/
113
+ * `@intutic/gate/vercel`/`@intutic/gate/eve`/`@intutic/gate/trueforge`
114
+ * (packages/gate-js) rather than `intutic-clawde`, but the shape is
115
+ * identical — no on-disk hook/config file, tools run as plain callables in
116
+ * the harness's own process (for eve, as per-tool/per-connection `approval`
117
+ * policies attached in the agent directory's own TypeScript; for TrueForge,
118
+ * as `intuticApprovalResponder()` answering `tool.approval_required`
119
+ * pauses — see `@intutic/gate/trueforge`'s module doc for why that shape
120
+ * differs from mastra/vercel's single-callback pattern).
121
+ *
122
+ * AI_SDK_HARNESS and AI_SDK_WORKFLOW (A3) are the same `@intutic/gate`
123
+ * family with one nuance worth naming: the VETO still runs SDK-side in the
124
+ * caller's own Node.js process (an approval responder / a `needsApproval`
125
+ * function), which is what `'sdk'` classifies — but for AI_SDK_HARNESS the
126
+ * tool EXECUTION it vetoes happens server-side in a Vercel Sandbox microVM,
127
+ * and its built-in sandbox tools have no veto surface at all beyond
128
+ * `permissionMode` (defaults to 'allow-all'). `'sdk'` describes where the
129
+ * gate mechanism lives, not a claim that every tool the harness can run
130
+ * passes through it — see gateRegistry.ts's NO_GATE rows for the honest
131
+ * scope statement per harness.
132
+ */
133
+ export declare const SDK_GATED_HARNESSES: ReadonlySet<HarnessTypeT>;
134
+ /**
135
+ * Harnesses with no tool-call gate of their own: the proxy and the MCP
136
+ * governance proxy are their enforcement. Mirrors the NO_GATE rows in
137
+ * `gateRegistry.ts`: aider's only native hook (`--git-commit-verify`) is
138
+ * opt-in, post-edit, and blind to `/run`; Roo Code and Claude Desktop have no
139
+ * hook system at all (Claude Desktop's Code tab is Claude Code, gated by the
140
+ * claude-code gate); Continue's CLI loads PreToolUse hooks but never fires
141
+ * them, and its IDE extension has none (see the continueConfigMerger.ts row).
142
+ */
143
+ export declare const NO_GATE_HARNESSES: ReadonlySet<HarnessTypeT>;
144
+ /**
145
+ * Harnesses that wrap OTHER already-gated harnesses instead of running tools
146
+ * themselves — no gate of their own, but not ungoverned either. Mirrors the
147
+ * `file: null` NO_GATE rows for `xirp` and `agentic-orchestrator` in
148
+ * `gateRegistry.ts`. Xirp was the first entry of this shape; Agentic
149
+ * Orchestrator (O3) is the second. O2 (QM) is expected to add a third, same
150
+ * "wraps other harnesses" shape, in a concurrent phase not yet merged as of
151
+ * this one.
152
+ */
153
+ export declare const DELEGATED_GATE_HARNESSES: ReadonlySet<HarnessTypeT>;
154
+ /**
155
+ * Harnesses whose blocking gate runs OUT OF PROCESS, in an Intutic-operated
156
+ * service reacting to the harness's own async approval/event API — not a
157
+ * file this daemon writes, and not an SDK imported into the harness's own
158
+ * process (no process of ours runs inside the harness at all). Mirrors the
159
+ * `file: null` NO_GATE row for `trueforge-server` in `gateRegistry.ts`.
160
+ *
161
+ * TRUEFORGE_SERVER (B3) is the first member: a TrueForge standalone/hosted
162
+ * server has no in-process host to hang an SDK gate off of (contrast
163
+ * TRUEFORGE, embedded mode, in `SDK_GATED_HARNESSES` above) — instead
164
+ * `services/trueforge-bridge` watches its turn/event stream externally and
165
+ * answers pending `tool.approval_required` pauses over HTTP. See the
166
+ * `'bridge'` `GateKind` doc above for the full distinction from `'sdk'` and
167
+ * `'delegated'`.
168
+ */
169
+ export declare const BRIDGE_GATED_HARNESSES: ReadonlySet<HarnessTypeT>;
170
+ /** How this harness's tool calls get gated. Defaults to `'hook'`. */
171
+ export declare function gateKindForHarness(type: HarnessTypeT): GateKind;
172
+ //# sourceMappingURL=gateKind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateKind.d.ts","sourceRoot":"","sources":["../src/gateKind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,EAAe,KAAK,WAAW,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,YAAY,CAkBxD,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAKtD,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,YAAY,CAO7D,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,YAAY,CAA2C,CAAA;AAExG,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAM/D"}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ /**
3
+ * gateKind.ts — classifies each harness by HOW its tool calls get governed:
4
+ * for the sync daemon's agent report (`agentReporter.ts`'s `guardrails`
5
+ * facet) and AI inventory, and for the control plane's silent-gate check,
6
+ * which expects a gate only from a harness that has one of its own.
7
+ *
8
+ * # Why this exists
9
+ *
10
+ * `collectAgentReport` used to report `hook_gate: true` unconditionally for
11
+ * every harness, with the comment "the daemon writes the hook gate for every
12
+ * harness it supports." That was already false for `langgraph` — which has
13
+ * no on-disk hook, only the SDK-side `intutic_clawde.gate` — and for `aider`,
14
+ * whose only NO_GATE-registered mechanism is a post-edit, /run-blind
15
+ * pre-commit hook (see `aiderConfigMerger.ts`'s NO_GATE row in
16
+ * `__tests__/harness/gateRegistry.ts`). Wave 1 adds eight more SDK-gated
17
+ * harnesses, which would have made the lie eight times larger without this
18
+ * fix.
19
+ *
20
+ * # What this does NOT do
21
+ *
22
+ * This does not verify that a user actually pip-installed `intutic-clawde`
23
+ * and wired `guard_tools`/`IntuticMiddleware`/etc. into their process — the
24
+ * daemon cannot observe another process's imports, the same way it cannot
25
+ * observe whether a written hook file was left executable. It only reports
26
+ * which MECHANISM this harness's governance model uses (a file the daemon
27
+ * itself writes and can verify existence of, vs. an SDK the harness's own
28
+ * process must import), matching the trust level `hook_gate: true` already
29
+ * carried for file-based harnesses before this fix.
30
+ *
31
+ * # Keeping this in sync with the gate registry
32
+ *
33
+ * `services/sync-daemon/__tests__/harness/gateRegistry.ts` (the GATES/NO_GATE
34
+ * completeness registry exercised by `generatedGateBehaviour.test.ts`) is the
35
+ * authoritative decision per harness, but it is a test-only module (it
36
+ * dynamically imports every writer's compiled `.js` from a temp build dir)
37
+ * and must not be imported from daemon runtime code. `services/sync-daemon/__tests__/harness/gateKind.test.ts`
38
+ * cross-checks the two lists so this file cannot silently drift from that
39
+ * registry's own NO_GATE rows: `file: null` harnesses split between 'sdk'
40
+ * (LangGraph + the Python frameworks — the gate ships in intutic-clawde),
41
+ * 'delegated' (xirp — the gate is whichever wrapped harness's own gate is
42
+ * running), and 'bridge' (trueforge-server — the gate runs in a separate
43
+ * Intutic-operated service, not in any process this repo's writers touch),
44
+ * and 'none' (roo-code, claude-desktop — no hook system); the one non-null
45
+ * row (aiderConfigMerger.ts, "no ... exists") is 'none' too.
46
+ *
47
+ * @module
48
+ */
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.BRIDGE_GATED_HARNESSES = exports.DELEGATED_GATE_HARNESSES = exports.NO_GATE_HARNESSES = exports.SDK_GATED_HARNESSES = void 0;
51
+ exports.gateKindForHarness = gateKindForHarness;
52
+ const enums_js_1 = require("./enums.js");
53
+ /**
54
+ * Harnesses whose blocking gate ships SDK-side, in the harness's own
55
+ * process — no on-disk hook/config file exists to point a gate at. Mirrors
56
+ * the `file: null` NO_GATE rows in `gateRegistry.ts`.
57
+ *
58
+ * MASTRA, VERCEL_AI_SDK (T2), EVE (A2), and TRUEFORGE (embedded-library mode
59
+ * only — see its own HarnessType doc) are the JS/TS-native members of this
60
+ * family: their blocking gate ships in `@intutic/gate/mastra`/
61
+ * `@intutic/gate/vercel`/`@intutic/gate/eve`/`@intutic/gate/trueforge`
62
+ * (packages/gate-js) rather than `intutic-clawde`, but the shape is
63
+ * identical — no on-disk hook/config file, tools run as plain callables in
64
+ * the harness's own process (for eve, as per-tool/per-connection `approval`
65
+ * policies attached in the agent directory's own TypeScript; for TrueForge,
66
+ * as `intuticApprovalResponder()` answering `tool.approval_required`
67
+ * pauses — see `@intutic/gate/trueforge`'s module doc for why that shape
68
+ * differs from mastra/vercel's single-callback pattern).
69
+ *
70
+ * AI_SDK_HARNESS and AI_SDK_WORKFLOW (A3) are the same `@intutic/gate`
71
+ * family with one nuance worth naming: the VETO still runs SDK-side in the
72
+ * caller's own Node.js process (an approval responder / a `needsApproval`
73
+ * function), which is what `'sdk'` classifies — but for AI_SDK_HARNESS the
74
+ * tool EXECUTION it vetoes happens server-side in a Vercel Sandbox microVM,
75
+ * and its built-in sandbox tools have no veto surface at all beyond
76
+ * `permissionMode` (defaults to 'allow-all'). `'sdk'` describes where the
77
+ * gate mechanism lives, not a claim that every tool the harness can run
78
+ * passes through it — see gateRegistry.ts's NO_GATE rows for the honest
79
+ * scope statement per harness.
80
+ */
81
+ exports.SDK_GATED_HARNESSES = new Set([
82
+ enums_js_1.HarnessType.LANGGRAPH,
83
+ enums_js_1.HarnessType.LANGCHAIN,
84
+ enums_js_1.HarnessType.CREWAI,
85
+ enums_js_1.HarnessType.AUTOGEN,
86
+ enums_js_1.HarnessType.AG2,
87
+ enums_js_1.HarnessType.GOOGLE_ADK,
88
+ enums_js_1.HarnessType.OPENAI_AGENTS,
89
+ enums_js_1.HarnessType.PYDANTIC_AI,
90
+ enums_js_1.HarnessType.SMOLAGENTS,
91
+ enums_js_1.HarnessType.STRANDS,
92
+ enums_js_1.HarnessType.AGENT_FRAMEWORK,
93
+ enums_js_1.HarnessType.MASTRA,
94
+ enums_js_1.HarnessType.VERCEL_AI_SDK,
95
+ enums_js_1.HarnessType.EVE,
96
+ enums_js_1.HarnessType.TRUEFORGE,
97
+ enums_js_1.HarnessType.AI_SDK_HARNESS,
98
+ enums_js_1.HarnessType.AI_SDK_WORKFLOW,
99
+ ]);
100
+ /**
101
+ * Harnesses with no tool-call gate of their own: the proxy and the MCP
102
+ * governance proxy are their enforcement. Mirrors the NO_GATE rows in
103
+ * `gateRegistry.ts`: aider's only native hook (`--git-commit-verify`) is
104
+ * opt-in, post-edit, and blind to `/run`; Roo Code and Claude Desktop have no
105
+ * hook system at all (Claude Desktop's Code tab is Claude Code, gated by the
106
+ * claude-code gate); Continue's CLI loads PreToolUse hooks but never fires
107
+ * them, and its IDE extension has none (see the continueConfigMerger.ts row).
108
+ */
109
+ exports.NO_GATE_HARNESSES = new Set([
110
+ enums_js_1.HarnessType.AIDER,
111
+ enums_js_1.HarnessType.ROO_CODE,
112
+ enums_js_1.HarnessType.CLAUDE_DESKTOP,
113
+ enums_js_1.HarnessType.CONTINUE,
114
+ ]);
115
+ /**
116
+ * Harnesses that wrap OTHER already-gated harnesses instead of running tools
117
+ * themselves — no gate of their own, but not ungoverned either. Mirrors the
118
+ * `file: null` NO_GATE rows for `xirp` and `agentic-orchestrator` in
119
+ * `gateRegistry.ts`. Xirp was the first entry of this shape; Agentic
120
+ * Orchestrator (O3) is the second. O2 (QM) is expected to add a third, same
121
+ * "wraps other harnesses" shape, in a concurrent phase not yet merged as of
122
+ * this one.
123
+ */
124
+ exports.DELEGATED_GATE_HARNESSES = new Set([
125
+ enums_js_1.HarnessType.XIRP,
126
+ enums_js_1.HarnessType.AGENTIC_ORCHESTRATOR,
127
+ // B2: AWS Bedrock AgentCore Runtime — hosts a customer's own framework
128
+ // code unchanged; governed by whichever already-supported framework
129
+ // adapter that code uses. See tools/cli/src/harness/agentcore.ts.
130
+ enums_js_1.HarnessType.AGENTCORE_RUNTIME,
131
+ ]);
132
+ /**
133
+ * Harnesses whose blocking gate runs OUT OF PROCESS, in an Intutic-operated
134
+ * service reacting to the harness's own async approval/event API — not a
135
+ * file this daemon writes, and not an SDK imported into the harness's own
136
+ * process (no process of ours runs inside the harness at all). Mirrors the
137
+ * `file: null` NO_GATE row for `trueforge-server` in `gateRegistry.ts`.
138
+ *
139
+ * TRUEFORGE_SERVER (B3) is the first member: a TrueForge standalone/hosted
140
+ * server has no in-process host to hang an SDK gate off of (contrast
141
+ * TRUEFORGE, embedded mode, in `SDK_GATED_HARNESSES` above) — instead
142
+ * `services/trueforge-bridge` watches its turn/event stream externally and
143
+ * answers pending `tool.approval_required` pauses over HTTP. See the
144
+ * `'bridge'` `GateKind` doc above for the full distinction from `'sdk'` and
145
+ * `'delegated'`.
146
+ */
147
+ exports.BRIDGE_GATED_HARNESSES = new Set([enums_js_1.HarnessType.TRUEFORGE_SERVER]);
148
+ /** How this harness's tool calls get gated. Defaults to `'hook'`. */
149
+ function gateKindForHarness(type) {
150
+ if (exports.SDK_GATED_HARNESSES.has(type))
151
+ return 'sdk';
152
+ if (exports.NO_GATE_HARNESSES.has(type))
153
+ return 'none';
154
+ if (exports.DELEGATED_GATE_HARNESSES.has(type))
155
+ return 'delegated';
156
+ if (exports.BRIDGE_GATED_HARNESSES.has(type))
157
+ return 'bridge';
158
+ return 'hook';
159
+ }
160
+ //# sourceMappingURL=gateKind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateKind.js","sourceRoot":"","sources":["../src/gateKind.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;;;AAiKH,gDAMC;AArKD,yCAA0E;AA2D1E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACU,QAAA,mBAAmB,GAA8B,IAAI,GAAG,CAAC;IACpE,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,MAAM;IAClB,sBAAW,CAAC,OAAO;IACnB,sBAAW,CAAC,GAAG;IACf,sBAAW,CAAC,UAAU;IACtB,sBAAW,CAAC,aAAa;IACzB,sBAAW,CAAC,WAAW;IACvB,sBAAW,CAAC,UAAU;IACtB,sBAAW,CAAC,OAAO;IACnB,sBAAW,CAAC,eAAe;IAC3B,sBAAW,CAAC,MAAM;IAClB,sBAAW,CAAC,aAAa;IACzB,sBAAW,CAAC,GAAG;IACf,sBAAW,CAAC,SAAS;IACrB,sBAAW,CAAC,cAAc;IAC1B,sBAAW,CAAC,eAAe;CAC5B,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACU,QAAA,iBAAiB,GAA8B,IAAI,GAAG,CAAC;IAClE,sBAAW,CAAC,KAAK;IACjB,sBAAW,CAAC,QAAQ;IACpB,sBAAW,CAAC,cAAc;IAC1B,sBAAW,CAAC,QAAQ;CACrB,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACU,QAAA,wBAAwB,GAA8B,IAAI,GAAG,CAAC;IACzE,sBAAW,CAAC,IAAI;IAChB,sBAAW,CAAC,oBAAoB;IAChC,uEAAuE;IACvE,oEAAoE;IACpE,kEAAkE;IAClE,sBAAW,CAAC,iBAAiB;CAC9B,CAAC,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACU,QAAA,sBAAsB,GAA8B,IAAI,GAAG,CAAC,CAAC,sBAAW,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAExG,qEAAqE;AACrE,SAAgB,kBAAkB,CAAC,IAAkB;IACnD,IAAI,2BAAmB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAC/C,IAAI,yBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAA;IAC9C,IAAI,gCAAwB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAA;IAC1D,IAAI,8BAAsB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IACrD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * How much a gate will evaluate, and for how long, before it refuses.
3
+ *
4
+ * Most harnesses treat a hook that runs past its timeout as having allowed
5
+ * the call (see {@link HOOK_GATE_TIMEOUTS}), so a gate that is slow on a
6
+ * crafted call is no gate. Two bounds keep every gate inside its harness's
7
+ * timeout:
8
+ *
9
+ * - **Size.** A command over {@link COMMAND_SIZE_LIMIT} bytes, or tool
10
+ * arguments over {@link ARGUMENTS_SIZE_LIMIT} bytes (serialized as compact
11
+ * JSON), are refused as `COMMAND_TOO_LARGE` before any rule runs. The limits
12
+ * come from 85,314 tool calls in real coding-agent transcripts: the largest
13
+ * shell command was 38.5 KB (99.9th percentile 13 KB), the largest file
14
+ * write 120 KB, the largest arguments of any tool 418 KB (a plan). So the
15
+ * command limit is six times the largest seen and the arguments limit more
16
+ * than twice.
17
+ * - **Time.** Each hook gate stops at {@link gateDeadlineMs} for its harness
18
+ * after it starts and refuses with a `GATE_DEADLINE` reason. Every built-in
19
+ * rule is linear in the text (sequence.ts, the phrase matcher,
20
+ * regexLinearity.ts in the sync daemon), so only a workspace's own WHERE
21
+ * patterns can get there.
22
+ *
23
+ * Sizes are UTF-8 bytes, which every gate can count the same way.
24
+ *
25
+ * @module
26
+ */
27
+ /** The largest shell command, in UTF-8 bytes, a gate evaluates. */
28
+ export declare const COMMAND_SIZE_LIMIT: number;
29
+ /** The largest tool arguments, in UTF-8 bytes of compact JSON, a gate evaluates. */
30
+ export declare const ARGUMENTS_SIZE_LIMIT: number;
31
+ /**
32
+ * The timeout `intutic connect` sets on a gate's hook entry, in seconds,
33
+ * wherever the harness has a key for one. Harness defaults run from 30 s to
34
+ * 600 s; 10 s keeps a stalled gate from holding the agent for minutes, and is
35
+ * also the longest any gate runs where the harness sets no limit at all.
36
+ */
37
+ export declare const HOOK_TIMEOUT_SECONDS = 10;
38
+ /**
39
+ * How far below its harness's hook timeout a gate refuses.
40
+ *
41
+ * The harness starts its clock when it spawns the hook; the gate starts its
42
+ * own once its interpreter is running (Node's `process.uptime()`, the bash
43
+ * gate's watchdog), and once its deadline fires it still has to stop its
44
+ * children, write the refusal and the audit line, and exit, and the harness
45
+ * has to read the exit. On a 14-core machine running every package's test
46
+ * suite beside 100 busy threads (load average near 190), a gate's refusal
47
+ * reached the harness at most 260 ms after its deadline, Node and bash alike.
48
+ * One second is nearly four times that.
49
+ */
50
+ export declare const GATE_DEADLINE_MARGIN_MS = 1000;
51
+ /** Who decides the timeout a harness applies to its gate. */
52
+ export type HookTimeoutSetBy =
53
+ /** `intutic connect` writes it into the hook entry. */
54
+ 'connect'
55
+ /** The harness's own value, which no setting changes. */
56
+ | 'harness'
57
+ /** The harness documents none, so the gate assumes the shortest default of any documented harness that runs a call whose hook timed out: Grok Build's 5 s. */
58
+ | 'undocumented'
59
+ /** The gate runs in the harness's process, which waits for it without a limit. */
60
+ | 'none';
61
+ /** The timeout a harness applies to its hook gate. */
62
+ export interface HookGateTimeout {
63
+ /** In milliseconds; null when the harness waits without a limit. */
64
+ readonly timeoutMs: number | null;
65
+ readonly setBy: HookTimeoutSetBy;
66
+ /** Where the value comes from. */
67
+ readonly source: string;
68
+ }
69
+ /**
70
+ * The hook timeout each harness applies to its gate, keyed by the harness id
71
+ * the gate is emitted for. The one source every gate's deadline is derived
72
+ * from: the writers set the timeouts marked `connect` from here, and a test
73
+ * reads each written hook entry back against it.
74
+ */
75
+ export declare const HOOK_GATE_TIMEOUTS: {
76
+ readonly 'claude-code': {
77
+ readonly timeoutMs: number;
78
+ readonly setBy: "connect";
79
+ readonly source: "`timeout` (seconds) on the hook entry in .claude/settings.json; default 600 s, a call whose hook times out runs (code.claude.com/docs/en/hooks)";
80
+ };
81
+ readonly cursor: {
82
+ readonly timeoutMs: number;
83
+ readonly setBy: "connect";
84
+ readonly source: "`timeout` (seconds) on the hooks.json entry, beside `failClosed: true`; default not stated (cursor.com/docs/agent/hooks)";
85
+ };
86
+ readonly windsurf: {
87
+ readonly timeoutMs: 5000;
88
+ readonly setBy: "undocumented";
89
+ readonly source: "hooks.json entries have no timeout key and Windsurf documents no timeout; any exit but 2 runs the call (docs.devin.ai/desktop/cascade/hooks)";
90
+ };
91
+ readonly codex: {
92
+ readonly timeoutMs: number;
93
+ readonly setBy: "connect";
94
+ readonly source: "`timeout` (seconds) on the hooks.json entry; default 600 s (Codex hooks documentation)";
95
+ };
96
+ readonly 'muse-code': {
97
+ readonly timeoutMs: 5000;
98
+ readonly setBy: "undocumented";
99
+ readonly source: "Muse Code documents no hook timeout and no key for one (dev.meta.ai/docs/muse-code)";
100
+ };
101
+ readonly 'github-copilot': {
102
+ readonly timeoutMs: number;
103
+ readonly setBy: "connect";
104
+ readonly source: "`timeout` (seconds) on the hook entry, the Copilot CLI's alias for `timeoutSec` and VS Code's key; default 30 s, a call whose hook times out runs (docs.github.com/en/copilot/reference/hooks-configuration)";
105
+ };
106
+ readonly cline: {
107
+ readonly timeoutMs: 30000;
108
+ readonly setBy: "harness";
109
+ readonly source: "HOOK_EXECUTION_TIMEOUT_MS = 30000 in Cline's hook-factory.ts, not configurable; a call whose hook times out runs";
110
+ };
111
+ readonly grok: {
112
+ readonly timeoutMs: number;
113
+ readonly setBy: "connect";
114
+ readonly source: "`timeout` (seconds) on the hook entry; default 5 s, no stated maximum, a call whose hook times out runs (docs.x.ai/build/features/hooks)";
115
+ };
116
+ readonly antigravity: {
117
+ readonly timeoutMs: number;
118
+ readonly setBy: "connect";
119
+ readonly source: "`timeout` (seconds) on the PreToolUse handler in ~/.gemini/config/hooks.json; default 30 s (antigravity.google/docs/hooks)";
120
+ };
121
+ readonly 'gemini-cli': {
122
+ readonly timeoutMs: number;
123
+ readonly setBy: "connect";
124
+ readonly source: "`timeout` (milliseconds) on the BeforeTool hook in ~/.gemini/settings.json; default 60 000 (geminicli.com/docs/hooks/reference)";
125
+ };
126
+ readonly goose: {
127
+ readonly timeoutMs: number;
128
+ readonly setBy: "connect";
129
+ readonly source: "`timeout` (seconds) beside `on_failure: \"block\"` in the plugin's hooks.json; default 30 s (goose hooks guide)";
130
+ };
131
+ readonly openhands: {
132
+ readonly timeoutMs: number;
133
+ readonly setBy: "connect";
134
+ readonly source: "`timeout` (seconds) in .openhands/hooks.json; default 60 s, a call whose hook times out runs (openhands-sdk hooks/config.py)";
135
+ };
136
+ readonly hermes: {
137
+ readonly timeoutMs: number;
138
+ readonly setBy: "connect";
139
+ readonly source: "`timeout` (seconds) beside `fail_closed: true` in ~/.hermes/config.yaml; default 60 s, at most 300 s (hermes-agent shell_hooks.py)";
140
+ };
141
+ readonly openclaw: {
142
+ readonly timeoutMs: number;
143
+ readonly setBy: "connect";
144
+ readonly source: "`timeoutMs` on the before_tool_call registration; default 15 s, a timeout blocks the call but cannot interrupt the handler (OpenClaw docs/plugins/hooks/reference.md)";
145
+ };
146
+ readonly pi: {
147
+ readonly timeoutMs: null;
148
+ readonly setBy: "none";
149
+ readonly source: "Pi awaits an extension's tool_call handler without a limit (core/extensions/runner.ts)";
150
+ };
151
+ readonly opencode: {
152
+ readonly timeoutMs: null;
153
+ readonly setBy: "none";
154
+ readonly source: "OpenCode awaits a plugin's tool.execute.before without a limit (packages/opencode/src/plugin/index.ts)";
155
+ };
156
+ };
157
+ /** A harness that runs a hook gate. */
158
+ export type HookGateHarness = keyof typeof HOOK_GATE_TIMEOUTS;
159
+ /**
160
+ * How long a harness's hook gate may decide, from its start, before it
161
+ * refuses with `GATE_DEADLINE`: {@link GATE_DEADLINE_MARGIN_MS} under the
162
+ * harness's timeout, and never longer than {@link HOOK_TIMEOUT_SECONDS} minus
163
+ * that margin, so a gate the harness waits on for 30 s or without limit still
164
+ * answers as promptly as one connect set a timeout for. On the loaded machine
165
+ * above, a call at the size limits took the bash gates at most 4.6 s and the
166
+ * JavaScript gates at most 1.2 s; every 4 s deadline is a JavaScript gate's.
167
+ * Only a workspace's own pathological WHERE pattern runs this long.
168
+ */
169
+ export declare function gateDeadlineMs(harness: HookGateHarness): number;
170
+ //# sourceMappingURL=gateLimits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateLimits.d.ts","sourceRoot":"","sources":["../src/gateLimits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,QAAa,CAAA;AAE5C,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,QAAc,CAAA;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAE3C,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB;AAC1B,uDAAuD;AACrD,SAAS;AACX,yDAAyD;GACvD,SAAS;AACX,8JAA8J;GAC5J,cAAc;AAChB,kFAAkF;GAChF,MAAM,CAAA;AAEV,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;IAChC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBqB,CAAA;AAEpD,uCAAuC;AACvC,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,kBAAkB,CAAA;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAG/D"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * How much a gate will evaluate, and for how long, before it refuses.
4
+ *
5
+ * Most harnesses treat a hook that runs past its timeout as having allowed
6
+ * the call (see {@link HOOK_GATE_TIMEOUTS}), so a gate that is slow on a
7
+ * crafted call is no gate. Two bounds keep every gate inside its harness's
8
+ * timeout:
9
+ *
10
+ * - **Size.** A command over {@link COMMAND_SIZE_LIMIT} bytes, or tool
11
+ * arguments over {@link ARGUMENTS_SIZE_LIMIT} bytes (serialized as compact
12
+ * JSON), are refused as `COMMAND_TOO_LARGE` before any rule runs. The limits
13
+ * come from 85,314 tool calls in real coding-agent transcripts: the largest
14
+ * shell command was 38.5 KB (99.9th percentile 13 KB), the largest file
15
+ * write 120 KB, the largest arguments of any tool 418 KB (a plan). So the
16
+ * command limit is six times the largest seen and the arguments limit more
17
+ * than twice.
18
+ * - **Time.** Each hook gate stops at {@link gateDeadlineMs} for its harness
19
+ * after it starts and refuses with a `GATE_DEADLINE` reason. Every built-in
20
+ * rule is linear in the text (sequence.ts, the phrase matcher,
21
+ * regexLinearity.ts in the sync daemon), so only a workspace's own WHERE
22
+ * patterns can get there.
23
+ *
24
+ * Sizes are UTF-8 bytes, which every gate can count the same way.
25
+ *
26
+ * @module
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.HOOK_GATE_TIMEOUTS = exports.GATE_DEADLINE_MARGIN_MS = exports.HOOK_TIMEOUT_SECONDS = exports.ARGUMENTS_SIZE_LIMIT = exports.COMMAND_SIZE_LIMIT = void 0;
30
+ exports.gateDeadlineMs = gateDeadlineMs;
31
+ /** The largest shell command, in UTF-8 bytes, a gate evaluates. */
32
+ exports.COMMAND_SIZE_LIMIT = 256 * 1024;
33
+ /** The largest tool arguments, in UTF-8 bytes of compact JSON, a gate evaluates. */
34
+ exports.ARGUMENTS_SIZE_LIMIT = 1024 * 1024;
35
+ /**
36
+ * The timeout `intutic connect` sets on a gate's hook entry, in seconds,
37
+ * wherever the harness has a key for one. Harness defaults run from 30 s to
38
+ * 600 s; 10 s keeps a stalled gate from holding the agent for minutes, and is
39
+ * also the longest any gate runs where the harness sets no limit at all.
40
+ */
41
+ exports.HOOK_TIMEOUT_SECONDS = 10;
42
+ /**
43
+ * How far below its harness's hook timeout a gate refuses.
44
+ *
45
+ * The harness starts its clock when it spawns the hook; the gate starts its
46
+ * own once its interpreter is running (Node's `process.uptime()`, the bash
47
+ * gate's watchdog), and once its deadline fires it still has to stop its
48
+ * children, write the refusal and the audit line, and exit, and the harness
49
+ * has to read the exit. On a 14-core machine running every package's test
50
+ * suite beside 100 busy threads (load average near 190), a gate's refusal
51
+ * reached the harness at most 260 ms after its deadline, Node and bash alike.
52
+ * One second is nearly four times that.
53
+ */
54
+ exports.GATE_DEADLINE_MARGIN_MS = 1000;
55
+ const CONNECT_MS = exports.HOOK_TIMEOUT_SECONDS * 1000;
56
+ /** Grok Build's default hook timeout, the shortest any documented harness uses; assumed where a harness documents none. */
57
+ const UNDOCUMENTED_ASSUMED_MS = 5000;
58
+ /**
59
+ * The hook timeout each harness applies to its gate, keyed by the harness id
60
+ * the gate is emitted for. The one source every gate's deadline is derived
61
+ * from: the writers set the timeouts marked `connect` from here, and a test
62
+ * reads each written hook entry back against it.
63
+ */
64
+ exports.HOOK_GATE_TIMEOUTS = {
65
+ 'claude-code': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry in .claude/settings.json; default 600 s, a call whose hook times out runs (code.claude.com/docs/en/hooks)' },
66
+ cursor: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hooks.json entry, beside `failClosed: true`; default not stated (cursor.com/docs/agent/hooks)' },
67
+ windsurf: { timeoutMs: UNDOCUMENTED_ASSUMED_MS, setBy: 'undocumented', source: 'hooks.json entries have no timeout key and Windsurf documents no timeout; any exit but 2 runs the call (docs.devin.ai/desktop/cascade/hooks)' },
68
+ codex: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hooks.json entry; default 600 s (Codex hooks documentation)' },
69
+ 'muse-code': { timeoutMs: UNDOCUMENTED_ASSUMED_MS, setBy: 'undocumented', source: 'Muse Code documents no hook timeout and no key for one (dev.meta.ai/docs/muse-code)' },
70
+ 'github-copilot': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry, the Copilot CLI\'s alias for `timeoutSec` and VS Code\'s key; default 30 s, a call whose hook times out runs (docs.github.com/en/copilot/reference/hooks-configuration)' },
71
+ cline: { timeoutMs: 30_000, setBy: 'harness', source: 'HOOK_EXECUTION_TIMEOUT_MS = 30000 in Cline\'s hook-factory.ts, not configurable; a call whose hook times out runs' },
72
+ grok: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the hook entry; default 5 s, no stated maximum, a call whose hook times out runs (docs.x.ai/build/features/hooks)' },
73
+ antigravity: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) on the PreToolUse handler in ~/.gemini/config/hooks.json; default 30 s (antigravity.google/docs/hooks)' },
74
+ 'gemini-cli': { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (milliseconds) on the BeforeTool hook in ~/.gemini/settings.json; default 60 000 (geminicli.com/docs/hooks/reference)' },
75
+ goose: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) beside `on_failure: "block"` in the plugin\'s hooks.json; default 30 s (goose hooks guide)' },
76
+ openhands: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) in .openhands/hooks.json; default 60 s, a call whose hook times out runs (openhands-sdk hooks/config.py)' },
77
+ hermes: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeout` (seconds) beside `fail_closed: true` in ~/.hermes/config.yaml; default 60 s, at most 300 s (hermes-agent shell_hooks.py)' },
78
+ openclaw: { timeoutMs: CONNECT_MS, setBy: 'connect', source: '`timeoutMs` on the before_tool_call registration; default 15 s, a timeout blocks the call but cannot interrupt the handler (OpenClaw docs/plugins/hooks/reference.md)' },
79
+ pi: { timeoutMs: null, setBy: 'none', source: 'Pi awaits an extension\'s tool_call handler without a limit (core/extensions/runner.ts)' },
80
+ opencode: { timeoutMs: null, setBy: 'none', source: 'OpenCode awaits a plugin\'s tool.execute.before without a limit (packages/opencode/src/plugin/index.ts)' },
81
+ };
82
+ /**
83
+ * How long a harness's hook gate may decide, from its start, before it
84
+ * refuses with `GATE_DEADLINE`: {@link GATE_DEADLINE_MARGIN_MS} under the
85
+ * harness's timeout, and never longer than {@link HOOK_TIMEOUT_SECONDS} minus
86
+ * that margin, so a gate the harness waits on for 30 s or without limit still
87
+ * answers as promptly as one connect set a timeout for. On the loaded machine
88
+ * above, a call at the size limits took the bash gates at most 4.6 s and the
89
+ * JavaScript gates at most 1.2 s; every 4 s deadline is a JavaScript gate's.
90
+ * Only a workspace's own pathological WHERE pattern runs this long.
91
+ */
92
+ function gateDeadlineMs(harness) {
93
+ const timeoutMs = exports.HOOK_GATE_TIMEOUTS[harness].timeoutMs;
94
+ return Math.min(timeoutMs ?? CONNECT_MS, CONNECT_MS) - exports.GATE_DEADLINE_MARGIN_MS;
95
+ }
96
+ //# sourceMappingURL=gateLimits.js.map