@intutic/sync-daemon 2.2.0 → 2.4.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.
- package/README.md +1 -1
- package/dist/agentReporter.d.ts +23 -11
- package/dist/agentReporter.d.ts.map +1 -1
- package/dist/agentReporter.js +20 -13
- package/dist/agentReporter.js.map +1 -1
- package/dist/configReader.d.ts +1 -3
- package/dist/configReader.d.ts.map +1 -1
- package/dist/configReader.js +0 -2
- package/dist/configReader.js.map +1 -1
- package/dist/configWriter.d.ts +11 -12
- package/dist/configWriter.d.ts.map +1 -1
- package/dist/configWriter.js +35 -58
- package/dist/configWriter.js.map +1 -1
- package/dist/disconnect/harnesses.d.ts +0 -2
- package/dist/disconnect/harnesses.d.ts.map +1 -1
- package/dist/disconnect/harnesses.js +157 -80
- package/dist/disconnect/harnesses.js.map +1 -1
- package/dist/disconnect/index.d.ts.map +1 -1
- package/dist/disconnect/index.js +11 -1
- package/dist/disconnect/index.js.map +1 -1
- package/dist/disconnect/mcp.d.ts +21 -0
- package/dist/disconnect/mcp.d.ts.map +1 -1
- package/dist/disconnect/mcp.js +71 -0
- package/dist/disconnect/mcp.js.map +1 -1
- package/dist/disconnect/recognise.d.ts +2 -2
- package/dist/disconnect/recognise.d.ts.map +1 -1
- package/dist/disconnect/recognise.js +15 -5
- package/dist/disconnect/recognise.js.map +1 -1
- package/dist/harness/aiderConfigMerger.d.ts +28 -8
- package/dist/harness/aiderConfigMerger.d.ts.map +1 -1
- package/dist/harness/aiderConfigMerger.js +59 -11
- package/dist/harness/aiderConfigMerger.js.map +1 -1
- package/dist/harness/antigravityCliHooks.d.ts +61 -0
- package/dist/harness/antigravityCliHooks.d.ts.map +1 -0
- package/dist/harness/antigravityCliHooks.js +207 -0
- package/dist/harness/antigravityCliHooks.js.map +1 -0
- package/dist/harness/antigravityHooks.d.ts +12 -2
- package/dist/harness/antigravityHooks.d.ts.map +1 -1
- package/dist/harness/antigravityHooks.js +36 -16
- package/dist/harness/antigravityHooks.js.map +1 -1
- package/dist/harness/antigravityProducts.d.ts +40 -0
- package/dist/harness/antigravityProducts.d.ts.map +1 -0
- package/dist/harness/antigravityProducts.js +109 -0
- package/dist/harness/antigravityProducts.js.map +1 -0
- package/dist/harness/claudeAgentsMd.d.ts +29 -0
- package/dist/harness/claudeAgentsMd.d.ts.map +1 -0
- package/dist/harness/claudeAgentsMd.js +80 -0
- package/dist/harness/claudeAgentsMd.js.map +1 -0
- package/dist/harness/claudeCodeHooks.d.ts +6 -5
- package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
- package/dist/harness/claudeCodeHooks.js +98 -24
- package/dist/harness/claudeCodeHooks.js.map +1 -1
- package/dist/harness/clineHooks.d.ts +0 -1
- package/dist/harness/clineHooks.d.ts.map +1 -1
- package/dist/harness/clineHooks.js +10 -4
- package/dist/harness/clineHooks.js.map +1 -1
- package/dist/harness/codexHooks.d.ts +2 -0
- package/dist/harness/codexHooks.d.ts.map +1 -1
- package/dist/harness/codexHooks.js +12 -4
- package/dist/harness/codexHooks.js.map +1 -1
- package/dist/harness/cursorHooks.d.ts +5 -2
- package/dist/harness/cursorHooks.d.ts.map +1 -1
- package/dist/harness/cursorHooks.js +9 -3
- package/dist/harness/cursorHooks.js.map +1 -1
- package/dist/harness/dshHooks.d.ts +5 -5
- package/dist/harness/dshHooks.d.ts.map +1 -1
- package/dist/harness/dshHooks.js +5 -5
- package/dist/harness/gateArtifacts.d.ts +35 -0
- package/dist/harness/gateArtifacts.d.ts.map +1 -0
- package/dist/harness/gateArtifacts.js +88 -0
- package/dist/harness/gateArtifacts.js.map +1 -0
- package/dist/harness/gateBody.d.ts +186 -69
- package/dist/harness/gateBody.d.ts.map +1 -1
- package/dist/harness/gateBody.js +820 -182
- package/dist/harness/gateBody.js.map +1 -1
- package/dist/harness/gateSightings.d.ts +47 -0
- package/dist/harness/gateSightings.d.ts.map +1 -0
- package/dist/harness/gateSightings.js +159 -0
- package/dist/harness/gateSightings.js.map +1 -0
- package/dist/harness/githubCopilotHooks.d.ts.map +1 -1
- package/dist/harness/githubCopilotHooks.js +7 -1
- package/dist/harness/githubCopilotHooks.js.map +1 -1
- package/dist/harness/gooseHardener.d.ts +0 -1
- package/dist/harness/gooseHardener.d.ts.map +1 -1
- package/dist/harness/gooseHardener.js +1 -1
- package/dist/harness/gooseHardener.js.map +1 -1
- package/dist/harness/gooseHooks.d.ts +14 -1
- package/dist/harness/gooseHooks.d.ts.map +1 -1
- package/dist/harness/gooseHooks.js +55 -29
- package/dist/harness/gooseHooks.js.map +1 -1
- package/dist/harness/grokHooks.d.ts +2 -2
- package/dist/harness/grokHooks.d.ts.map +1 -1
- package/dist/harness/grokHooks.js +11 -6
- package/dist/harness/grokHooks.js.map +1 -1
- package/dist/harness/hermesHooks.d.ts +18 -8
- package/dist/harness/hermesHooks.d.ts.map +1 -1
- package/dist/harness/hermesHooks.js +48 -17
- package/dist/harness/hermesHooks.js.map +1 -1
- package/dist/harness/mcpAutoWrite.d.ts +24 -9
- package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
- package/dist/harness/mcpAutoWrite.js +218 -25
- package/dist/harness/mcpAutoWrite.js.map +1 -1
- package/dist/harness/museHooks.d.ts +3 -3
- package/dist/harness/museHooks.d.ts.map +1 -1
- package/dist/harness/museHooks.js +9 -5
- package/dist/harness/museHooks.js.map +1 -1
- package/dist/harness/n8nHooks.d.ts +0 -1
- package/dist/harness/n8nHooks.d.ts.map +1 -1
- package/dist/harness/n8nHooks.js +4 -1
- package/dist/harness/n8nHooks.js.map +1 -1
- package/dist/harness/openCodeHooks.d.ts +2 -2
- package/dist/harness/openCodeHooks.d.ts.map +1 -1
- package/dist/harness/openCodeHooks.js +7 -3
- package/dist/harness/openCodeHooks.js.map +1 -1
- package/dist/harness/openWebuiHooks.d.ts +0 -1
- package/dist/harness/openWebuiHooks.d.ts.map +1 -1
- package/dist/harness/openWebuiHooks.js +5 -1
- package/dist/harness/openWebuiHooks.js.map +1 -1
- package/dist/harness/openclawHooks.d.ts +70 -18
- package/dist/harness/openclawHooks.d.ts.map +1 -1
- package/dist/harness/openclawHooks.js +213 -161
- package/dist/harness/openclawHooks.js.map +1 -1
- package/dist/harness/openhandsHooks.d.ts +24 -10
- package/dist/harness/openhandsHooks.d.ts.map +1 -1
- package/dist/harness/openhandsHooks.js +49 -48
- package/dist/harness/openhandsHooks.js.map +1 -1
- package/dist/harness/piHooks.d.ts +52 -17
- package/dist/harness/piHooks.d.ts.map +1 -1
- package/dist/harness/piHooks.js +177 -166
- package/dist/harness/piHooks.js.map +1 -1
- package/dist/harness/protectedPaths.d.ts +107 -25
- package/dist/harness/protectedPaths.d.ts.map +1 -1
- package/dist/harness/protectedPaths.js +342 -48
- package/dist/harness/protectedPaths.js.map +1 -1
- package/dist/harness/rulesSection.d.ts +62 -0
- package/dist/harness/rulesSection.d.ts.map +1 -0
- package/dist/harness/rulesSection.js +145 -0
- package/dist/harness/rulesSection.js.map +1 -0
- package/dist/harness/windsurfHooks.d.ts +0 -1
- package/dist/harness/windsurfHooks.d.ts.map +1 -1
- package/dist/harness/windsurfHooks.js +4 -1
- package/dist/harness/windsurfHooks.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -9
- package/dist/index.js.map +1 -1
- package/dist/inventory.d.ts +53 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +133 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lib/complianceProbes.d.ts +2 -1
- package/dist/lib/complianceProbes.d.ts.map +1 -1
- package/dist/lib/complianceProbes.js +1 -1
- package/dist/lib/complianceProbes.js.map +1 -1
- package/dist/lib/decisionsDigest.d.ts +34 -16
- package/dist/lib/decisionsDigest.d.ts.map +1 -1
- package/dist/lib/decisionsDigest.js +105 -46
- package/dist/lib/decisionsDigest.js.map +1 -1
- package/dist/lib/egressPolicy.d.ts +2 -2
- package/dist/lib/egressPolicy.js +2 -2
- package/dist/lib/mcpRegistryPy.d.ts +11 -0
- package/dist/lib/mcpRegistryPy.d.ts.map +1 -0
- package/dist/lib/mcpRegistryPy.js +173 -0
- package/dist/lib/mcpRegistryPy.js.map +1 -0
- package/dist/lib/phrasesPy.d.ts +11 -0
- package/dist/lib/phrasesPy.d.ts.map +1 -0
- package/dist/lib/phrasesPy.js +351 -0
- package/dist/lib/phrasesPy.js.map +1 -0
- package/dist/lib/policySnapshot.d.ts +46 -10
- package/dist/lib/policySnapshot.d.ts.map +1 -1
- package/dist/lib/policySnapshot.js +136 -47
- package/dist/lib/policySnapshot.js.map +1 -1
- package/dist/lib/processPoller.d.ts.map +1 -1
- package/dist/lib/processPoller.js +9 -2
- package/dist/lib/processPoller.js.map +1 -1
- package/dist/lib/regexLinearity.d.ts +43 -0
- package/dist/lib/regexLinearity.d.ts.map +1 -0
- package/dist/lib/regexLinearity.js +275 -0
- package/dist/lib/regexLinearity.js.map +1 -0
- package/dist/lib/runtimeEnv.d.ts +1 -3
- package/dist/lib/runtimeEnv.d.ts.map +1 -1
- package/dist/lib/runtimeEnv.js +0 -2
- package/dist/lib/runtimeEnv.js.map +1 -1
- package/dist/lib/sequencePy.d.ts +10 -0
- package/dist/lib/sequencePy.d.ts.map +1 -0
- package/dist/lib/sequencePy.js +102 -0
- package/dist/lib/sequencePy.js.map +1 -0
- package/dist/sessionReporter.d.ts +17 -11
- package/dist/sessionReporter.d.ts.map +1 -1
- package/dist/sessionReporter.js +36 -23
- package/dist/sessionReporter.js.map +1 -1
- package/dist/skillWriter.d.ts +23 -5
- package/dist/skillWriter.d.ts.map +1 -1
- package/dist/skillWriter.js +159 -16
- package/dist/skillWriter.js.map +1 -1
- package/dist/syncCycle.d.ts.map +1 -1
- package/dist/syncCycle.js +21 -9
- package/dist/syncCycle.js.map +1 -1
- package/dist/trajectoryMonitor.d.ts +1 -3
- package/dist/trajectoryMonitor.d.ts.map +1 -1
- package/dist/trajectoryMonitor.js +1 -4
- package/dist/trajectoryMonitor.js.map +1 -1
- package/dist/watcher/driftWatcher.d.ts +0 -1
- package/dist/watcher/driftWatcher.d.ts.map +1 -1
- package/dist/watcher/driftWatcher.js +1 -2
- package/dist/watcher/driftWatcher.js.map +1 -1
- package/dist/watcher/settingsGuard.d.ts +33 -7
- package/dist/watcher/settingsGuard.d.ts.map +1 -1
- package/dist/watcher/settingsGuard.js +373 -61
- package/dist/watcher/settingsGuard.js.map +1 -1
- package/dist/watcher/vscodeHookSettings.d.ts +30 -0
- package/dist/watcher/vscodeHookSettings.d.ts.map +1 -0
- package/dist/watcher/vscodeHookSettings.js +170 -0
- package/dist/watcher/vscodeHookSettings.js.map +1 -0
- package/dist/wsClient.d.ts +0 -1
- package/dist/wsClient.d.ts.map +1 -1
- package/dist/wsClient.js +0 -1
- package/dist/wsClient.js.map +1 -1
- package/package.json +5 -5
- package/dist/harness/claudeDesktopHooks.d.ts +0 -33
- package/dist/harness/claudeDesktopHooks.d.ts.map +0 -1
- package/dist/harness/claudeDesktopHooks.js +0 -256
- package/dist/harness/claudeDesktopHooks.js.map +0 -1
- package/dist/harness/continueHooks.d.ts +0 -63
- package/dist/harness/continueHooks.d.ts.map +0 -1
- package/dist/harness/continueHooks.js +0 -250
- package/dist/harness/continueHooks.js.map +0 -1
- package/dist/harness/gateKind.d.ts +0 -164
- package/dist/harness/gateKind.d.ts.map +0 -1
- package/dist/harness/gateKind.js +0 -144
- package/dist/harness/gateKind.js.map +0 -1
- package/dist/harness/rooCodeHooks.d.ts +0 -31
- package/dist/harness/rooCodeHooks.d.ts.map +0 -1
- package/dist/harness/rooCodeHooks.js +0 -281
- package/dist/harness/rooCodeHooks.js.map +0 -1
|
@@ -1,54 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The gate evaluator, emitted once per language instead of written thirteen
|
|
3
|
-
* times.
|
|
4
|
-
*
|
|
5
|
-
* # Why this file exists
|
|
6
|
-
*
|
|
7
|
-
* Every harness writer used to hand-author its own copy of the decision logic
|
|
8
|
-
* inside a TypeScript template literal. Four production defects came directly
|
|
9
|
-
* out of that arrangement, and each one silently removed enforcement while every
|
|
10
|
-
* test stayed green:
|
|
11
|
-
*
|
|
12
|
-
* - `claudeCodeHooks` emitted `...UNIVERSAL_PROTECTED_PATHS,` as *literal source
|
|
13
|
-
* text* into a script that never imported it. Node threw `ReferenceError`
|
|
14
|
-
* before the gate decided anything — and a Claude Code PreToolUse hook exiting
|
|
15
|
-
* 1 is a hook *error*, not a block, so the call proceeded.
|
|
16
|
-
* - `INTUITIC_` for `INTUTIC_`: the gate died on an unbound variable under
|
|
17
|
-
* `set -u`, exiting 1 rather than 2 — again, not a block.
|
|
18
|
-
* - Five bash writers wrote `\"` where `\\"` was needed. Bash ate the quotes,
|
|
19
|
-
* the audit line stopped being parseable JSON, and `drainHookEvents` drops
|
|
20
|
-
* malformed lines and then *wipes the log* on a successful drain. The record
|
|
21
|
-
* of a block was destroyed rather than delayed.
|
|
22
|
-
* - `gooseHooks`/`openhandsHooks` never extracted a command at all, so neither
|
|
23
|
-
* had a shell-bypass guard — for their entire life.
|
|
24
|
-
*
|
|
25
|
-
* The common cause is not carelessness. It is that shell and JavaScript embedded
|
|
26
|
-
* in a template literal have three levels of escaping and no compiler checking
|
|
27
|
-
* any of them. Emitting from one place does not make the escaping easier; it
|
|
28
|
-
* makes there be one of it, with one set of tests.
|
|
29
|
-
*
|
|
30
|
-
* # The contract with a writer
|
|
31
|
-
*
|
|
32
|
-
* # One editing hazard, since it bit four times
|
|
33
|
-
*
|
|
34
|
-
* A backtick inside a comment in an emitted body ends the TypeScript template
|
|
35
|
-
* literal it lives in, and the rest of the gate becomes TypeScript. `tsc` does
|
|
36
|
-
* catch it — but as a syntax error dozens of lines away, which reads as
|
|
37
|
-
* unrelated damage. Use plain quotes in comments inside the emitted strings.
|
|
38
|
-
*
|
|
39
|
-
* A lint for this was tried and removed: a line-based scan cannot cheaply tell
|
|
40
|
-
* a comment inside a template literal from one outside it, and it produced 26
|
|
41
|
-
* false positives on this file's own prose. The compiler is the right detector;
|
|
42
|
-
* this note is the right documentation.
|
|
43
|
-
*
|
|
44
|
-
* A writer supplies the harness-specific parts — how to read the tool call, how
|
|
45
|
-
* to record an event, how to refuse — and interpolates the bodies below. See
|
|
46
|
-
* {@link ShellGateOptions} and {@link JsGateOptions} for exactly what must be in
|
|
47
|
-
* scope.
|
|
48
|
-
*
|
|
49
|
-
* @module
|
|
50
|
-
*/
|
|
51
1
|
import { DESTRUCTIVE_COMMAND_PATTERNS, type GuardPattern } from './protectedPaths.js';
|
|
2
|
+
import { type HookGateHarness } from '@intutic/shared-types';
|
|
52
3
|
/**
|
|
53
4
|
* Bumped when the emitted evaluator changes shape.
|
|
54
5
|
*
|
|
@@ -69,7 +20,7 @@ import { DESTRUCTIVE_COMMAND_PATTERNS, type GuardPattern } from './protectedPath
|
|
|
69
20
|
*
|
|
70
21
|
* v5: the residual fail-open edges were closed. Every bash gate now converts
|
|
71
22
|
* an accidental crash (exit != 0 and != 2 under `set -euo pipefail`) into
|
|
72
|
-
* exit 2 via {@link
|
|
23
|
+
* exit 2 via {@link emitShellFailClosed}; every bash gate refuses a stdin
|
|
73
24
|
* payload from which neither a tool name nor a tool_input could be extracted
|
|
74
25
|
* (the envelope posture githubCopilotHooks established, now uniform); every
|
|
75
26
|
* JS gate installs `uncaughtException`/`unhandledRejection` handlers as its
|
|
@@ -98,7 +49,7 @@ import { DESTRUCTIVE_COMMAND_PATTERNS, type GuardPattern } from './protectedPath
|
|
|
98
49
|
* picks the fail-open reading of that ambiguity rather than blocking every
|
|
99
50
|
* MCP call the first time a v6 gate meets an old snapshot).
|
|
100
51
|
*
|
|
101
|
-
* v8
|
|
52
|
+
* v8: the `hold` severity and the `action` subject. A hold
|
|
102
53
|
* rule — a `require_approval` SOP rule the control plane resolves, or a local
|
|
103
54
|
* `review_before:` token the daemon compiles as `sop.local.review_before.*` —
|
|
104
55
|
* refuses the call through the harness's own contract, appends the v1 hold
|
|
@@ -122,12 +73,133 @@ import { DESTRUCTIVE_COMMAND_PATTERNS, type GuardPattern } from './protectedPath
|
|
|
122
73
|
* change: an invalid snapshot keeps its `sso_group.*` block rules instead of
|
|
123
74
|
* dropping them with the rest of the dynamic tier. A v8 gate reading a v9
|
|
124
75
|
* snapshot enforces the same rules and drops them on an invalid one.
|
|
76
|
+
*
|
|
77
|
+
* v10: the hold classifier matches each action needle's words with a gap
|
|
78
|
+
* regex (`SQL_GAP_ERE`, replaced in v12) between them, over the normalised command, instead of
|
|
79
|
+
* as a plain substring of the raw one. `DROP/**\/TABLE`, `DROP -- why` +
|
|
80
|
+
* newline + `TABLE`, an escaped `\n`, a line continuation and (in the JS
|
|
81
|
+
* gates, which read the raw command) a tab or a doubled space all dodged a
|
|
82
|
+
* `review_before: action:db_write` or `action:deploy` hold. Only the emitted
|
|
83
|
+
* classifier changed; the `.rules` format did not, so v9 and v10 gates read
|
|
84
|
+
* each other's snapshots — a v9 gate just holds fewer spellings.
|
|
85
|
+
*
|
|
86
|
+
* v11: the classifier reads every harness's shell tool ({@link
|
|
87
|
+
* ACTION_TOOL_NAMES}, now the proxy's `SHELL_TOOLS`, Gemini CLI's
|
|
88
|
+
* `run_shell_command` included) with the v10 matching. A v10 gate does not
|
|
89
|
+
* classify a command run through those extra tool names. The `.rules` format
|
|
90
|
+
* is unchanged.
|
|
91
|
+
*
|
|
92
|
+
* v12: no regex runs on a command to find words that may be split apart. The
|
|
93
|
+
* hold classifier and `phrase`-subject rules (`destructive.sql_drop`) use the
|
|
94
|
+
* linear phrase matcher (`@intutic/shared-types` phrases.ts, emitted as
|
|
95
|
+
* JavaScript; `phrases.py`, emitted as Python and run by the bash gates'
|
|
96
|
+
* extractor), over the raw command. The v10 regex took seconds on a few
|
|
97
|
+
* hundred kilobytes of `git -- git -- …` in the JS gates, and bash's pattern
|
|
98
|
+
* substitution a minute on a long run of backslashes. A v11 gate reading a v12
|
|
99
|
+
* snapshot reads a `phrase` rule's source — the phrases joined by `|` — as a
|
|
100
|
+
* regex over the command, which still matches their plain spellings.
|
|
101
|
+
*
|
|
102
|
+
* v13: no gate rule runs a backtracking regex on a call, and no gate runs
|
|
103
|
+
* past its own deadline. Rules shaped `A.*B` carry the `s` flag in the
|
|
104
|
+
* `.rules` flags column (`is` with `i`) and run as sequences of steps
|
|
105
|
+
* (`@intutic/shared-types` sequence.ts, `sequence.py`); `grep -E` still runs
|
|
106
|
+
* them as written. A call whose command is over `COMMAND_SIZE_LIMIT` bytes or
|
|
107
|
+
* whose arguments are over `ARGUMENTS_SIZE_LIMIT` is refused as
|
|
108
|
+
* `COMMAND_TOO_LARGE`, and a gate still deciding at its deadline refuses
|
|
109
|
+
* with `GATE_DEADLINE`, ahead of the harnesses that read a
|
|
110
|
+
* hook timeout as an allow. A v12 gate compares the flags column with `i`, so
|
|
111
|
+
* it runs a sequence rule as the regex it also is, case-sensitively.
|
|
112
|
+
*
|
|
113
|
+
* v14: the MCP server registry and refusal codes. The snapshot carries the
|
|
114
|
+
* workspace's registry decisions as an `@mcp_registry` data line (two
|
|
115
|
+
* columns, inside the digest), and the JS and bash gates refuse an
|
|
116
|
+
* `mcp__<server>__<tool>` call to a blocked or held server, to a server the
|
|
117
|
+
* workspace has not approved under `mcpDefaultPolicy: deny`, or to a disabled
|
|
118
|
+
* tool, with the MCP proxy's codes, rule ids and reasons
|
|
119
|
+
* (`evaluateMcpRegistry` in `@intutic/shared-types`). An invalid snapshot
|
|
120
|
+
* keeps the record but not its approvals, as it keeps the SSO-group refusals
|
|
121
|
+
* but not the member's groups. A JSON decision (Cline, Grok Build,
|
|
122
|
+
* Antigravity) now carries `code` and `ruleId` ({@link HOOK_REFUSAL_CODES}).
|
|
123
|
+
* The `.rules` rule format is unchanged; a v13 gate skips the record line as
|
|
124
|
+
* it skips `@sso_groups`, and enforces no registry.
|
|
125
|
+
*
|
|
126
|
+
* v15: the in-process gates (the `'throw'` contract: OpenCode's plugin, Pi's
|
|
127
|
+
* extension, OpenClaw's plugin) run their rules under the same deadline,
|
|
128
|
+
* measured from the start of the call rather than of the process, which
|
|
129
|
+
* started long before. Pi and OpenCode await a tool-call handler with no time
|
|
130
|
+
* limit, and OpenClaw's own hook timeout cannot interrupt synchronous code,
|
|
131
|
+
* so a v14 in-process gate on a slow ` WHERE ` pattern held the agent.
|
|
132
|
+
*
|
|
133
|
+
* v16: the MCP server allowlist moved inside the digest. It was a
|
|
134
|
+
* `#mcpservers` header, which the digest does not cover, so adding a server
|
|
135
|
+
* to it by hand widened the allowlist and left the snapshot valid. It is now
|
|
136
|
+
* an `@mcp_allowlist` data line (tag, severity, comma-joined servers; three
|
|
137
|
+
* columns, so every rule parser skips it), and a snapshot that fails its
|
|
138
|
+
* digest keeps the allowlist but admits no server and refuses at `block`,
|
|
139
|
+
* as it keeps the registry's refusals but not its approvals. The bash gates'
|
|
140
|
+
* registry decision is `intutic_clawde/gate/mcp_registry.py`, emitted
|
|
141
|
+
* verbatim. A v15 gate reading a v16 snapshot enforces no allowlist; the
|
|
142
|
+
* daemon regenerates every gate each sync cycle.
|
|
143
|
+
*
|
|
144
|
+
* v17: an unverified snapshot admits no MCP server. A snapshot whose digest
|
|
145
|
+
* is broken or missing, or that names another workspace, used to keep the
|
|
146
|
+
* registry's refusals and an allowlist that admitted nothing; but a deleted
|
|
147
|
+
* record looks exactly like one never set, and an edit to the registry's
|
|
148
|
+
* blocked list or default policy still widened it. Every gate now refuses
|
|
149
|
+
* every MCP call on such a snapshot as `POLICY_SNAPSHOT_UNVERIFIED`
|
|
150
|
+
* (`mcpSnapshotUnverifiedRefusal` in `@intutic/shared-types`), at `block`
|
|
151
|
+
* in an observe-only workspace too, and the sync daemon restores the last
|
|
152
|
+
* snapshot it verified. The JS and Python readers also read a snapshot with
|
|
153
|
+
* no `#digest` line as unverified, as the bash gates already did. And the
|
|
154
|
+
* compiled floor refuses an edit to a VS Code settings file that sets
|
|
155
|
+
* `chat.useHooks` or `chat.hookFilesLocations` (`HOOK_SETTING_PATTERNS`),
|
|
156
|
+
* which can switch off the GitHub Copilot gate. The `.rules` format is
|
|
157
|
+
* unchanged.
|
|
158
|
+
*
|
|
159
|
+
* v18: each gate's deadline is its own harness's: a second under the hook
|
|
160
|
+
* timeout that harness applies (`HOOK_GATE_TIMEOUTS` and `gateDeadlineMs` in
|
|
161
|
+
* `@intutic/shared-types`), at most 9 s. One 4 s deadline for every gate,
|
|
162
|
+
* sized for Grok Build's 5 s default (connect now writes 10 s), refused legitimate calls on a busy machine in
|
|
163
|
+
* harnesses that wait 10 s or more. The bash gates also screen each subject
|
|
164
|
+
* with one `grep` holding every rule's pattern before testing rule by rule,
|
|
165
|
+
* and take the whitespace-collapsed fields from the extractor as they are:
|
|
166
|
+
* a call at the size limit had forked a hundred `grep`s and spent seconds of
|
|
167
|
+
* a loaded machine before any rule could match. The `.rules` format is
|
|
168
|
+
* unchanged.
|
|
125
169
|
*/
|
|
126
|
-
export declare const GATE_VERSION =
|
|
170
|
+
export declare const GATE_VERSION = 18;
|
|
171
|
+
/**
|
|
172
|
+
* The refusal codes a hook gate's JSON decision carries, as `code` beside the
|
|
173
|
+
* deciding `ruleId` (null when no rule decided), for the harnesses that read
|
|
174
|
+
* a decision from stdout rather than an exit code: Cline (`cancel`), Grok
|
|
175
|
+
* Build and Antigravity (`decision: deny`). The exit-code harnesses read the
|
|
176
|
+
* same refusal as text on stderr, the rule id in brackets. Held to
|
|
177
|
+
* `packages/shared-types/fixtures/refusal-codes.json` (`hook`) by a test.
|
|
178
|
+
*
|
|
179
|
+
* - `BUILT_IN_RULE`: a rule compiled into the gate (a governance bypass, a
|
|
180
|
+
* write to a protected path or a skill directory, a secret in content);
|
|
181
|
+
* - `SNAPSHOT`: a block rule from the policy snapshot (an SOP, the
|
|
182
|
+
* destructive-command tier, a skill-content rule);
|
|
183
|
+
* - `SSO_GROUP`: an `sso_group.*` rule, compiled from the workspace's SSO
|
|
184
|
+
* group policy for this member;
|
|
185
|
+
* - `HELD`: a hold rule, with `holdId`;
|
|
186
|
+
* - `SERVER_BLOCKED`, `SERVER_HELD`, `SERVER_NOT_APPROVED`, `TOOL_DISABLED`:
|
|
187
|
+
* the MCP server registry;
|
|
188
|
+
* - `SERVER_NOT_ALLOWED`: the workspace's `mcpAllowedServers` list;
|
|
189
|
+
* - `POLICY_SNAPSHOT_UNVERIFIED`: an MCP call on a snapshot that failed its
|
|
190
|
+
* integrity check, which admits no MCP server;
|
|
191
|
+
* - `COMMAND_TOO_LARGE`: the call is over the size a gate evaluates;
|
|
192
|
+
* - `GATE_DEADLINE`: the gate did not decide within its harness's deadline
|
|
193
|
+
* (`gateDeadlineMs` in `@intutic/shared-types`);
|
|
194
|
+
* - `UNREADABLE_CALL`: the payload held no tool call the gate could read;
|
|
195
|
+
* - `GATE_CRASHED`: the gate failed while deciding.
|
|
196
|
+
*/
|
|
197
|
+
export declare const HOOK_REFUSAL_CODES: readonly ["BUILT_IN_RULE", "SNAPSHOT", "SSO_GROUP", "HELD", "SERVER_BLOCKED", "SERVER_HELD", "SERVER_NOT_APPROVED", "TOOL_DISABLED", "SERVER_NOT_ALLOWED", "POLICY_SNAPSHOT_UNVERIFIED", "COMMAND_TOO_LARGE", "GATE_DEADLINE", "UNREADABLE_CALL", "GATE_CRASHED"];
|
|
127
198
|
/**
|
|
128
199
|
* The coarse command → action-token classification the hold tier keys on:
|
|
129
|
-
* `review_before: action:deploy` holds a shell command that contains
|
|
130
|
-
* the deploy needles
|
|
200
|
+
* `review_before: action:deploy` holds a shell command that contains one of
|
|
201
|
+
* the deploy needles, whatever separates its words (the phrase matcher,
|
|
202
|
+
* `@intutic/shared-types` phrases.ts). Deliberately minimal — a gate that tries to be clever
|
|
131
203
|
* about shell commands is a gate that blocks real work — and it mirrors the
|
|
132
204
|
* proxy's `actions.rs` in both directions: `hookActionParity.test.ts` reads
|
|
133
205
|
* THIS file as text and fails if either side knows a needle the other does
|
|
@@ -135,8 +207,15 @@ export declare const GATE_VERSION = 9;
|
|
|
135
207
|
* that is what the test's regex finds.
|
|
136
208
|
*/
|
|
137
209
|
export declare const ACTION_NEEDLES: ReadonlyArray<readonly [string, readonly string[]]>;
|
|
138
|
-
/**
|
|
139
|
-
|
|
210
|
+
/**
|
|
211
|
+
* The (lower-cased) tool names whose `command` the classifier reads: every
|
|
212
|
+
* harness's shell tool. The same list as the proxy's `SHELL_TOOLS` in
|
|
213
|
+
* `actions.rs` (`hookActionParity.test.ts` holds them equal), so a hold the
|
|
214
|
+
* proxy would classify is one the gate can hold before the call runs.
|
|
215
|
+
* `run_shell_command` is Gemini CLI's, `run_command` Antigravity's and
|
|
216
|
+
* `execute_command` Cline's.
|
|
217
|
+
*/
|
|
218
|
+
export declare const ACTION_TOOL_NAMES: readonly ["bash", "shell", "run_command", "runcommand", "execute_command", "run_shell_command", "terminal", "execute", "exec"];
|
|
140
219
|
/** Where a gate appends a hold, relative to the workspace root; the daemon's
|
|
141
220
|
* `drainReviewRequests` reads the same file. */
|
|
142
221
|
export declare const REVIEW_REQUESTS_BASENAME = "review-requests.jsonl";
|
|
@@ -144,6 +223,26 @@ export declare const REVIEW_REQUESTS_LOG = ".intutic/events/review-requests.json
|
|
|
144
223
|
/** Bumped when a hold record's shape changes; the control plane drops any
|
|
145
224
|
* other version at ingest. */
|
|
146
225
|
export declare const REVIEW_REQUEST_VERSION = 1;
|
|
226
|
+
/**
|
|
227
|
+
* The Python the bash gates run, defined once per gate script: the phrase
|
|
228
|
+
* matcher ({@link PHRASES_PY_SOURCE}), the MCP registry decision
|
|
229
|
+
* ({@link MCP_REGISTRY_PY_SOURCE}) and four entry points over them.
|
|
230
|
+
*
|
|
231
|
+
* - `intutic_actions(tool, command)` — the hold classifier, called by
|
|
232
|
+
* {@link SHELL_EXTRACT}'s Python, which already reads the raw tool input:
|
|
233
|
+
* space-padded action tokens (" action:deploy ") or " ".
|
|
234
|
+
* - `intutic_phrase_rule(source, command)` — a `phrase`-subject rule: its
|
|
235
|
+
* source is `|`-separated phrases, each matched as words with boundaries.
|
|
236
|
+
* - `intutic_mcp_registry(record_b64, tool)` — the `@mcp_registry` record's
|
|
237
|
+
* decision on an MCP call.
|
|
238
|
+
* - `intutic_mcp_unverified(tool)` — the refusal of an MCP call on a
|
|
239
|
+
* snapshot that failed its integrity check.
|
|
240
|
+
*
|
|
241
|
+
* The classifier used to be `grep -E` with a gap regex over the normalised
|
|
242
|
+
* command, and bash's own pattern substitution on it took a minute on a long
|
|
243
|
+
* run of backslashes. Python is already required by every bash gate.
|
|
244
|
+
*/
|
|
245
|
+
export declare const GATE_PY_LIB: string;
|
|
147
246
|
/**
|
|
148
247
|
* How old a snapshot may be before a gate reports it as stale.
|
|
149
248
|
*
|
|
@@ -158,21 +257,23 @@ export declare const SNAPSHOT_STALE_AFTER_DAYS = 7;
|
|
|
158
257
|
*
|
|
159
258
|
* The three values are not stylistic. Claude Code, Cursor and the bash
|
|
160
259
|
* harnesses read the **exit code** (2 = deny; 1 is an error and lets the call
|
|
161
|
-
* through). Cline
|
|
162
|
-
*
|
|
260
|
+
* through). Cline ignores the exit code and reads a `{"cancel": true}`
|
|
261
|
+
* object on stdout. Grok Build ALSO ignores the exit code, but its
|
|
163
262
|
* confirmed verdict shape is a *different* stdout object —
|
|
164
263
|
* `{"decision":"deny","reason":"..."}` — not `{"cancel":true}`. The two
|
|
165
264
|
* stdout contracts are kept as distinct union members rather than folded into
|
|
166
265
|
* one "stdout-cancel" bucket precisely because a gate that emits the wrong
|
|
167
266
|
* field name looks identical in a code review and enforces nothing: Grok
|
|
168
|
-
* Build does not recognise `cancel`, and Cline
|
|
267
|
+
* Build does not recognise `cancel`, and Cline does not recognise
|
|
169
268
|
* `decision`. A gate that uses the wrong one is silently inert.
|
|
170
269
|
*/
|
|
171
270
|
/**
|
|
172
271
|
* `'throw'` is for a gate that runs INSIDE the harness process (OpenCode's
|
|
173
|
-
* plugin hook): the refusal is a thrown
|
|
174
|
-
*
|
|
175
|
-
*
|
|
272
|
+
* plugin hook, Pi's extension, OpenClaw's plugin): the refusal is a thrown
|
|
273
|
+
* Error carrying the BLOCKED message. OpenCode turns it into the tool-error
|
|
274
|
+
* the model reads; the Pi and OpenClaw handlers catch it and return their
|
|
275
|
+
* host's block result. No exit code, no stdout — the same in-process posture
|
|
276
|
+
* the n8n workflow gate takes.
|
|
176
277
|
*/
|
|
177
278
|
export type BlockContract = 'exit2' | 'stdout-cancel' | 'stdout-decision-deny' | 'throw';
|
|
178
279
|
/**
|
|
@@ -249,11 +350,14 @@ export declare function toRulesLine(p: GuardPattern): string;
|
|
|
249
350
|
* defined by the writer AFTER this prelude, so the trap probes for it before
|
|
250
351
|
* calling: a crash earlier than the definition still blocks, just without an
|
|
251
352
|
* audit line (stderr carries the reason either way).
|
|
353
|
+
*
|
|
354
|
+
* It also starts the gate's deadline, which is the harness's own
|
|
355
|
+
* ({@link gateDeadlineMs}).
|
|
252
356
|
*/
|
|
253
|
-
export declare
|
|
357
|
+
export declare function emitShellFailClosed(harness: HookGateHarness): string;
|
|
254
358
|
export interface ShellGateOptions {
|
|
255
359
|
/** Harness id, as it appears in audit lines. */
|
|
256
|
-
harness:
|
|
360
|
+
harness: HookGateHarness;
|
|
257
361
|
/**
|
|
258
362
|
* Name of the shell function the writer defined to record an event.
|
|
259
363
|
* Called as `<fn> <verdict> <tool> <reason>`.
|
|
@@ -267,11 +371,24 @@ export interface ShellGateOptions {
|
|
|
267
371
|
*/
|
|
268
372
|
reviewRequestFile?: string;
|
|
269
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* The JS classifier, `intuticActions(toolName, command)`. Needs
|
|
376
|
+
* `intuticNormalise` in scope. Exported for the classifier's tests.
|
|
377
|
+
*/
|
|
378
|
+
export declare function emitJsActionClassifier(): string;
|
|
270
379
|
export declare function emitShellGate(opts: ShellGateOptions): string;
|
|
271
380
|
export interface JsGateOptions {
|
|
272
|
-
|
|
381
|
+
/** Harness id, as it appears in audit lines; it also picks the gate's deadline. */
|
|
382
|
+
harness: HookGateHarness;
|
|
273
383
|
/** How this harness refuses. */
|
|
274
384
|
contract: BlockContract;
|
|
385
|
+
/**
|
|
386
|
+
* The harness's decision object may carry only the fields it documents
|
|
387
|
+
* (Google Antigravity), so a refusal names its code in the reason text,
|
|
388
|
+
* `(refusal code SERVER_BLOCKED)`, rather than in `code` and `ruleId`
|
|
389
|
+
* fields. The rule id is already in the reason, in brackets.
|
|
390
|
+
*/
|
|
391
|
+
documentedFieldsOnly?: boolean;
|
|
275
392
|
/** See {@link ShellGateOptions.reviewRequestFile}. Writers whose artifact
|
|
276
393
|
* does not live in `.intutic/hooks/` (cline, opencode) pass it. */
|
|
277
394
|
reviewRequestFile?: string;
|
|
@@ -286,7 +403,7 @@ export interface JsGateOptions {
|
|
|
286
403
|
*/
|
|
287
404
|
export declare function emitJsGate(opts: JsGateOptions): string;
|
|
288
405
|
/**
|
|
289
|
-
* Pre-image capture — the storage half of the rollback enforcement rung
|
|
406
|
+
* Pre-image capture — the storage half of the rollback enforcement rung.
|
|
290
407
|
*
|
|
291
408
|
* ## Why this exists and why it is here
|
|
292
409
|
*
|
|
@@ -346,7 +463,7 @@ export declare function emitPreImageCapture(): string;
|
|
|
346
463
|
* every emitted gate for real.
|
|
347
464
|
*
|
|
348
465
|
* Refuses through the harness's contract, like everything else: exit 2 means
|
|
349
|
-
* nothing to cline
|
|
466
|
+
* nothing to cline, which only reads stdout — a crashed
|
|
350
467
|
* stdout-cancel gate must still print its cancel object.
|
|
351
468
|
*/
|
|
352
469
|
export declare function emitJsFailClosedPrelude(opts: JsGateOptions): string;
|
|
@@ -364,7 +481,7 @@ export declare function emitJsFailClosedPrelude(opts: JsGateOptions): string;
|
|
|
364
481
|
* allow — was a silent hole. The message names the fix, because a developer who
|
|
365
482
|
* hits this needs to act on it rather than file a bug.
|
|
366
483
|
*/
|
|
367
|
-
export declare const SHELL_EXTRACT
|
|
484
|
+
export declare const SHELL_EXTRACT: string;
|
|
368
485
|
/**
|
|
369
486
|
* The Python gate, for Open WebUI.
|
|
370
487
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateBody.d.ts","sourceRoot":"","sources":["../../src/harness/gateBody.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gateBody.d.ts","sourceRoot":"","sources":["../../src/harness/gateBody.ts"],"names":[],"mappings":"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"}
|