@scopebond/hook 0.8.1 → 0.9.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 +210 -0
- package/dist/budget-load.d.ts +68 -0
- package/dist/budget-load.d.ts.map +1 -0
- package/dist/budget-load.js +164 -0
- package/dist/budget-load.js.map +1 -0
- package/dist/capabilities.d.ts +103 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +212 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/classify.d.ts +17 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +78 -0
- package/dist/classify.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +523 -13
- package/dist/cli.js.map +1 -1
- package/dist/cloud.d.ts +8 -0
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js.map +1 -1
- package/dist/dispatch-cli.d.ts +2 -0
- package/dist/dispatch-cli.d.ts.map +1 -0
- package/dist/dispatch-cli.js +128 -0
- package/dist/dispatch-cli.js.map +1 -0
- package/dist/explain.d.ts.map +1 -1
- package/dist/explain.js +2 -1
- package/dist/explain.js.map +1 -1
- package/dist/group.d.ts +12 -0
- package/dist/group.d.ts.map +1 -0
- package/dist/group.js +55 -0
- package/dist/group.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +10 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +56 -0
- package/dist/install.js.map +1 -1
- package/dist/map.d.ts +4 -0
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +29 -1
- package/dist/map.js.map +1 -1
- package/dist/obs-emitter.d.ts +132 -0
- package/dist/obs-emitter.d.ts.map +1 -0
- package/dist/obs-emitter.js +415 -0
- package/dist/obs-emitter.js.map +1 -0
- package/dist/obs-store.d.ts +160 -0
- package/dist/obs-store.d.ts.map +1 -0
- package/dist/obs-store.js +367 -0
- package/dist/obs-store.js.map +1 -0
- package/dist/obs-upload.d.ts +24 -0
- package/dist/obs-upload.d.ts.map +1 -0
- package/dist/obs-upload.js +231 -0
- package/dist/obs-upload.js.map +1 -0
- package/dist/observation.d.ts +232 -0
- package/dist/observation.d.ts.map +1 -0
- package/dist/observation.js +308 -0
- package/dist/observation.js.map +1 -0
- package/dist/paths.d.ts +15 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +79 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy-load.d.ts +60 -0
- package/dist/policy-load.d.ts.map +1 -0
- package/dist/policy-load.js +151 -0
- package/dist/policy-load.js.map +1 -0
- package/dist/proof.d.ts +30 -0
- package/dist/proof.d.ts.map +1 -0
- package/dist/proof.js +186 -0
- package/dist/proof.js.map +1 -0
- package/dist/rules.d.ts +20 -0
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +50 -0
- package/dist/rules.js.map +1 -1
- package/dist/runtime.d.ts +18 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +74 -10
- package/dist/runtime.js.map +1 -1
- package/dist/scan.d.ts +7 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +38 -0
- package/dist/scan.js.map +1 -0
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +12 -3
- package/dist/shell.js.map +1 -1
- package/dist/sql-classify.d.ts +11 -0
- package/dist/sql-classify.d.ts.map +1 -0
- package/dist/sql-classify.js +251 -0
- package/dist/sql-classify.js.map +1 -0
- package/dist/typed-infra.d.ts +73 -0
- package/dist/typed-infra.d.ts.map +1 -0
- package/dist/typed-infra.js +758 -0
- package/dist/typed-infra.js.map +1 -0
- package/dist/typed-ops.d.ts +140 -0
- package/dist/typed-ops.d.ts.map +1 -0
- package/dist/typed-ops.js +549 -0
- package/dist/typed-ops.js.map +1 -0
- package/dist/vectors.d.ts +40 -0
- package/dist/vectors.d.ts.map +1 -0
- package/dist/vectors.js +219 -0
- package/dist/vectors.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Capability manifest: what this installed hook can honestly claim, cell by cell.
|
|
2
|
+
//
|
|
3
|
+
// A cell is keyed by connector + adapter version + host variant + action type + event
|
|
4
|
+
// phase. There is no global "supported" boolean: a connection can have verified shell
|
|
5
|
+
// coverage and unsupported browser coverage at the same time, and Codex, Claude Code and
|
|
6
|
+
// Cursor are separate cells because they hook different events at different times.
|
|
7
|
+
//
|
|
8
|
+
// The state is computed, never asserted:
|
|
9
|
+
//
|
|
10
|
+
// unsupported the adapter has no hook for this action, or it is known to
|
|
11
|
+
// escape interception (nested tool orchestration)
|
|
12
|
+
// inactive the adapter could cover it, but the harness is not configured
|
|
13
|
+
// configured_unverified configured, and either never proven or proven only by fixture
|
|
14
|
+
// verified_reporting a recorded proof that is current, passed, came from a real
|
|
15
|
+
// harness run, and was acknowledged by Cloud
|
|
16
|
+
// degraded a recorded proof for the current adapter and vectors failed
|
|
17
|
+
// retired a cell kept for history whose adapter no longer ships
|
|
18
|
+
//
|
|
19
|
+
// Only `verified_reporting` claims coverage. A local fixture run proves the adapter, the
|
|
20
|
+
// policy and the signatures on this machine; it does not prove that a particular host
|
|
21
|
+
// (Codex desktop, Claude desktop, Cursor) delivers the event, and it does not prove Cloud
|
|
22
|
+
// received the receipt, so a fixture proof alone never produces `verified_reporting`.
|
|
23
|
+
// For an observation-only action (Cursor's after-edit event) the proof is a known
|
|
24
|
+
// successful after-action fixture, labelled observation-only; no deny fixture is required
|
|
25
|
+
// or claimed, because nothing is prevented there.
|
|
26
|
+
import { createHash } from "node:crypto";
|
|
27
|
+
import { VECTORS } from "./vectors.js";
|
|
28
|
+
const GROUP_FIELDS = ["action_group", "action_group_size", "action_group_seq"];
|
|
29
|
+
const CLAUDE_HOSTS = ["claude_terminal", "claude_desktop"];
|
|
30
|
+
const CODEX_HOSTS = ["codex_cli", "codex_desktop"];
|
|
31
|
+
const NESTED = "nested_orchestration";
|
|
32
|
+
const SPECS = [
|
|
33
|
+
// Claude Code ---------------------------------------------------------------------
|
|
34
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "shell.exec", phase: "pre_action", via: "PreToolUse Bash/PowerShell/Shell", supported: true, fields: ["program", "command", ...GROUP_FIELDS], operations: ["program", "destructive_program", "opaque_program", "derived_file_read", "derived_file_write", "derived_git_push"] },
|
|
35
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "file.write", phase: "pre_action", via: "PreToolUse Write/Edit/MultiEdit/NotebookEdit", supported: true, fields: ["path", ...GROUP_FIELDS], operations: ["write", "protected_path", "ci_path", "root_scope_when_configured"] },
|
|
36
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "file.read", phase: "pre_action", via: "PreToolUse Read", supported: true, fields: ["path", ...GROUP_FIELDS], operations: ["read", "credential_path"] },
|
|
37
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "git.push", phase: "pre_action", via: "PreToolUse Bash (parsed git push)", supported: true, fields: ["ref", "force", ...GROUP_FIELDS], operations: ["push", "force", "delete", "refspec", "mirror_all", "unresolved_destination"] },
|
|
38
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "net.fetch", phase: "pre_action", via: "PreToolUse WebFetch", supported: true, observation_only: true, fields: ["host", "path", "method", ...GROUP_FIELDS], operations: ["fetch_get"] },
|
|
39
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "mcp.tool.call", phase: "pre_action", via: "PreToolUse mcp__server__tool", supported: true, observation_only: true, fields: ["server", "tool", "args_digest", ...GROUP_FIELDS], operations: ["tool_call"] },
|
|
40
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: NESTED, phase: "pre_action", via: "Task / sub-agent tools", supported: false, unsupported_reason: "a tool that runs nested calls is recorded as one unevaluated action; calls it makes inside are not shown to this adapter and are not claimed", fields: [], operations: [] },
|
|
41
|
+
// Codex ---------------------------------------------------------------------------
|
|
42
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "shell.exec", phase: "pre_action", via: "PreToolUse Bash/exec_command/unified_exec/PowerShell", supported: true, fields: ["program", "command", ...GROUP_FIELDS], operations: ["program", "destructive_program", "opaque_program", "derived_file_read", "derived_file_write", "derived_git_push"] },
|
|
43
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "file.write", phase: "pre_action", via: "PreToolUse apply_patch", supported: true, fields: ["path", ...GROUP_FIELDS], operations: ["write", "rename_destination", "protected_path", "ci_path", "root_scope_when_configured"] },
|
|
44
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "file.read", phase: "pre_action", via: "(no native read hook)", supported: false, unsupported_reason: "Codex sends no native file-read event; reads made through shell commands are derived under shell.exec, not claimed here", fields: [], operations: [] },
|
|
45
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "git.push", phase: "pre_action", via: "PreToolUse Bash (parsed git push)", supported: true, fields: ["ref", "force", ...GROUP_FIELDS], operations: ["push", "force", "delete", "refspec", "mirror_all", "unresolved_destination"] },
|
|
46
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "net.fetch", phase: "pre_action", via: "(no fetch hook)", supported: false, unsupported_reason: "Codex sends no network-fetch event to this adapter", fields: [], operations: [] },
|
|
47
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "mcp.tool.call", phase: "pre_action", via: "PreToolUse mcp__server__tool", supported: true, observation_only: true, fields: ["server", "tool", "args_digest", ...GROUP_FIELDS], operations: ["tool_call"] },
|
|
48
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: NESTED, phase: "pre_action", via: "sub-agent / nested tool wrappers", supported: false, unsupported_reason: "a wrapper that orchestrates nested calls has not been shown to route them through the hook, so it is not claimed", fields: [], operations: [] },
|
|
49
|
+
// Cursor (tested mode) --------------------------------------------------------------
|
|
50
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "shell.exec", phase: "pre_action", via: "beforeShellExecution", supported: true, fields: ["program", "command", ...GROUP_FIELDS], operations: ["program", "destructive_program", "opaque_program", "derived_file_read", "derived_file_write", "derived_git_push"] },
|
|
51
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "file.read", phase: "pre_action", via: "beforeReadFile", supported: true, fields: ["path", ...GROUP_FIELDS], operations: ["read", "credential_path"] },
|
|
52
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "file.write", phase: "pre_action", via: "(no before-edit hook)", supported: false, unsupported_reason: "Cursor has no before-edit event, so a write cannot be stopped there", fields: [], operations: [] },
|
|
53
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "file.write", phase: "after_action", via: "afterFileEdit", supported: true, observation_only: true, fields: ["path", ...GROUP_FIELDS], operations: ["observed_write"] },
|
|
54
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "git.push", phase: "pre_action", via: "beforeShellExecution (parsed git push)", supported: true, fields: ["ref", "force", ...GROUP_FIELDS], operations: ["push", "force", "delete", "refspec", "mirror_all", "unresolved_destination"] },
|
|
55
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "net.fetch", phase: "pre_action", via: "(no fetch hook)", supported: false, unsupported_reason: "Cursor sends no network-fetch event to this adapter", fields: [], operations: [] },
|
|
56
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "mcp.tool.call", phase: "pre_action", via: "beforeMCPExecution", supported: true, observation_only: true, fields: ["server", "tool", "args_digest", ...GROUP_FIELDS], operations: ["tool_call"] },
|
|
57
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: NESTED, phase: "pre_action", via: "nested tool wrappers", supported: false, unsupported_reason: "nested calls made inside a tool are not shown to this adapter and are not claimed", fields: [], operations: [] },
|
|
58
|
+
// Typed operations (observations, not receipts): the closed git, package and github_resource
|
|
59
|
+
// operations derived from the actual command before it runs. They are observation-only:
|
|
60
|
+
// they describe what was dispatched and never gate it. A fixture proves the derivation on
|
|
61
|
+
// this machine only; it does not prove the host delivers the event or that the workspace
|
|
62
|
+
// accepted it, so these cells stay configured_unverified until a real-host proof exists.
|
|
63
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "git.commit", phase: "pre_action", via: "PreToolUse Bash/PowerShell (git commit)", supported: true, observation_only: true, fields: ["repository_id", "refs", "force", "head_sha", "resolution", "remote_id"], operations: ["commit"] },
|
|
64
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "package.install", phase: "pre_action", via: "PreToolUse Bash/PowerShell (npm, pnpm, yarn, pip, uv with named packages)", supported: true, observation_only: true, fields: ["manager", "manager_version", "packages", "lifecycle_scripts"], operations: ["install", "add", "update"] },
|
|
65
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "github.resource", phase: "pre_action", via: "PreToolUse Bash/PowerShell (gh) and mcp__github__ tools", supported: true, observation_only: true, fields: ["repository_id", "base_sha", "head_sha", "release_digest", "required_check_policy_version"], operations: ["pr_create", "release_create"] },
|
|
66
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "github.pr_change", phase: "pre_action", via: "gh pr edit / gh pr merge, merge_pull_request", supported: false, unsupported_reason: "a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform", fields: [], operations: [] },
|
|
67
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "deploy.run", phase: "pre_action", via: "(no deploy adapter)", supported: false, unsupported_reason: "a deploy operation carries check results that only an independent platform source can supply; this hook is not one", fields: [], operations: [] },
|
|
68
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "git.commit", phase: "pre_action", via: "PreToolUse Bash (git commit)", supported: true, observation_only: true, fields: ["repository_id", "refs", "force", "head_sha", "resolution", "remote_id"], operations: ["commit"] },
|
|
69
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "package.install", phase: "pre_action", via: "PreToolUse Bash (npm, pnpm, yarn, pip, uv with named packages)", supported: true, observation_only: true, fields: ["manager", "manager_version", "packages", "lifecycle_scripts"], operations: ["install", "add", "update"] },
|
|
70
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "github.resource", phase: "pre_action", via: "PreToolUse Bash (gh) and mcp__github__ tools", supported: true, observation_only: true, fields: ["repository_id", "base_sha", "head_sha", "release_digest", "required_check_policy_version"], operations: ["pr_create", "release_create"] },
|
|
71
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "github.pr_change", phase: "pre_action", via: "gh pr edit / gh pr merge, merge_pull_request", supported: false, unsupported_reason: "a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform", fields: [], operations: [] },
|
|
72
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "deploy.run", phase: "pre_action", via: "(no deploy adapter)", supported: false, unsupported_reason: "a deploy operation carries check results that only an independent platform source can supply; this hook is not one", fields: [], operations: [] },
|
|
73
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "git.commit", phase: "pre_action", via: "beforeShellExecution (git commit)", supported: true, observation_only: true, fields: ["repository_id", "refs", "force", "head_sha", "resolution", "remote_id"], operations: ["commit"] },
|
|
74
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "package.install", phase: "pre_action", via: "beforeShellExecution (npm, pnpm, yarn, pip, uv with named packages)", supported: true, observation_only: true, fields: ["manager", "manager_version", "packages", "lifecycle_scripts"], operations: ["install", "add", "update"] },
|
|
75
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "github.resource", phase: "pre_action", via: "beforeShellExecution (gh) and beforeMCPExecution github tools", supported: true, observation_only: true, fields: ["repository_id", "base_sha", "head_sha", "release_digest", "required_check_policy_version"], operations: ["pr_create", "release_create"] },
|
|
76
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "github.pr_change", phase: "pre_action", via: "gh pr edit / gh pr merge, merge_pull_request", supported: false, unsupported_reason: "a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform", fields: [], operations: [] },
|
|
77
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "deploy.run", phase: "pre_action", via: "(no deploy adapter)", supported: false, unsupported_reason: "a deploy operation carries check results that only an independent platform source can supply; this hook is not one", fields: [], operations: [] },
|
|
78
|
+
// Network, Cloudflare and database operations (MP11): observation-only, derived from the actual
|
|
79
|
+
// command (or, for a Claude Code WebFetch, the tool input) before it runs. Fixtures prove the
|
|
80
|
+
// derivation on this machine; no real-host proof exists yet, so these stay configured_unverified.
|
|
81
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "network.request", phase: "pre_action", via: "PreToolUse Bash/PowerShell (curl, wget, Invoke-WebRequest, Invoke-RestMethod) and WebFetch", supported: true, observation_only: true, fields: ["scheme", "host", "port", "method", "net_operation"], operations: ["read", "write", "upload"] },
|
|
82
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "cloudflare.resource", phase: "pre_action", via: "PreToolUse Bash/PowerShell (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)", supported: true, observation_only: true, fields: ["resource_kind", "account_id", "environment_binding", "artifact_digest", "visibility_before", "visibility_after"], operations: ["create", "update", "write", "delete", "set_visibility"] },
|
|
83
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "database.exec", phase: "pre_action", via: "PreToolUse Bash/PowerShell (wrangler d1 execute and migrations apply, psql, sqlite3)", supported: true, observation_only: true, fields: ["provider", "verb", "predicate_class", "database_id", "migration_digest"], operations: ["read", "insert", "update", "delete", "delete_all", "create", "alter", "drop", "migrate"] },
|
|
84
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "browser.action", phase: "pre_action", via: "(no browser hook)", supported: false, unsupported_reason: "no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed", fields: [], operations: [] },
|
|
85
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "communication.send", phase: "pre_action", via: "(no communications adapter)", supported: false, unsupported_reason: "mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived", fields: [], operations: [] },
|
|
86
|
+
{ adapter: "claude", host_variants: CLAUDE_HOSTS, action_type: "visibility.change", phase: "pre_action", via: "(no visibility source)", supported: false, unsupported_reason: "no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown", fields: [], operations: [] },
|
|
87
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "network.request", phase: "pre_action", via: "PreToolUse Bash/exec_command/unified_exec/PowerShell (curl, wget, Invoke-WebRequest, Invoke-RestMethod)", supported: true, observation_only: true, fields: ["scheme", "host", "port", "method", "net_operation"], operations: ["read", "write", "upload"] },
|
|
88
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "cloudflare.resource", phase: "pre_action", via: "PreToolUse Bash/exec_command/unified_exec/PowerShell (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)", supported: true, observation_only: true, fields: ["resource_kind", "account_id", "environment_binding", "artifact_digest", "visibility_before", "visibility_after"], operations: ["create", "update", "write", "delete", "set_visibility"] },
|
|
89
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "database.exec", phase: "pre_action", via: "PreToolUse Bash/exec_command/unified_exec/PowerShell (wrangler d1 execute and migrations apply, psql, sqlite3)", supported: true, observation_only: true, fields: ["provider", "verb", "predicate_class", "database_id", "migration_digest"], operations: ["read", "insert", "update", "delete", "delete_all", "create", "alter", "drop", "migrate"] },
|
|
90
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "browser.action", phase: "pre_action", via: "(no browser hook)", supported: false, unsupported_reason: "no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed", fields: [], operations: [] },
|
|
91
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "communication.send", phase: "pre_action", via: "(no communications adapter)", supported: false, unsupported_reason: "mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived", fields: [], operations: [] },
|
|
92
|
+
{ adapter: "codex", host_variants: CODEX_HOSTS, action_type: "visibility.change", phase: "pre_action", via: "(no visibility source)", supported: false, unsupported_reason: "no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown", fields: [], operations: [] },
|
|
93
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "network.request", phase: "pre_action", via: "beforeShellExecution (curl, wget, Invoke-WebRequest, Invoke-RestMethod)", supported: true, observation_only: true, fields: ["scheme", "host", "port", "method", "net_operation"], operations: ["read", "write", "upload"] },
|
|
94
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "cloudflare.resource", phase: "pre_action", via: "beforeShellExecution (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)", supported: true, observation_only: true, fields: ["resource_kind", "account_id", "environment_binding", "artifact_digest", "visibility_before", "visibility_after"], operations: ["create", "update", "write", "delete", "set_visibility"] },
|
|
95
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "database.exec", phase: "pre_action", via: "beforeShellExecution (wrangler d1 execute and migrations apply, psql, sqlite3)", supported: true, observation_only: true, fields: ["provider", "verb", "predicate_class", "database_id", "migration_digest"], operations: ["read", "insert", "update", "delete", "delete_all", "create", "alter", "drop", "migrate"] },
|
|
96
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "browser.action", phase: "pre_action", via: "(no browser hook)", supported: false, unsupported_reason: "no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed", fields: [], operations: [] },
|
|
97
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "communication.send", phase: "pre_action", via: "(no communications adapter)", supported: false, unsupported_reason: "mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived", fields: [], operations: [] },
|
|
98
|
+
{ adapter: "cursor", host_variants: ["cursor"], action_type: "visibility.change", phase: "pre_action", via: "(no visibility source)", supported: false, unsupported_reason: "no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown", fields: [], operations: [] },
|
|
99
|
+
];
|
|
100
|
+
export const cellKey = (adapterVersion, host, actionType, phase) => `scopebond-hook@${adapterVersion}/${host}/${actionType}/${phase}`;
|
|
101
|
+
/** The vectors that prove one cell: those tagged with its action type for its adapter. For
|
|
102
|
+
* the after-action cell only the after-action vector counts. */
|
|
103
|
+
export function vectorsForCell(adapter, actionType, phase) {
|
|
104
|
+
return VECTORS.filter((v) => v.agent === adapter && v.cell?.action_type === actionType
|
|
105
|
+
&& (phase === "after_action" ? v.cell.role === "after_action" : v.cell.role !== "after_action"));
|
|
106
|
+
}
|
|
107
|
+
/** Digest of a cell's vectors (id, payload and expectation). A proof recorded against one
|
|
108
|
+
* digest says nothing about a changed set. */
|
|
109
|
+
export function vectorDigest(vectors) {
|
|
110
|
+
if (vectors.length === 0)
|
|
111
|
+
return null;
|
|
112
|
+
const canonical = JSON.stringify([...vectors].sort((a, b) => a.id.localeCompare(b.id)).map((v) => [v.id, v.event ?? null, v.input, v.expect, v.catalog, v.unknown === true]));
|
|
113
|
+
return `sha256:${createHash("sha256").update(canonical).digest("hex")}`;
|
|
114
|
+
}
|
|
115
|
+
/** The gaps the cell's vectors document, plus the always-true program-only limit. */
|
|
116
|
+
function gapsFor(adapter, actionType) {
|
|
117
|
+
const gaps = new Set();
|
|
118
|
+
for (const v of VECTORS)
|
|
119
|
+
if (v.gap && v.agent === adapter && (actionType === "shell.exec" ? v.rule === "R09" || v.rule === "R10" || v.rule === "R06" : false))
|
|
120
|
+
gaps.add(v.gap);
|
|
121
|
+
return [...gaps];
|
|
122
|
+
}
|
|
123
|
+
/** Compute the state of one cell from what is configured and what has been proven. */
|
|
124
|
+
export function cellState(input) {
|
|
125
|
+
if (input.retired)
|
|
126
|
+
return { state: "retired", reason: "this adapter no longer ships; kept for history" };
|
|
127
|
+
if (!input.supported)
|
|
128
|
+
return { state: "unsupported", reason: input.unsupportedReason ?? "no hook for this action" };
|
|
129
|
+
if (!input.configured)
|
|
130
|
+
return { state: "inactive", reason: "the hook is not configured for this harness" };
|
|
131
|
+
if (input.digest === null)
|
|
132
|
+
return { state: "configured_unverified", reason: "configured; no test vectors exist for this cell, so it cannot be proven" };
|
|
133
|
+
const proof = input.proof;
|
|
134
|
+
if (!proof)
|
|
135
|
+
return { state: "configured_unverified", reason: "configured; not yet proven (run `scopebond capabilities --prove`)" };
|
|
136
|
+
if (proof.adapter_version !== input.adapterVersion || proof.test_vector_digest !== input.digest) {
|
|
137
|
+
return { state: "configured_unverified", reason: "the recorded proof is for a different adapter version or vector set; run it again" };
|
|
138
|
+
}
|
|
139
|
+
const denyOk = input.observationOnly ? proof.safe_deny === "not_applicable" : proof.safe_deny === true;
|
|
140
|
+
if (!proof.safe_allow || !denyOk || !proof.signature || !proof.grouping || proof.typed_operation === false) {
|
|
141
|
+
return { state: "degraded", reason: `the current proof failed: ${[!proof.safe_allow && "safe allow", !denyOk && "safe deny", !proof.signature && "signature", !proof.grouping && "grouping", proof.typed_operation === false && "typed operation"].filter(Boolean).join(", ")}` };
|
|
142
|
+
}
|
|
143
|
+
if (proof.origin !== "live_harness") {
|
|
144
|
+
return { state: "configured_unverified", reason: `${input.observationOnly ? "observation-only fixture" : "local fixture"} passed; a real ${"host"} run and Cloud acknowledgement are still outstanding` };
|
|
145
|
+
}
|
|
146
|
+
if (proof.cloud_ack !== "acknowledged") {
|
|
147
|
+
return { state: "configured_unverified", reason: proof.cloud_ack === "failed" ? "Cloud did not acknowledge the proof receipt" : "real-host proof passed; Cloud acknowledgement outstanding" };
|
|
148
|
+
}
|
|
149
|
+
return { state: "verified_reporting", reason: input.observationOnly ? "observation-only: a known successful after-action receipt was acknowledged" : "safe allow, safe deny, signature and Cloud acknowledgement all recorded" };
|
|
150
|
+
}
|
|
151
|
+
/** The manifest for the installed hook. Pure: no filesystem, no clock beyond `now`. */
|
|
152
|
+
export function computeManifest(input) {
|
|
153
|
+
const cells = [];
|
|
154
|
+
for (const spec of SPECS) {
|
|
155
|
+
const vectors = spec.supported ? vectorsForCell(spec.adapter, spec.action_type, spec.phase) : [];
|
|
156
|
+
const digest = vectorDigest(vectors);
|
|
157
|
+
for (const host of spec.host_variants) {
|
|
158
|
+
const key = cellKey(input.adapterVersion, host, spec.action_type, spec.phase);
|
|
159
|
+
const proof = input.proofs?.[key] ?? null;
|
|
160
|
+
const observationOnly = spec.observation_only === true;
|
|
161
|
+
const { state, reason } = cellState({
|
|
162
|
+
supported: spec.supported, unsupportedReason: spec.unsupported_reason, configured: input.configured[spec.adapter],
|
|
163
|
+
digest, adapterVersion: input.adapterVersion, proof, observationOnly, retired: input.retired?.includes(key),
|
|
164
|
+
});
|
|
165
|
+
cells.push({
|
|
166
|
+
key, connector: "scopebond-hook", adapter_version: input.adapterVersion, host_variant: host,
|
|
167
|
+
action_type: spec.action_type, event_phase: spec.phase, state, reason,
|
|
168
|
+
pre_action: spec.supported && spec.phase === "pre_action",
|
|
169
|
+
after_action: spec.supported && spec.phase === "after_action",
|
|
170
|
+
boundary: spec.supported && spec.phase === "pre_action" && !observationOnly ? "harness_hook" : "none",
|
|
171
|
+
observation_only: observationOnly,
|
|
172
|
+
emitted_required_fields: spec.fields, supported_operations: spec.operations,
|
|
173
|
+
known_gaps: spec.supported ? gapsFor(spec.adapter, spec.action_type) : [],
|
|
174
|
+
min_runtime: { node: ">=22.13" },
|
|
175
|
+
test_vector_digest: digest, last_proof: proof,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { connector: "scopebond-hook", adapter_version: input.adapterVersion, generated_at: (input.now ?? new Date()).toISOString(), cells };
|
|
180
|
+
}
|
|
181
|
+
/** The spec for a cell key, for the proof runner. */
|
|
182
|
+
export function specForCell(cell) {
|
|
183
|
+
const spec = SPECS.find((s) => s.action_type === cell.action_type && s.phase === cell.event_phase && s.host_variants.includes(cell.host_variant));
|
|
184
|
+
return spec ? { adapter: spec.adapter, action_type: spec.action_type, phase: spec.phase } : null;
|
|
185
|
+
}
|
|
186
|
+
const VIA = new Map(SPECS.flatMap((s) => s.host_variants.map((h) => [`${h}/${s.action_type}/${s.phase}`, s.via])));
|
|
187
|
+
/** Plain-text rendering. Unsupported stays unsupported; nothing here upgrades a state. */
|
|
188
|
+
export function renderManifest(manifest) {
|
|
189
|
+
const lines = [];
|
|
190
|
+
lines.push(`Capability manifest — scopebond-hook ${manifest.adapter_version}`);
|
|
191
|
+
lines.push("A state is only ever what a recorded proof supports. A local fixture never makes a cell verified.");
|
|
192
|
+
const hosts = [...new Set(manifest.cells.map((c) => c.host_variant))];
|
|
193
|
+
for (const host of hosts) {
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push(host);
|
|
196
|
+
for (const cell of manifest.cells.filter((c) => c.host_variant === host)) {
|
|
197
|
+
const phase = cell.event_phase === "after_action" ? "after action" : "before action";
|
|
198
|
+
const via = VIA.get(`${host}/${cell.action_type}/${cell.event_phase}`);
|
|
199
|
+
lines.push(` ${cell.action_type.padEnd(21)} ${phase.padEnd(13)} ${cell.state.padEnd(21)}${cell.observation_only ? " observation-only" : ""}`);
|
|
200
|
+
lines.push(` ${cell.reason}${via ? ` [${via}]` : ""}`);
|
|
201
|
+
for (const gap of cell.known_gaps)
|
|
202
|
+
lines.push(` limit: ${gap}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const counts = new Map();
|
|
206
|
+
for (const cell of manifest.cells)
|
|
207
|
+
counts.set(cell.state, (counts.get(cell.state) ?? 0) + 1);
|
|
208
|
+
lines.push("");
|
|
209
|
+
lines.push(`Summary: ${[...counts].map(([state, n]) => `${n} ${state}`).join(", ")}`);
|
|
210
|
+
return lines.join("\n");
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Capability manifest: what this installed hook can honestly claim, cell by cell.\n//\n// A cell is keyed by connector + adapter version + host variant + action type + event\n// phase. There is no global \"supported\" boolean: a connection can have verified shell\n// coverage and unsupported browser coverage at the same time, and Codex, Claude Code and\n// Cursor are separate cells because they hook different events at different times.\n//\n// The state is computed, never asserted:\n//\n// unsupported the adapter has no hook for this action, or it is known to\n// escape interception (nested tool orchestration)\n// inactive the adapter could cover it, but the harness is not configured\n// configured_unverified configured, and either never proven or proven only by fixture\n// verified_reporting a recorded proof that is current, passed, came from a real\n// harness run, and was acknowledged by Cloud\n// degraded a recorded proof for the current adapter and vectors failed\n// retired a cell kept for history whose adapter no longer ships\n//\n// Only `verified_reporting` claims coverage. A local fixture run proves the adapter, the\n// policy and the signatures on this machine; it does not prove that a particular host\n// (Codex desktop, Claude desktop, Cursor) delivers the event, and it does not prove Cloud\n// received the receipt, so a fixture proof alone never produces `verified_reporting`.\n// For an observation-only action (Cursor's after-edit event) the proof is a known\n// successful after-action fixture, labelled observation-only; no deny fixture is required\n// or claimed, because nothing is prevented there.\n\nimport { createHash } from \"node:crypto\";\nimport { VECTORS, type Vector, type VectorAgent } from \"./vectors.js\";\n\nexport type CapabilityState =\n | \"unsupported\" | \"configured_unverified\" | \"verified_reporting\" | \"degraded\" | \"inactive\" | \"retired\";\n\nexport type HostVariant = \"claude_terminal\" | \"claude_desktop\" | \"codex_cli\" | \"codex_desktop\" | \"cursor\";\nexport type EventPhase = \"pre_action\" | \"after_action\";\nexport type Adapter = VectorAgent;\n\n/** The outcome of running a cell's fixtures. */\nexport interface ProofRecord {\n cell: string;\n ran_at: string;\n adapter_version: string;\n test_vector_digest: string;\n /** `fixture`: local run against temp state. `live_harness`: recorded from a real host. */\n origin: \"fixture\" | \"live_harness\";\n /** A benign action was allowed and produced a countersigned receipt. */\n safe_allow: boolean;\n /** A violating action was denied at the claimed boundary, or `not_applicable`. */\n safe_deny: boolean | \"not_applicable\";\n /** Every receipt from the fixtures verified against the countersigning key. */\n signature: boolean;\n /** Every receipt of one tool call carried the same action group. */\n grouping: boolean;\n /** Cloud acknowledgement. Never `acknowledged` from a local fixture run. */\n cloud_ack: \"not_checked\" | \"acknowledged\" | \"failed\";\n observation_only: boolean;\n /** `source_receipt_hash` of the fixture receipts whose action type is this cell's (allow\n * fixtures, and deny fixtures for a before-action cell). Empty when none matched. */\n proof_digests?: string[];\n /** Typed-operation cells only: every fixture derived the closed operation it expects. */\n typed_operation?: boolean;\n}\n\nexport interface CapabilityCell {\n key: string;\n connector: \"scopebond-hook\";\n adapter_version: string;\n host_variant: HostVariant;\n action_type: string;\n event_phase: EventPhase;\n state: CapabilityState;\n /** Why the cell is in this state, in plain words. */\n reason: string;\n pre_action: boolean;\n after_action: boolean;\n /** Where enforcement happens: the harness's own hook, or nowhere. */\n boundary: \"harness_hook\" | \"none\";\n observation_only: boolean;\n emitted_required_fields: string[];\n supported_operations: string[];\n /** Limits the vectors document; repeated here rather than hidden. */\n known_gaps: string[];\n min_runtime: { node: string };\n test_vector_digest: string | null;\n last_proof: ProofRecord | null;\n}\n\nexport interface Manifest {\n connector: \"scopebond-hook\";\n adapter_version: string;\n generated_at: string;\n cells: CapabilityCell[];\n}\n\ninterface CellSpec {\n adapter: Adapter;\n host_variants: HostVariant[];\n action_type: string;\n phase: EventPhase;\n /** Which harness event(s) carry it, for the reader. */\n via: string;\n supported: boolean;\n unsupported_reason?: string;\n observation_only?: boolean;\n fields: string[];\n operations: string[];\n}\n\nconst GROUP_FIELDS = [\"action_group\", \"action_group_size\", \"action_group_seq\"];\nconst CLAUDE_HOSTS: HostVariant[] = [\"claude_terminal\", \"claude_desktop\"];\nconst CODEX_HOSTS: HostVariant[] = [\"codex_cli\", \"codex_desktop\"];\n\nconst NESTED = \"nested_orchestration\";\n\nconst SPECS: CellSpec[] = [\n // Claude Code ---------------------------------------------------------------------\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"shell.exec\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell/Shell\", supported: true, fields: [\"program\", \"command\", ...GROUP_FIELDS], operations: [\"program\", \"destructive_program\", \"opaque_program\", \"derived_file_read\", \"derived_file_write\", \"derived_git_push\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"file.write\", phase: \"pre_action\", via: \"PreToolUse Write/Edit/MultiEdit/NotebookEdit\", supported: true, fields: [\"path\", ...GROUP_FIELDS], operations: [\"write\", \"protected_path\", \"ci_path\", \"root_scope_when_configured\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"file.read\", phase: \"pre_action\", via: \"PreToolUse Read\", supported: true, fields: [\"path\", ...GROUP_FIELDS], operations: [\"read\", \"credential_path\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"git.push\", phase: \"pre_action\", via: \"PreToolUse Bash (parsed git push)\", supported: true, fields: [\"ref\", \"force\", ...GROUP_FIELDS], operations: [\"push\", \"force\", \"delete\", \"refspec\", \"mirror_all\", \"unresolved_destination\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"net.fetch\", phase: \"pre_action\", via: \"PreToolUse WebFetch\", supported: true, observation_only: true, fields: [\"host\", \"path\", \"method\", ...GROUP_FIELDS], operations: [\"fetch_get\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"mcp.tool.call\", phase: \"pre_action\", via: \"PreToolUse mcp__server__tool\", supported: true, observation_only: true, fields: [\"server\", \"tool\", \"args_digest\", ...GROUP_FIELDS], operations: [\"tool_call\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: NESTED, phase: \"pre_action\", via: \"Task / sub-agent tools\", supported: false, unsupported_reason: \"a tool that runs nested calls is recorded as one unevaluated action; calls it makes inside are not shown to this adapter and are not claimed\", fields: [], operations: [] },\n // Codex ---------------------------------------------------------------------------\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"shell.exec\", phase: \"pre_action\", via: \"PreToolUse Bash/exec_command/unified_exec/PowerShell\", supported: true, fields: [\"program\", \"command\", ...GROUP_FIELDS], operations: [\"program\", \"destructive_program\", \"opaque_program\", \"derived_file_read\", \"derived_file_write\", \"derived_git_push\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"file.write\", phase: \"pre_action\", via: \"PreToolUse apply_patch\", supported: true, fields: [\"path\", ...GROUP_FIELDS], operations: [\"write\", \"rename_destination\", \"protected_path\", \"ci_path\", \"root_scope_when_configured\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"file.read\", phase: \"pre_action\", via: \"(no native read hook)\", supported: false, unsupported_reason: \"Codex sends no native file-read event; reads made through shell commands are derived under shell.exec, not claimed here\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"git.push\", phase: \"pre_action\", via: \"PreToolUse Bash (parsed git push)\", supported: true, fields: [\"ref\", \"force\", ...GROUP_FIELDS], operations: [\"push\", \"force\", \"delete\", \"refspec\", \"mirror_all\", \"unresolved_destination\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"net.fetch\", phase: \"pre_action\", via: \"(no fetch hook)\", supported: false, unsupported_reason: \"Codex sends no network-fetch event to this adapter\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"mcp.tool.call\", phase: \"pre_action\", via: \"PreToolUse mcp__server__tool\", supported: true, observation_only: true, fields: [\"server\", \"tool\", \"args_digest\", ...GROUP_FIELDS], operations: [\"tool_call\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: NESTED, phase: \"pre_action\", via: \"sub-agent / nested tool wrappers\", supported: false, unsupported_reason: \"a wrapper that orchestrates nested calls has not been shown to route them through the hook, so it is not claimed\", fields: [], operations: [] },\n // Cursor (tested mode) --------------------------------------------------------------\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"shell.exec\", phase: \"pre_action\", via: \"beforeShellExecution\", supported: true, fields: [\"program\", \"command\", ...GROUP_FIELDS], operations: [\"program\", \"destructive_program\", \"opaque_program\", \"derived_file_read\", \"derived_file_write\", \"derived_git_push\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"file.read\", phase: \"pre_action\", via: \"beforeReadFile\", supported: true, fields: [\"path\", ...GROUP_FIELDS], operations: [\"read\", \"credential_path\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"file.write\", phase: \"pre_action\", via: \"(no before-edit hook)\", supported: false, unsupported_reason: \"Cursor has no before-edit event, so a write cannot be stopped there\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"file.write\", phase: \"after_action\", via: \"afterFileEdit\", supported: true, observation_only: true, fields: [\"path\", ...GROUP_FIELDS], operations: [\"observed_write\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"git.push\", phase: \"pre_action\", via: \"beforeShellExecution (parsed git push)\", supported: true, fields: [\"ref\", \"force\", ...GROUP_FIELDS], operations: [\"push\", \"force\", \"delete\", \"refspec\", \"mirror_all\", \"unresolved_destination\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"net.fetch\", phase: \"pre_action\", via: \"(no fetch hook)\", supported: false, unsupported_reason: \"Cursor sends no network-fetch event to this adapter\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"mcp.tool.call\", phase: \"pre_action\", via: \"beforeMCPExecution\", supported: true, observation_only: true, fields: [\"server\", \"tool\", \"args_digest\", ...GROUP_FIELDS], operations: [\"tool_call\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: NESTED, phase: \"pre_action\", via: \"nested tool wrappers\", supported: false, unsupported_reason: \"nested calls made inside a tool are not shown to this adapter and are not claimed\", fields: [], operations: [] },\n // Typed operations (observations, not receipts): the closed git, package and github_resource\n // operations derived from the actual command before it runs. They are observation-only:\n // they describe what was dispatched and never gate it. A fixture proves the derivation on\n // this machine only; it does not prove the host delivers the event or that the workspace\n // accepted it, so these cells stay configured_unverified until a real-host proof exists.\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"git.commit\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (git commit)\", supported: true, observation_only: true, fields: [\"repository_id\",\"refs\",\"force\",\"head_sha\",\"resolution\",\"remote_id\"], operations: [\"commit\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"package.install\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (npm, pnpm, yarn, pip, uv with named packages)\", supported: true, observation_only: true, fields: [\"manager\",\"manager_version\",\"packages\",\"lifecycle_scripts\"], operations: [\"install\",\"add\",\"update\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"github.resource\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (gh) and mcp__github__ tools\", supported: true, observation_only: true, fields: [\"repository_id\",\"base_sha\",\"head_sha\",\"release_digest\",\"required_check_policy_version\"], operations: [\"pr_create\",\"release_create\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"github.pr_change\", phase: \"pre_action\", via: \"gh pr edit / gh pr merge, merge_pull_request\", supported: false, unsupported_reason: \"a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform\", fields: [], operations: [] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"deploy.run\", phase: \"pre_action\", via: \"(no deploy adapter)\", supported: false, unsupported_reason: \"a deploy operation carries check results that only an independent platform source can supply; this hook is not one\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"git.commit\", phase: \"pre_action\", via: \"PreToolUse Bash (git commit)\", supported: true, observation_only: true, fields: [\"repository_id\",\"refs\",\"force\",\"head_sha\",\"resolution\",\"remote_id\"], operations: [\"commit\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"package.install\", phase: \"pre_action\", via: \"PreToolUse Bash (npm, pnpm, yarn, pip, uv with named packages)\", supported: true, observation_only: true, fields: [\"manager\",\"manager_version\",\"packages\",\"lifecycle_scripts\"], operations: [\"install\",\"add\",\"update\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"github.resource\", phase: \"pre_action\", via: \"PreToolUse Bash (gh) and mcp__github__ tools\", supported: true, observation_only: true, fields: [\"repository_id\",\"base_sha\",\"head_sha\",\"release_digest\",\"required_check_policy_version\"], operations: [\"pr_create\",\"release_create\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"github.pr_change\", phase: \"pre_action\", via: \"gh pr edit / gh pr merge, merge_pull_request\", supported: false, unsupported_reason: \"a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"deploy.run\", phase: \"pre_action\", via: \"(no deploy adapter)\", supported: false, unsupported_reason: \"a deploy operation carries check results that only an independent platform source can supply; this hook is not one\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"git.commit\", phase: \"pre_action\", via: \"beforeShellExecution (git commit)\", supported: true, observation_only: true, fields: [\"repository_id\",\"refs\",\"force\",\"head_sha\",\"resolution\",\"remote_id\"], operations: [\"commit\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"package.install\", phase: \"pre_action\", via: \"beforeShellExecution (npm, pnpm, yarn, pip, uv with named packages)\", supported: true, observation_only: true, fields: [\"manager\",\"manager_version\",\"packages\",\"lifecycle_scripts\"], operations: [\"install\",\"add\",\"update\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"github.resource\", phase: \"pre_action\", via: \"beforeShellExecution (gh) and beforeMCPExecution github tools\", supported: true, observation_only: true, fields: [\"repository_id\",\"base_sha\",\"head_sha\",\"release_digest\",\"required_check_policy_version\"], operations: [\"pr_create\",\"release_create\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"github.pr_change\", phase: \"pre_action\", via: \"gh pr edit / gh pr merge, merge_pull_request\", supported: false, unsupported_reason: \"a pull request named only by number has no head or base commit in the request; recording pr_update and pr_merge needs a platform read-back this hook does not perform\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"deploy.run\", phase: \"pre_action\", via: \"(no deploy adapter)\", supported: false, unsupported_reason: \"a deploy operation carries check results that only an independent platform source can supply; this hook is not one\", fields: [], operations: [] },\n // Network, Cloudflare and database operations (MP11): observation-only, derived from the actual\n // command (or, for a Claude Code WebFetch, the tool input) before it runs. Fixtures prove the\n // derivation on this machine; no real-host proof exists yet, so these stay configured_unverified.\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"network.request\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (curl, wget, Invoke-WebRequest, Invoke-RestMethod) and WebFetch\", supported: true, observation_only: true, fields: [\"scheme\",\"host\",\"port\",\"method\",\"net_operation\"], operations: [\"read\",\"write\",\"upload\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"cloudflare.resource\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)\", supported: true, observation_only: true, fields: [\"resource_kind\",\"account_id\",\"environment_binding\",\"artifact_digest\",\"visibility_before\",\"visibility_after\"], operations: [\"create\",\"update\",\"write\",\"delete\",\"set_visibility\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"database.exec\", phase: \"pre_action\", via: \"PreToolUse Bash/PowerShell (wrangler d1 execute and migrations apply, psql, sqlite3)\", supported: true, observation_only: true, fields: [\"provider\",\"verb\",\"predicate_class\",\"database_id\",\"migration_digest\"], operations: [\"read\",\"insert\",\"update\",\"delete\",\"delete_all\",\"create\",\"alter\",\"drop\",\"migrate\"] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"browser.action\", phase: \"pre_action\", via: \"(no browser hook)\", supported: false, unsupported_reason: \"no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed\", fields: [], operations: [] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"communication.send\", phase: \"pre_action\", via: \"(no communications adapter)\", supported: false, unsupported_reason: \"mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived\", fields: [], operations: [] },\n { adapter: \"claude\", host_variants: CLAUDE_HOSTS, action_type: \"visibility.change\", phase: \"pre_action\", via: \"(no visibility source)\", supported: false, unsupported_reason: \"no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"network.request\", phase: \"pre_action\", via: \"PreToolUse Bash/exec_command/unified_exec/PowerShell (curl, wget, Invoke-WebRequest, Invoke-RestMethod)\", supported: true, observation_only: true, fields: [\"scheme\",\"host\",\"port\",\"method\",\"net_operation\"], operations: [\"read\",\"write\",\"upload\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"cloudflare.resource\", phase: \"pre_action\", via: \"PreToolUse Bash/exec_command/unified_exec/PowerShell (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)\", supported: true, observation_only: true, fields: [\"resource_kind\",\"account_id\",\"environment_binding\",\"artifact_digest\",\"visibility_before\",\"visibility_after\"], operations: [\"create\",\"update\",\"write\",\"delete\",\"set_visibility\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"database.exec\", phase: \"pre_action\", via: \"PreToolUse Bash/exec_command/unified_exec/PowerShell (wrangler d1 execute and migrations apply, psql, sqlite3)\", supported: true, observation_only: true, fields: [\"provider\",\"verb\",\"predicate_class\",\"database_id\",\"migration_digest\"], operations: [\"read\",\"insert\",\"update\",\"delete\",\"delete_all\",\"create\",\"alter\",\"drop\",\"migrate\"] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"browser.action\", phase: \"pre_action\", via: \"(no browser hook)\", supported: false, unsupported_reason: \"no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"communication.send\", phase: \"pre_action\", via: \"(no communications adapter)\", supported: false, unsupported_reason: \"mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived\", fields: [], operations: [] },\n { adapter: \"codex\", host_variants: CODEX_HOSTS, action_type: \"visibility.change\", phase: \"pre_action\", via: \"(no visibility source)\", supported: false, unsupported_reason: \"no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"network.request\", phase: \"pre_action\", via: \"beforeShellExecution (curl, wget, Invoke-WebRequest, Invoke-RestMethod)\", supported: true, observation_only: true, fields: [\"scheme\",\"host\",\"port\",\"method\",\"net_operation\"], operations: [\"read\",\"write\",\"upload\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"cloudflare.resource\", phase: \"pre_action\", via: \"beforeShellExecution (wrangler deploy, pages deploy, d1 create/delete, r2 bucket and object commands)\", supported: true, observation_only: true, fields: [\"resource_kind\",\"account_id\",\"environment_binding\",\"artifact_digest\",\"visibility_before\",\"visibility_after\"], operations: [\"create\",\"update\",\"write\",\"delete\",\"set_visibility\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"database.exec\", phase: \"pre_action\", via: \"beforeShellExecution (wrangler d1 execute and migrations apply, psql, sqlite3)\", supported: true, observation_only: true, fields: [\"provider\",\"verb\",\"predicate_class\",\"database_id\",\"migration_digest\"], operations: [\"read\",\"insert\",\"update\",\"delete\",\"delete_all\",\"create\",\"alter\",\"drop\",\"migrate\"] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"browser.action\", phase: \"pre_action\", via: \"(no browser hook)\", supported: false, unsupported_reason: \"no approved browser or computer-use event is wired for this host: a browser tool reaches this adapter as a generic MCP tool call with no origin, verb or action class, so no browser operation is derived and none is claimed\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"communication.send\", phase: \"pre_action\", via: \"(no communications adapter)\", supported: false, unsupported_reason: \"mail and chat tools reach this adapter only as generic MCP tool calls; no provider adapter reads a destination domain or channel, or an attachment set, from the request, so no communication operation is derived\", fields: [], operations: [] },\n { adapter: \"cursor\", host_variants: [\"cursor\"], action_type: \"visibility.change\", phase: \"pre_action\", via: \"(no visibility source)\", supported: false, unsupported_reason: \"no host event or supported command reports a resource's visibility before and after; an R2 public-URL change is typed as cloudflare_resource set_visibility with the before state unknown\", fields: [], operations: [] },\n];\n\nexport const cellKey = (adapterVersion: string, host: HostVariant, actionType: string, phase: EventPhase): string =>\n `scopebond-hook@${adapterVersion}/${host}/${actionType}/${phase}`;\n\n/** The vectors that prove one cell: those tagged with its action type for its adapter. For\n * the after-action cell only the after-action vector counts. */\nexport function vectorsForCell(adapter: Adapter, actionType: string, phase: EventPhase): Vector[] {\n return VECTORS.filter((v) => v.agent === adapter && v.cell?.action_type === actionType\n && (phase === \"after_action\" ? v.cell.role === \"after_action\" : v.cell.role !== \"after_action\"));\n}\n\n/** Digest of a cell's vectors (id, payload and expectation). A proof recorded against one\n * digest says nothing about a changed set. */\nexport function vectorDigest(vectors: readonly Vector[]): string | null {\n if (vectors.length === 0) return null;\n const canonical = JSON.stringify([...vectors].sort((a, b) => a.id.localeCompare(b.id)).map((v) => [v.id, v.event ?? null, v.input, v.expect, v.catalog, v.unknown === true]));\n return `sha256:${createHash(\"sha256\").update(canonical).digest(\"hex\")}`;\n}\n\n/** The gaps the cell's vectors document, plus the always-true program-only limit. */\nfunction gapsFor(adapter: Adapter, actionType: string): string[] {\n const gaps = new Set<string>();\n for (const v of VECTORS) if (v.gap && v.agent === adapter && (actionType === \"shell.exec\" ? v.rule === \"R09\" || v.rule === \"R10\" || v.rule === \"R06\" : false)) gaps.add(v.gap);\n return [...gaps];\n}\n\nexport interface ManifestInput {\n adapterVersion: string;\n /** Which harnesses have the hook configured (any scope). */\n configured: Record<Adapter, boolean>;\n /** Recorded proofs by cell key. */\n proofs?: Record<string, ProofRecord | undefined>;\n now?: Date;\n /** Cell keys (any version) whose adapter no longer ships, for history. */\n retired?: string[];\n}\n\n/** Compute the state of one cell from what is configured and what has been proven. */\nexport function cellState(input: {\n supported: boolean; unsupportedReason?: string; configured: boolean; digest: string | null; adapterVersion: string;\n proof: ProofRecord | null | undefined; observationOnly: boolean; retired?: boolean;\n}): { state: CapabilityState; reason: string } {\n if (input.retired) return { state: \"retired\", reason: \"this adapter no longer ships; kept for history\" };\n if (!input.supported) return { state: \"unsupported\", reason: input.unsupportedReason ?? \"no hook for this action\" };\n if (!input.configured) return { state: \"inactive\", reason: \"the hook is not configured for this harness\" };\n if (input.digest === null) return { state: \"configured_unverified\", reason: \"configured; no test vectors exist for this cell, so it cannot be proven\" };\n const proof = input.proof;\n if (!proof) return { state: \"configured_unverified\", reason: \"configured; not yet proven (run `scopebond capabilities --prove`)\" };\n if (proof.adapter_version !== input.adapterVersion || proof.test_vector_digest !== input.digest) {\n return { state: \"configured_unverified\", reason: \"the recorded proof is for a different adapter version or vector set; run it again\" };\n }\n const denyOk = input.observationOnly ? proof.safe_deny === \"not_applicable\" : proof.safe_deny === true;\n if (!proof.safe_allow || !denyOk || !proof.signature || !proof.grouping || proof.typed_operation === false) {\n return { state: \"degraded\", reason: `the current proof failed: ${[!proof.safe_allow && \"safe allow\", !denyOk && \"safe deny\", !proof.signature && \"signature\", !proof.grouping && \"grouping\", proof.typed_operation === false && \"typed operation\"].filter(Boolean).join(\", \")}` };\n }\n if (proof.origin !== \"live_harness\") {\n return { state: \"configured_unverified\", reason: `${input.observationOnly ? \"observation-only fixture\" : \"local fixture\"} passed; a real ${\"host\"} run and Cloud acknowledgement are still outstanding` };\n }\n if (proof.cloud_ack !== \"acknowledged\") {\n return { state: \"configured_unverified\", reason: proof.cloud_ack === \"failed\" ? \"Cloud did not acknowledge the proof receipt\" : \"real-host proof passed; Cloud acknowledgement outstanding\" };\n }\n return { state: \"verified_reporting\", reason: input.observationOnly ? \"observation-only: a known successful after-action receipt was acknowledged\" : \"safe allow, safe deny, signature and Cloud acknowledgement all recorded\" };\n}\n\n/** The manifest for the installed hook. Pure: no filesystem, no clock beyond `now`. */\nexport function computeManifest(input: ManifestInput): Manifest {\n const cells: CapabilityCell[] = [];\n for (const spec of SPECS) {\n const vectors = spec.supported ? vectorsForCell(spec.adapter, spec.action_type, spec.phase) : [];\n const digest = vectorDigest(vectors);\n for (const host of spec.host_variants) {\n const key = cellKey(input.adapterVersion, host, spec.action_type, spec.phase);\n const proof = input.proofs?.[key] ?? null;\n const observationOnly = spec.observation_only === true;\n const { state, reason } = cellState({\n supported: spec.supported, unsupportedReason: spec.unsupported_reason, configured: input.configured[spec.adapter],\n digest, adapterVersion: input.adapterVersion, proof, observationOnly, retired: input.retired?.includes(key),\n });\n cells.push({\n key, connector: \"scopebond-hook\", adapter_version: input.adapterVersion, host_variant: host,\n action_type: spec.action_type, event_phase: spec.phase, state, reason,\n pre_action: spec.supported && spec.phase === \"pre_action\",\n after_action: spec.supported && spec.phase === \"after_action\",\n boundary: spec.supported && spec.phase === \"pre_action\" && !observationOnly ? \"harness_hook\" : \"none\",\n observation_only: observationOnly,\n emitted_required_fields: spec.fields, supported_operations: spec.operations,\n known_gaps: spec.supported ? gapsFor(spec.adapter, spec.action_type) : [],\n min_runtime: { node: \">=22.13\" },\n test_vector_digest: digest, last_proof: proof,\n });\n }\n }\n return { connector: \"scopebond-hook\", adapter_version: input.adapterVersion, generated_at: (input.now ?? new Date()).toISOString(), cells };\n}\n\n/** The spec for a cell key, for the proof runner. */\nexport function specForCell(cell: CapabilityCell): { adapter: Adapter; action_type: string; phase: EventPhase } | null {\n const spec = SPECS.find((s) => s.action_type === cell.action_type && s.phase === cell.event_phase && s.host_variants.includes(cell.host_variant));\n return spec ? { adapter: spec.adapter, action_type: spec.action_type, phase: spec.phase } : null;\n}\n\nconst VIA = new Map(SPECS.flatMap((s) => s.host_variants.map((h) => [`${h}/${s.action_type}/${s.phase}`, s.via] as const)));\n\n/** Plain-text rendering. Unsupported stays unsupported; nothing here upgrades a state. */\nexport function renderManifest(manifest: Manifest): string {\n const lines: string[] = [];\n lines.push(`Capability manifest — scopebond-hook ${manifest.adapter_version}`);\n lines.push(\"A state is only ever what a recorded proof supports. A local fixture never makes a cell verified.\");\n const hosts = [...new Set(manifest.cells.map((c) => c.host_variant))];\n for (const host of hosts) {\n lines.push(\"\");\n lines.push(host);\n for (const cell of manifest.cells.filter((c) => c.host_variant === host)) {\n const phase = cell.event_phase === \"after_action\" ? \"after action\" : \"before action\";\n const via = VIA.get(`${host}/${cell.action_type}/${cell.event_phase}`);\n lines.push(` ${cell.action_type.padEnd(21)} ${phase.padEnd(13)} ${cell.state.padEnd(21)}${cell.observation_only ? \" observation-only\" : \"\"}`);\n lines.push(` ${cell.reason}${via ? ` [${via}]` : \"\"}`);\n for (const gap of cell.known_gaps) lines.push(` limit: ${gap}`);\n }\n }\n const counts = new Map<string, number>();\n for (const cell of manifest.cells) counts.set(cell.state, (counts.get(cell.state) ?? 0) + 1);\n lines.push(\"\");\n lines.push(`Summary: ${[...counts].map(([state, n]) => `${n} ${state}`).join(\", \")}`);\n return lines.join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NormalizedIntent } from "./map.js";
|
|
2
|
+
import { type RuleSet } from "./rules.js";
|
|
3
|
+
export type CatalogId = "I03" | "I04" | "I05" | "H01" | "H02" | "H03" | "H04" | "H05" | "C01" | "C02";
|
|
4
|
+
export interface Classification {
|
|
5
|
+
ids: CatalogId[];
|
|
6
|
+
/** Why the intent could not be classified (an unresolved ref, program or path). */
|
|
7
|
+
unknown: string[];
|
|
8
|
+
/** Set for H04: the classification is from the program name only, not a typed target. */
|
|
9
|
+
coverage?: "program_only";
|
|
10
|
+
}
|
|
11
|
+
/** Ids whose match the default policy blocks. I-classes are inventory only. */
|
|
12
|
+
export declare const BLOCKING: readonly CatalogId[];
|
|
13
|
+
export declare function classifyIntent(intent: NormalizedIntent, rules: RuleSet): Classification;
|
|
14
|
+
/** Whether the compiled default policy denies an intent with this classification. Used
|
|
15
|
+
* by the parity test and the proof runner. */
|
|
16
|
+
export declare function classificationBlocks(c: Classification): boolean;
|
|
17
|
+
//# sourceMappingURL=classify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,EAA4D,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAEpG,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEtG,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,SAAS,EAAE,CAAC;IACjB,mFAAmF;IACnF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yFAAyF;IACzF,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAKD,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,SAAS,SAAS,EAAsD,CAAC;AAEhG,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,CAmCvF;AAED;+CAC+C;AAC/C,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE/D"}
|
package/dist/classify.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Catalog classification of one mapped intent, from the same typed data the compiled
|
|
2
|
+
// policy is built from (the rule set), so the two cannot drift.
|
|
3
|
+
//
|
|
4
|
+
// Detector ids follow the monitoring catalog: I03 ordinary read, I04 ordinary write,
|
|
5
|
+
// I05 shell inventory; H01 protected push, H02 credential read, H03 CI write,
|
|
6
|
+
// H04 destructive shell, H05 root-escape mutation; C01 protected history rewrite,
|
|
7
|
+
// C02 guardrail modification. `compile()` decides enforcement from the rule set;
|
|
8
|
+
// `classifyIntent()` names what an intent is. `test/parity.test.mjs` asserts that an
|
|
9
|
+
// intent is classified high/critical exactly when the compiled policy denies it.
|
|
10
|
+
//
|
|
11
|
+
// Unknown is not clean: an intent whose destination, program or path could not be
|
|
12
|
+
// resolved is returned in `unknown`, never as an ordinary I-class match.
|
|
13
|
+
import { UNKNOWN_REF } from "./shell.js";
|
|
14
|
+
import { isDestructiveProgram, isProtectedBranch, pathRuleMatches } from "./rules.js";
|
|
15
|
+
/** The CI locations: a write to one is H03; any other protected write is C02. */
|
|
16
|
+
const CI_LOCATION = /github\/(?:workflows|actions)|gitlab-ci|circleci|azure-pipelines|jenkinsfile|bitbucket-pipelines|travis|drone|cloudbuild|buildkite/i;
|
|
17
|
+
/** Ids whose match the default policy blocks. I-classes are inventory only. */
|
|
18
|
+
export const BLOCKING = ["H01", "H02", "H03", "H04", "H05", "C01", "C02"];
|
|
19
|
+
export function classifyIntent(intent, rules) {
|
|
20
|
+
const ids = [];
|
|
21
|
+
const unknown = [];
|
|
22
|
+
const params = intent.params;
|
|
23
|
+
let coverage;
|
|
24
|
+
const path = typeof params.path === "string" ? params.path : "";
|
|
25
|
+
if (intent.action_type === "git.push") {
|
|
26
|
+
const ref = typeof params.ref === "string" ? params.ref : undefined;
|
|
27
|
+
const rewrite = params.force === true || params.delete === true || params.all === true;
|
|
28
|
+
if (ref === undefined || ref === UNKNOWN_REF)
|
|
29
|
+
unknown.push("push destination not resolved");
|
|
30
|
+
else if (ref === "--all" || ref === "--mirror" || ref === "--branches")
|
|
31
|
+
ids.push("C01");
|
|
32
|
+
else if (isProtectedBranch(rules, ref))
|
|
33
|
+
ids.push(rewrite ? "C01" : "H01");
|
|
34
|
+
}
|
|
35
|
+
else if (intent.action_type === "file.read") {
|
|
36
|
+
if (path === "")
|
|
37
|
+
unknown.push("read path not resolved");
|
|
38
|
+
else
|
|
39
|
+
ids.push(rules.protected_read.some((r) => pathRuleMatches(r, path)) ? "H02" : "I03");
|
|
40
|
+
}
|
|
41
|
+
else if (intent.action_type === "file.write") {
|
|
42
|
+
if (path === "")
|
|
43
|
+
unknown.push("write target not resolved");
|
|
44
|
+
else {
|
|
45
|
+
const scope = params.root_scope;
|
|
46
|
+
if (scope === "outside")
|
|
47
|
+
ids.push("H05");
|
|
48
|
+
else if (scope === "unresolved") {
|
|
49
|
+
ids.push("H05");
|
|
50
|
+
unknown.push("write target could not be resolved");
|
|
51
|
+
}
|
|
52
|
+
const hit = rules.protected_write.find((r) => pathRuleMatches(r, path));
|
|
53
|
+
if (hit)
|
|
54
|
+
ids.push(CI_LOCATION.test(hit.kind === "raw" ? hit.pattern : hit.value) ? "H03" : "C02");
|
|
55
|
+
else if (ids.length === 0)
|
|
56
|
+
ids.push("I04");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (intent.action_type === "shell.exec") {
|
|
60
|
+
const program = typeof params.program === "string" ? params.program : "";
|
|
61
|
+
if (program === "")
|
|
62
|
+
unknown.push("program not resolved");
|
|
63
|
+
else {
|
|
64
|
+
ids.push("I05");
|
|
65
|
+
if (isDestructiveProgram(rules, program)) {
|
|
66
|
+
ids.push("H04");
|
|
67
|
+
coverage = "program_only";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { ids, unknown, ...(coverage ? { coverage } : {}) };
|
|
72
|
+
}
|
|
73
|
+
/** Whether the compiled default policy denies an intent with this classification. Used
|
|
74
|
+
* by the parity test and the proof runner. */
|
|
75
|
+
export function classificationBlocks(c) {
|
|
76
|
+
return c.unknown.length > 0 || c.ids.some((id) => BLOCKING.includes(id));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=classify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"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","sourcesContent":["// Catalog classification of one mapped intent, from the same typed data the compiled\n// policy is built from (the rule set), so the two cannot drift.\n//\n// Detector ids follow the monitoring catalog: I03 ordinary read, I04 ordinary write,\n// I05 shell inventory; H01 protected push, H02 credential read, H03 CI write,\n// H04 destructive shell, H05 root-escape mutation; C01 protected history rewrite,\n// C02 guardrail modification. `compile()` decides enforcement from the rule set;\n// `classifyIntent()` names what an intent is. `test/parity.test.mjs` asserts that an\n// intent is classified high/critical exactly when the compiled policy denies it.\n//\n// Unknown is not clean: an intent whose destination, program or path could not be\n// resolved is returned in `unknown`, never as an ordinary I-class match.\n\nimport type { NormalizedIntent } from \"./map.js\";\nimport { UNKNOWN_REF } from \"./shell.js\";\nimport { isDestructiveProgram, isProtectedBranch, pathRuleMatches, type RuleSet } from \"./rules.js\";\n\nexport type CatalogId = \"I03\" | \"I04\" | \"I05\" | \"H01\" | \"H02\" | \"H03\" | \"H04\" | \"H05\" | \"C01\" | \"C02\";\n\nexport interface Classification {\n ids: CatalogId[];\n /** Why the intent could not be classified (an unresolved ref, program or path). */\n unknown: string[];\n /** Set for H04: the classification is from the program name only, not a typed target. */\n coverage?: \"program_only\";\n}\n\n/** The CI locations: a write to one is H03; any other protected write is C02. */\nconst CI_LOCATION = /github\\/(?:workflows|actions)|gitlab-ci|circleci|azure-pipelines|jenkinsfile|bitbucket-pipelines|travis|drone|cloudbuild|buildkite/i;\n\n/** Ids whose match the default policy blocks. I-classes are inventory only. */\nexport const BLOCKING: readonly CatalogId[] = [\"H01\", \"H02\", \"H03\", \"H04\", \"H05\", \"C01\", \"C02\"];\n\nexport function classifyIntent(intent: NormalizedIntent, rules: RuleSet): Classification {\n const ids: CatalogId[] = [];\n const unknown: string[] = [];\n const params = intent.params;\n let coverage: Classification[\"coverage\"];\n const path = typeof params.path === \"string\" ? params.path : \"\";\n\n if (intent.action_type === \"git.push\") {\n const ref = typeof params.ref === \"string\" ? params.ref : undefined;\n const rewrite = params.force === true || params.delete === true || params.all === true;\n if (ref === undefined || ref === UNKNOWN_REF) unknown.push(\"push destination not resolved\");\n else if (ref === \"--all\" || ref === \"--mirror\" || ref === \"--branches\") ids.push(\"C01\");\n else if (isProtectedBranch(rules, ref)) ids.push(rewrite ? \"C01\" : \"H01\");\n } else if (intent.action_type === \"file.read\") {\n if (path === \"\") unknown.push(\"read path not resolved\");\n else ids.push(rules.protected_read.some((r) => pathRuleMatches(r, path)) ? \"H02\" : \"I03\");\n } else if (intent.action_type === \"file.write\") {\n if (path === \"\") unknown.push(\"write target not resolved\");\n else {\n const scope = params.root_scope;\n if (scope === \"outside\") ids.push(\"H05\");\n else if (scope === \"unresolved\") { ids.push(\"H05\"); unknown.push(\"write target could not be resolved\"); }\n const hit = rules.protected_write.find((r) => pathRuleMatches(r, path));\n if (hit) ids.push(CI_LOCATION.test(hit.kind === \"raw\" ? hit.pattern : hit.value) ? \"H03\" : \"C02\");\n else if (ids.length === 0) ids.push(\"I04\");\n }\n } else if (intent.action_type === \"shell.exec\") {\n const program = typeof params.program === \"string\" ? params.program : \"\";\n if (program === \"\") unknown.push(\"program not resolved\");\n else {\n ids.push(\"I05\");\n if (isDestructiveProgram(rules, program)) { ids.push(\"H04\"); coverage = \"program_only\"; }\n }\n }\n return { ids, unknown, ...(coverage ? { coverage } : {}) };\n}\n\n/** Whether the compiled default policy denies an intent with this classification. Used\n * by the parity test and the proof runner. */\nexport function classificationBlocks(c: Classification): boolean {\n return c.unknown.length > 0 || c.ids.some((id) => BLOCKING.includes(id));\n}\n"]}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAwpBA,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,IAAI,CAS7F"}
|