@guilz-dev/belay 0.8.1 → 0.9.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.
- package/README.md +67 -11
- package/dist/adapters/claude/runtime-entry.js +2 -0
- package/dist/adapters/codex/runtime-entry.js +2 -0
- package/dist/adapters/cursor/hooks.d.ts +5 -1
- package/dist/adapters/cursor/hooks.js +37 -2
- package/dist/adapters/cursor/runtime-entry.js +5 -0
- package/dist/adapters/shared/gate-runtime.d.ts +6 -0
- package/dist/adapters/shared/gate-runtime.js +260 -59
- package/dist/bundle/claude-runtime.mjs +7068 -3966
- package/dist/bundle/codex-runtime.mjs +7001 -3899
- package/dist/bundle/cursor-runtime.mjs +7004 -3899
- package/dist/commands/classify-for-report.js +5 -0
- package/dist/commands/doctor.js +88 -9
- package/dist/commands/explain.js +3 -2
- package/dist/commands/metrics.js +42 -0
- package/dist/commands/recovery-checkpoints.d.ts +8 -1
- package/dist/commands/recovery-checkpoints.js +44 -11
- package/dist/commands/session.d.ts +5 -0
- package/dist/commands/session.js +8 -1
- package/dist/config-io.js +2 -2
- package/dist/conformance/contained-execution-guarantee.d.ts +121 -0
- package/dist/conformance/contained-execution-guarantee.js +121 -0
- package/dist/conformance/guarantee-table.js +7 -0
- package/dist/core/audit-analysis.js +7 -4
- package/dist/core/audit-io.d.ts +1 -0
- package/dist/core/audit-io.js +16 -6
- package/dist/core/audit-legacy-archive.d.ts +6 -0
- package/dist/core/audit-legacy-archive.js +51 -0
- package/dist/core/audit-metrics.d.ts +15 -0
- package/dist/core/audit-metrics.js +16 -2
- package/dist/core/audit-query.d.ts +2 -0
- package/dist/core/audit-query.js +33 -9
- package/dist/core/audit-recovery-metrics.d.ts +33 -0
- package/dist/core/audit-recovery-metrics.js +146 -0
- package/dist/core/audit-serialize.d.ts +9 -0
- package/dist/core/audit-serialize.js +179 -0
- package/dist/core/audit-types.d.ts +8 -1
- package/dist/core/audit-types.js +1 -1
- package/dist/core/bounded-output.d.ts +11 -0
- package/dist/core/bounded-output.js +26 -0
- package/dist/core/capability/attestation.d.ts +56 -0
- package/dist/core/capability/attestation.js +110 -3
- package/dist/core/capability/boundary-session.d.ts +5 -0
- package/dist/core/capability/boundary-session.js +38 -1
- package/dist/core/capability/index.d.ts +1 -1
- package/dist/core/capability/index.js +1 -1
- package/dist/core/capability/policy-engine.js +32 -13
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.js +89 -10
- package/dist/core/contained-execution/docker-policy.d.ts +18 -0
- package/dist/core/contained-execution/docker-policy.js +97 -0
- package/dist/core/contained-execution/docker.d.ts +223 -0
- package/dist/core/contained-execution/docker.js +846 -0
- package/dist/core/contained-execution/eligibility.d.ts +9 -0
- package/dist/core/contained-execution/eligibility.js +103 -0
- package/dist/core/contained-execution/failure.d.ts +18 -0
- package/dist/core/contained-execution/failure.js +105 -0
- package/dist/core/contained-execution/mirror.d.ts +54 -0
- package/dist/core/contained-execution/mirror.js +587 -0
- package/dist/core/contained-execution/policy.d.ts +10 -0
- package/dist/core/contained-execution/policy.js +20 -0
- package/dist/core/decision-config-fingerprint.d.ts +3 -0
- package/dist/core/decision-config-fingerprint.js +6 -0
- package/dist/core/effect-ir/index.d.ts +1 -1
- package/dist/core/effect-ir/index.js +1 -1
- package/dist/core/effect-ir/normalize.d.ts +5 -0
- package/dist/core/effect-ir/normalize.js +17 -7
- package/dist/core/effect-ir/shell-build.js +2 -14
- package/dist/core/effect-ir/shell-lower.js +103 -25
- package/dist/core/gate-contract.d.ts +4 -1
- package/dist/core/gate-contract.js +2 -0
- package/dist/core/process-runner.d.ts +10 -3
- package/dist/core/process-runner.js +66 -10
- package/dist/core/recovery/checkpoint.d.ts +3 -0
- package/dist/core/recovery/checkpoint.js +33 -4
- package/dist/core/recovery/types.d.ts +1 -0
- package/dist/core/scrub.d.ts +17 -0
- package/dist/core/scrub.js +499 -5
- package/dist/core/standing-allow.d.ts +0 -20
- package/dist/core/standing-allow.js +0 -71
- package/dist/core/transactional/apply-observed-changes.d.ts +1 -0
- package/dist/core/transactional/apply-observed-changes.js +11 -0
- package/dist/core/transactional/backend-selector.d.ts +2 -1
- package/dist/core/transactional/backend-selector.js +32 -29
- package/dist/core/transactional/backend.d.ts +3 -0
- package/dist/core/transactional/file-checkpoint-backend.js +242 -54
- package/dist/core/transactional/file-checkpoint-git.d.ts +3 -0
- package/dist/core/transactional/file-checkpoint-git.js +53 -0
- package/dist/core/transactional/file-checkpoint-isolation.d.ts +3 -0
- package/dist/core/transactional/file-checkpoint-isolation.js +16 -0
- package/dist/core/transactional/git-worktree-backend.js +3 -0
- package/dist/core/transactional/git-worktree.d.ts +1 -0
- package/dist/core/transactional/git-worktree.js +1 -0
- package/dist/core/transactional/runner.js +59 -13
- package/dist/core/types.d.ts +13 -0
- package/dist/core/verdict/egress-classify.js +1 -0
- package/dist/core/verdict/parser.d.ts +10 -0
- package/dist/core/verdict/parser.js +271 -40
- package/dist/core/verdict/shell-semantics.js +21 -0
- package/dist/corpus/adversarial-probe.d.ts +1 -1
- package/dist/corpus/adversarial-probe.js +3 -3
- package/dist/corpus/benign-probe-cores.d.ts +6 -0
- package/dist/corpus/{must-allow-commands.js → benign-probe-cores.js} +8 -2
- package/dist/corpus/coverage-compare.d.ts +36 -0
- package/dist/corpus/coverage-compare.js +197 -0
- package/dist/corpus/coverage-contexts.d.ts +17 -0
- package/dist/corpus/coverage-contexts.js +88 -0
- package/dist/corpus/coverage-matrix.d.ts +37 -0
- package/dist/corpus/coverage-matrix.js +159 -0
- package/dist/corpus/coverage-probe.d.ts +91 -0
- package/dist/corpus/coverage-probe.js +341 -0
- package/dist/corpus/evaluate.d.ts +1 -1
- package/dist/corpus/evaluate.js +1 -1
- package/dist/corpus/structural-fixture-root.d.ts +2 -0
- package/dist/corpus/structural-fixture-root.js +5 -0
- package/dist/defaults.js +0 -8
- package/dist/egress-daemon.js +20 -4
- package/dist/installer.js +3 -0
- package/dist/runtime-provenance.d.ts +10 -0
- package/dist/runtime-provenance.js +63 -0
- package/dist/templates.js +12 -7
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -1
- package/skills/belay/SKILL.md +19 -0
- package/skills/belay/belay-status.md +5 -0
- package/dist/corpus/must-allow-commands.d.ts +0 -6
package/README.md
CHANGED
|
@@ -122,7 +122,13 @@ approved shell action first, then lets the remaining prompt continue. CLI replay
|
|
|
122
122
|
|
|
123
123
|
Approvals are one-shot and expire after 15 minutes by default. Every decision is
|
|
124
124
|
written to `.cursor/belay/audit.ndjson`, `.claude/belay/audit.ndjson`, or
|
|
125
|
-
`.codex/belay/audit.ndjson` (depending on the adapter).
|
|
125
|
+
`.codex/belay/audit.ndjson` (depending on the adapter). Schema v3 preserves ISO
|
|
126
|
+
timestamps, fingerprints, and `approvalCorrelationId` for metrics joins. Dogfood
|
|
127
|
+
readiness counts only the active cohort (runtime bundle + authorization-relevant
|
|
128
|
+
config + boundary profile); legacy placeholder logs should be archived via
|
|
129
|
+
`belay upgrade` before trusting readiness. See
|
|
130
|
+
[config schema — audit log](./docs/config-schema.md#audit-log-ndjson-schema-v3) and
|
|
131
|
+
[dogfood audit remediation](./docs/dogfood-audit-remediation-2026-08-22.ja.md).
|
|
126
132
|
|
|
127
133
|
In **audit mode** (`mode: "audit"`), would-be denials are recorded
|
|
128
134
|
(`wouldBlock: true`) but execution still continues, and no approval IDs are
|
|
@@ -135,12 +141,13 @@ Belay is a layered hook gate, not a static denylist. Higher layers are opt-in.
|
|
|
135
141
|
| Layer | Role | Enabled by |
|
|
136
142
|
|-------|------|------------|
|
|
137
143
|
| **L1** Containment | Egress proxy, sandbox capability broker | `egress` / `sandbox` config |
|
|
138
|
-
| **L2** Observation | Transactional
|
|
144
|
+
| **L2** Observation | Transactional mirror and durable checkpoint observation | `policy.transactional` |
|
|
139
145
|
| **L3** Prediction | Policy rules + command heuristics | default |
|
|
140
146
|
| **L4** Approval | Human one-shot / scoped approvals | default |
|
|
141
147
|
|
|
142
148
|
- Normalized shell authorization uses only canonical `EffectPlan` requirements.
|
|
143
|
-
Command lists, legacy overrides, corpus labels, and
|
|
149
|
+
Command lists, legacy overrides, corpus labels, and legacy standing-allow records for shell,
|
|
150
|
+
tool, and subagent actions are inert at runtime.
|
|
144
151
|
- Payload-free reads are `allow`; reversible repository-local writes (including implicit
|
|
145
152
|
download output) are `allow_flagged`. Outside-repository writes, external mutation,
|
|
146
153
|
explicit payload/file/secret sends, high-stakes effects, and partial/indeterminate plans
|
|
@@ -148,6 +155,52 @@ Belay is a layered hook gate, not a static denylist. Higher layers are opt-in.
|
|
|
148
155
|
- Adversarial resistance requires the full L1 stack:
|
|
149
156
|
`belay init --preset l1-full-recommended`, verified with `belay sandbox status`.
|
|
150
157
|
|
|
158
|
+
### Contained unknown execution (opt-in)
|
|
159
|
+
|
|
160
|
+
For an eligible repository-local `unknown_local_effect`, an operator may opt into one disposable
|
|
161
|
+
Docker run instead of taking the ordinary approval path. No command allowlist is involved:
|
|
162
|
+
EffectPlan remains the shell authority, and executable names, prefixes, fingerprints, corpus
|
|
163
|
+
membership, Rails, RSpec, and fictional command names all use the same effect-based eligibility
|
|
164
|
+
route. The original host command is blocked after mediation.
|
|
165
|
+
|
|
166
|
+
Enable it only with an operator-provisioned image and explicit local Docker substrate:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"sandbox": {
|
|
171
|
+
"enabled": true,
|
|
172
|
+
"runtime": "container",
|
|
173
|
+
"containedExecution": {
|
|
174
|
+
"enabled": true,
|
|
175
|
+
"image": "registry.example/contained-runner:2026-08-18",
|
|
176
|
+
"dockerExecutable": "/usr/local/bin/docker",
|
|
177
|
+
"dockerHost": "unix:///var/run/docker.sock"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Run `belay session start` after changing this configuration. It binds a fresh signed capability to
|
|
184
|
+
the configured Docker executable, local Unix daemon, and immutable image ID; image-tag drift,
|
|
185
|
+
tampering, stale proof, or config changes require another session start. v1 never builds or pulls
|
|
186
|
+
an image automatically and always uses network `none`.
|
|
187
|
+
|
|
188
|
+
Belay copies the current workspace to a bounded metadata-free mirror, mounts only that mirror in
|
|
189
|
+
the container at the original guest path, and discards it after one run. Workspace changes are
|
|
190
|
+
discarded; there is no diff/apply or host replay. Guest output is scrubbed and retained only as
|
|
191
|
+
16 KiB tails. This boundary scrub is mandatory even when ordinary audit `redaction.*` options are
|
|
192
|
+
disabled. A nonzero guest exit is reported as contained failure and does not create an approval.
|
|
193
|
+
|
|
194
|
+
In audit mode Belay's contained route reports `wouldMediate` and performs no contained execution:
|
|
195
|
+
it reads no attestation and runs neither a mirror nor a container. The gate returns `allow`, so the
|
|
196
|
+
host hook delegates the original invocation as ordinary audit pass-through; it is not a contained
|
|
197
|
+
route host replay.
|
|
198
|
+
In enforce mode, only pre-execution Docker substrate or daemon unavailability returns to the normal
|
|
199
|
+
approval path. Missing, stale, or tampered attestation/capability; missing or mismatched image;
|
|
200
|
+
mirror/lease failure; create/inspect/start failure; timeout; and cleanup uncertainty fail closed
|
|
201
|
+
without approval. This route is not L1-full;
|
|
202
|
+
see the [guarantee table](./docs/guarantee-table.md) for its exact boundary and residual risks.
|
|
203
|
+
|
|
151
204
|
## Install options
|
|
152
205
|
|
|
153
206
|
```bash
|
|
@@ -242,18 +295,21 @@ Notable settings:
|
|
|
242
295
|
- **`classifier.strictChains: true`** (default) — scans every `&&`, `|`, and `;`
|
|
243
296
|
segment into the EffectPlan and keeps the strictest policy projection. Legacy
|
|
244
297
|
`overrides.allow` / `overrides.external` lists are accepted only for config
|
|
245
|
-
compatibility; shell authorization ignores them
|
|
246
|
-
|
|
298
|
+
compatibility; shell authorization ignores them. **`belay doctor` fails** when either
|
|
299
|
+
list is non-empty (ADR-005). Remove legacy lists; improve EffectPlan semantics or use
|
|
300
|
+
one-shot approval instead.
|
|
247
301
|
- **`controlPlane.enabled: true`** — stores approval state under
|
|
248
302
|
`~/.config/belay/` (or `XDG_CONFIG_HOME/belay`), shared across repos for the
|
|
249
303
|
current OS user. `upgrade` migrates repo-local approvals in; disabling merges
|
|
250
304
|
them back. File-mutation tools and shell redirects cannot write control-plane
|
|
251
305
|
paths while it is enabled.
|
|
252
|
-
- **`policy.transactional.checkpoint.enabled: true`** — after enabling the
|
|
253
|
-
|
|
254
|
-
`
|
|
255
|
-
|
|
256
|
-
|
|
306
|
+
- **`policy.transactional.checkpoint.enabled: true`** — after enabling the transactional
|
|
307
|
+
runner, persist repo-local pre-images and expose them through `belay recover list`. Clean Git
|
|
308
|
+
uses `git_worktree`; dirty Git and non-Git directories use `file_checkpoint` when separately
|
|
309
|
+
enabled (`policy.transactional.fileCheckpoint.enabled` and, for non-Git roots,
|
|
310
|
+
`allowNonGit: true`) with an attested workspace-isolating boundary. Restore is conflict-checked
|
|
311
|
+
and always requires a signed out-of-band, exact one-shot approval. Network, remote Git,
|
|
312
|
+
databases, processes, and repo-external effects are outside this guarantee.
|
|
257
313
|
- **Cloud judge** — configure with `belay config` (interactive) or `belay config set judge.providerId <id>`.
|
|
258
314
|
Providers: `ollama`, `codex`, `claude`, `cursor`. **Provider** is the vendor/service
|
|
259
315
|
(`judge.providerId`); **driver** is the API compatibility layer (`judge.provider`:
|
|
@@ -297,7 +353,7 @@ belay status # show install scope / skill-only state
|
|
|
297
353
|
belay metrics # would-block / verdict summary
|
|
298
354
|
belay report # audit log report
|
|
299
355
|
belay recover [advice] [--command "rm important.ts"] # advisory candidates only
|
|
300
|
-
belay recover status # checkpoint backend and state counts
|
|
356
|
+
belay recover status # checkpoint backend, eligibility, and state counts
|
|
301
357
|
belay recover list # proven repo-local recovery points
|
|
302
358
|
belay recover show <checkpoint-id>
|
|
303
359
|
belay recover apply <checkpoint-id> # signed OOB exact one-shot approval required
|
|
@@ -162,6 +162,7 @@ export async function runShellGateHook() {
|
|
|
162
162
|
command,
|
|
163
163
|
payload,
|
|
164
164
|
toolName: 'Bash',
|
|
165
|
+
sourceEvent: 'PreToolUse',
|
|
165
166
|
});
|
|
166
167
|
jsonResponse(gateVerdictToClaudePreToolUseResponse(verdict));
|
|
167
168
|
}
|
|
@@ -261,6 +262,7 @@ export async function runToolGateHook(_eventName) {
|
|
|
261
262
|
cwd,
|
|
262
263
|
payload: normalizedPayload,
|
|
263
264
|
toolName,
|
|
265
|
+
sourceEvent: 'PreToolUse',
|
|
264
266
|
});
|
|
265
267
|
jsonResponse(gateVerdictToClaudePreToolUseResponse(verdict));
|
|
266
268
|
}
|
|
@@ -180,6 +180,7 @@ export async function runToolGateHook(eventName) {
|
|
|
180
180
|
command: kind === 'shell' ? extractString(normalizedPayload.tool_input, 'command') : undefined,
|
|
181
181
|
payload: normalizedPayload,
|
|
182
182
|
toolName,
|
|
183
|
+
sourceEvent: eventName,
|
|
183
184
|
});
|
|
184
185
|
jsonResponse(gateVerdictToCodexPreToolUseResponse(verdict));
|
|
185
186
|
}
|
|
@@ -209,6 +210,7 @@ export async function runShellGateHook() {
|
|
|
209
210
|
command,
|
|
210
211
|
payload,
|
|
211
212
|
toolName: 'Shell',
|
|
213
|
+
sourceEvent: 'PreToolUse',
|
|
212
214
|
});
|
|
213
215
|
jsonResponse(gateVerdictToCodexPreToolUseResponse(verdict));
|
|
214
216
|
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import type { HooksFile } from '../../types.js';
|
|
1
|
+
import type { HookEntry, HooksFile } from '../../types.js';
|
|
2
|
+
/** Legacy Belay-managed Shell preToolUse gate duplicated beforeShellExecution. */
|
|
3
|
+
export declare function legacyManagedShellPreToolUseEntry(platform: NodeJS.Platform, hooksDir: string, repoRoot: string): HookEntry;
|
|
4
|
+
export declare function removeLegacyManagedShellPreToolUse(hooks: HooksFile, platform: NodeJS.Platform, hooksDir: string, repoRoot: string): HooksFile;
|
|
2
5
|
export declare function mergeCursorHooksFile(current: HooksFile, platform: NodeJS.Platform, hooksDir: string, repoRoot: string): HooksFile;
|
|
6
|
+
export declare function hasDuplicateCursorShellGates(hooks: HooksFile, platform: NodeJS.Platform, hooksDir: string, repoRoot: string): boolean;
|
|
@@ -10,10 +10,37 @@ function mergeHookEntry(current, expected, placement) {
|
|
|
10
10
|
}
|
|
11
11
|
return [...filtered, expected];
|
|
12
12
|
}
|
|
13
|
+
/** Legacy Belay-managed Shell preToolUse gate duplicated beforeShellExecution. */
|
|
14
|
+
export function legacyManagedShellPreToolUseEntry(platform, hooksDir, repoRoot) {
|
|
15
|
+
const managed = getManagedHookEntries(platform, hooksDir, repoRoot);
|
|
16
|
+
const referencePreToolUse = managed.find((entry) => entry.event === 'preToolUse' && entry.definition.matcher === 'Write')?.definition;
|
|
17
|
+
if (!referencePreToolUse) {
|
|
18
|
+
throw new Error('managed hook definitions missing for legacy Shell migration');
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
command: referencePreToolUse.command,
|
|
22
|
+
matcher: 'Shell',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function removeLegacyManagedShellPreToolUse(hooks, platform, hooksDir, repoRoot) {
|
|
26
|
+
const legacy = legacyManagedShellPreToolUseEntry(platform, hooksDir, repoRoot);
|
|
27
|
+
const preToolUse = hooks.hooks.preToolUse;
|
|
28
|
+
if (!Array.isArray(preToolUse)) {
|
|
29
|
+
return hooks;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
...hooks,
|
|
33
|
+
hooks: {
|
|
34
|
+
...hooks.hooks,
|
|
35
|
+
preToolUse: preToolUse.filter((entry) => !entryMatches(entry, legacy)),
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
13
39
|
export function mergeCursorHooksFile(current, platform, hooksDir, repoRoot) {
|
|
40
|
+
const withoutLegacyShell = removeLegacyManagedShellPreToolUse(current, platform, hooksDir, repoRoot);
|
|
14
41
|
const next = {
|
|
15
|
-
version:
|
|
16
|
-
hooks: { ...
|
|
42
|
+
version: withoutLegacyShell.version || 1,
|
|
43
|
+
hooks: { ...withoutLegacyShell.hooks },
|
|
17
44
|
};
|
|
18
45
|
const managedEntries = getManagedHookEntries(platform, hooksDir, repoRoot);
|
|
19
46
|
for (const { event, definition } of managedEntries) {
|
|
@@ -24,3 +51,11 @@ export function mergeCursorHooksFile(current, platform, hooksDir, repoRoot) {
|
|
|
24
51
|
}
|
|
25
52
|
return next;
|
|
26
53
|
}
|
|
54
|
+
export function hasDuplicateCursorShellGates(hooks, platform, hooksDir, repoRoot) {
|
|
55
|
+
const legacy = legacyManagedShellPreToolUseEntry(platform, hooksDir, repoRoot);
|
|
56
|
+
const preToolUse = hooks.hooks.preToolUse;
|
|
57
|
+
if (!Array.isArray(preToolUse)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return preToolUse.some((entry) => entryMatches(entry, legacy));
|
|
61
|
+
}
|
|
@@ -65,6 +65,7 @@ export async function runShellGateHook() {
|
|
|
65
65
|
kind: 'shell',
|
|
66
66
|
cwd,
|
|
67
67
|
command,
|
|
68
|
+
sourceEvent: 'beforeShellExecution',
|
|
68
69
|
});
|
|
69
70
|
jsonResponse(gateVerdictToCursorResponse(verdict));
|
|
70
71
|
}
|
|
@@ -87,6 +88,7 @@ export async function runToolGateHook(eventName) {
|
|
|
87
88
|
kind: 'subagent',
|
|
88
89
|
cwd,
|
|
89
90
|
payload,
|
|
91
|
+
sourceEvent: eventName,
|
|
90
92
|
});
|
|
91
93
|
jsonResponse(gateVerdictToCursorResponse(verdict));
|
|
92
94
|
return;
|
|
@@ -97,6 +99,7 @@ export async function runToolGateHook(eventName) {
|
|
|
97
99
|
cwd,
|
|
98
100
|
payload,
|
|
99
101
|
toolName,
|
|
102
|
+
sourceEvent: eventName,
|
|
100
103
|
});
|
|
101
104
|
jsonResponse(gateVerdictToCursorResponse(verdict));
|
|
102
105
|
return;
|
|
@@ -107,6 +110,7 @@ export async function runToolGateHook(eventName) {
|
|
|
107
110
|
cwd,
|
|
108
111
|
payload,
|
|
109
112
|
toolName,
|
|
113
|
+
sourceEvent: eventName,
|
|
110
114
|
});
|
|
111
115
|
jsonResponse(gateVerdictToCursorResponse(verdict));
|
|
112
116
|
return;
|
|
@@ -116,6 +120,7 @@ export async function runToolGateHook(eventName) {
|
|
|
116
120
|
kind: 'subagent',
|
|
117
121
|
cwd,
|
|
118
122
|
payload,
|
|
123
|
+
sourceEvent: eventName,
|
|
119
124
|
});
|
|
120
125
|
jsonResponse(gateVerdictToCursorResponse(verdict));
|
|
121
126
|
return;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ApprovalReplayHint } from '../../core/approval-replay.js';
|
|
2
|
+
import { type ExecuteContainedDockerParams, executeContainedDocker } from '../../core/contained-execution/docker.js';
|
|
3
|
+
import { type ContainedExecutionMirrorHandle, type ContainedExecutionMirrorOptions } from '../../core/contained-execution/mirror.js';
|
|
2
4
|
import { type GatedActionKind, type GatePermissionResponse, type GateVerdict } from '../../core/gate-contract.js';
|
|
3
5
|
import { GateNormalizationError } from '../../core/gate-engine.js';
|
|
4
6
|
import { type BelayConfigV3 } from '../../core/index.js';
|
|
@@ -30,6 +32,9 @@ export interface GateRuntimeDeps {
|
|
|
30
32
|
stdout?: string;
|
|
31
33
|
stderr?: string;
|
|
32
34
|
}>;
|
|
35
|
+
readSignedAttestation: (filePath: string) => Promise<unknown>;
|
|
36
|
+
withContainedExecutionMirror: <T>(options: ContainedExecutionMirrorOptions, operation: (mirror: ContainedExecutionMirrorHandle) => Promise<T>) => Promise<T>;
|
|
37
|
+
executeContainedDocker: (params: ExecuteContainedDockerParams) => ReturnType<typeof executeContainedDocker>;
|
|
33
38
|
}
|
|
34
39
|
export declare function createDefaultGateRuntimeDeps(): GateRuntimeDeps;
|
|
35
40
|
export declare function resolveGateConfig(ctx: Pick<GateRuntimeContext, 'layout' | 'repoRoot' | 'configPath'>, deps: GateRuntimeDeps): Promise<BelayConfigV3>;
|
|
@@ -41,6 +46,7 @@ export declare function evaluateGatedAction(ctx: GateRuntimeContext, deps: GateR
|
|
|
41
46
|
command?: string;
|
|
42
47
|
payload?: Record<string, unknown>;
|
|
43
48
|
toolName?: string;
|
|
49
|
+
sourceEvent?: string;
|
|
44
50
|
}): Promise<GateVerdict>;
|
|
45
51
|
/** R39: unmapped Codex tools ask via pending approval — not hard deny without approval path. */
|
|
46
52
|
export declare function gateUnmappedToolVerdict(ctx: GateRuntimeContext, deps: GateRuntimeDeps, toolName: string, payload: Record<string, unknown>): Promise<GateVerdict>;
|