ai2rules-harness 0.8.0 → 0.8.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 +165 -71
- package/package.json +7 -8
package/README.md
CHANGED
|
@@ -1,116 +1,210 @@
|
|
|
1
1
|
# ai2rules-harness
|
|
2
2
|
|
|
3
|
-
**Govern a local coding agent in one command.**
|
|
3
|
+
**Govern a local coding agent in one command.** A deterministic kernel decides every
|
|
4
|
+
tool call Claude Code proposes, before it runs. No model takes part in the decision.
|
|
4
5
|
|
|
5
6
|
```bash
|
|
6
7
|
npm install -g ai2rules-harness
|
|
7
|
-
|
|
8
|
-
harness
|
|
8
|
+
cd your-project
|
|
9
|
+
harness init # govern this project
|
|
10
|
+
harness demo # watch the kernel decide: 5 cases, nothing executed
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
it runs eight cases through the real kernel (Read, Write, Shell, JIRA_CREATE_ISSUE,
|
|
15
|
-
scoped actions, path roots, poisoned knowledge, classification), records each verdict,
|
|
16
|
-
and replays them to prove deterministic decisions. Decision-only, no tool execution.
|
|
13
|
+
> **The package is `ai2rules-harness`; the command it installs is `harness`.**
|
|
14
|
+
> npm does not print the commands a package adds, so if you are wondering what
|
|
15
|
+
> you got: it is one command, `harness`. Run `harness --help` for the list.
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
> when the binary lives inside the project it would govern — a local
|
|
20
|
-
> `node_modules` install puts the kernel in the agent's own writable root, where
|
|
21
|
-
> replacing one file turns governance off silently. `npx ai2rules-harness init`
|
|
22
|
-
> is fine: its cache is outside your project.
|
|
17
|
+
## Install
|
|
23
18
|
|
|
24
|
-
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g ai2rules-harness
|
|
21
|
+
harness --version
|
|
22
|
+
```
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
- **No Rust, no build step.** npm installs a prebuilt binary for your platform:
|
|
25
|
+
Linux x64, macOS (Intel and Apple Silicon), Windows x64.
|
|
26
|
+
- **Install it globally, not into a project.** `harness init` refuses to run when
|
|
27
|
+
the binary lives inside the project it would govern: a local `node_modules`
|
|
28
|
+
install puts the kernel in the agent's own writable folder, where replacing one
|
|
29
|
+
file turns governance off silently. Not `npx ai2rules-harness init` either: the
|
|
30
|
+
hook would point into npx's cache, and when npm prunes it governance turns off
|
|
31
|
+
silently. `npx` is fine for commands that install nothing, such as
|
|
32
|
+
`demo --story law-firm`, `replay-transcripts` and `doctor`.
|
|
33
|
+
- **Windows:** run it from PowerShell or Git Bash. Claude Code runs the hook through
|
|
34
|
+
Git Bash, which Claude Code on Windows already needs.
|
|
35
|
+
- **Update:** `npm install -g ai2rules-harness@latest`.
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
binary in a `postinstall` and verified a checksum fetched from the same host — which
|
|
33
|
-
proves the file arrived intact, not that it is the right file. Now the binary is
|
|
34
|
-
covered by the integrity hash npm writes into *your* lockfile, and the tarballs
|
|
35
|
-
carry [npm provenance](https://docs.npmjs.com/generating-provenance-statements)
|
|
36
|
-
signed against the workflow and commit that built them.
|
|
37
|
+
If your platform has no prebuilt binary, the CLI tells you how to build one, or you
|
|
38
|
+
point the `AI2RULES_HARNESS` environment variable at an existing binary.
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
behind a proxy or a mirrored registry — none of which was true before.
|
|
40
|
+
## A five-minute tour
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
how to build one, or you point `AI2RULES_HARNESS` at an existing binary.
|
|
42
|
+
**1. Govern a project.** In the project's folder:
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
```bash
|
|
45
|
+
harness init
|
|
46
|
+
```
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
This writes into the project: a policy file (`.claude/cc-world.yaml`), a small hook
|
|
49
|
+
script (`.claude/hooks/world-gate.sh`), the hook entries in `.claude/settings.json`,
|
|
50
|
+
and a `.gitignore` line for the runtime state. From the next Claude Code session on,
|
|
51
|
+
every tool call goes through the kernel first, and each decision and how the call
|
|
52
|
+
ended go to a local log, `.claude/state/decisions.jsonl`. It is safe to run twice and never replaces a policy you
|
|
53
|
+
have edited. Add `--dry-run` to see the plan without writing anything.
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
takes part in the decision: a verdict is a pure function of the proposed call, the
|
|
53
|
-
session's context, and a compiled manifest.
|
|
55
|
+
**2. Watch it decide.**
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
```bash
|
|
58
|
+
harness demo
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Five cases through the real kernel and your project's policy: an in-project write
|
|
62
|
+
is allowed, an out-of-project write in the background is denied, tainted input
|
|
63
|
+
(text that came from outside, such as a web page) cannot reach the network, and a
|
|
64
|
+
destructive command needs your approval. Every verdict is written to a log and
|
|
65
|
+
replayed to show the decisions are reproducible. Nothing is executed and no
|
|
66
|
+
credentials are needed.
|
|
56
67
|
|
|
57
|
-
|
|
68
|
+
No project at hand? `harness demo --story law-firm` tells a story over its own
|
|
69
|
+
built-in policy, no `init` needed: an AI legal assistant reads a poisoned client
|
|
70
|
+
email. Add `--html story.html` for a page you can step through in a browser.
|
|
71
|
+
|
|
72
|
+
**3. Check the installation.**
|
|
58
73
|
|
|
59
74
|
```bash
|
|
60
|
-
harness
|
|
75
|
+
harness doctor
|
|
61
76
|
```
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
Reports whether the binary, the hook and the policy are in place and what the
|
|
79
|
+
policy covers.
|
|
80
|
+
|
|
81
|
+
**4. See what it would have done to your past sessions.**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
harness replay-transcripts
|
|
85
|
+
```
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
Replays the tool calls from your earlier Claude Code sessions
|
|
88
|
+
(`~/.claude/projects`) through the kernel and reports how often it would have
|
|
89
|
+
allowed, asked or denied, and why. Nothing is executed and nothing leaves the
|
|
90
|
+
machine. It works without `init`, so it is a good first look before you govern
|
|
91
|
+
anything.
|
|
71
92
|
|
|
72
|
-
|
|
93
|
+
**5. Change the policy with switches.**
|
|
73
94
|
|
|
74
95
|
```bash
|
|
75
|
-
|
|
76
|
-
| CLAUDE_PROJECT_DIR=$PWD bash .claude/hooks/world-gate.sh
|
|
96
|
+
harness console
|
|
77
97
|
```
|
|
78
98
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
99
|
+
Serves a local page (127.0.0.1 only) and prints its address, `http://127.0.0.1:8790/`
|
|
100
|
+
by default; open it in a browser. The page has profiles and Allow / Ask / Off
|
|
101
|
+
switches for groups of actions. The switches rewrite the project's policy file, and
|
|
102
|
+
a running Claude Code session follows Allow and Ask on its very next tool call. The
|
|
103
|
+
page also shows the live feed of decisions.
|
|
104
|
+
|
|
105
|
+
**Off** removes actions from the policy (ABSENT, below). The hook `harness init`
|
|
106
|
+
writes leaves such calls to Claude Code's own permissions, so Off blocks them only
|
|
107
|
+
when the hook runs with `--enforce-absent`; the page warns when it does not.
|
|
108
|
+
|
|
109
|
+
## Commands
|
|
110
|
+
|
|
111
|
+
**Everyday**
|
|
112
|
+
|
|
113
|
+
| Command | What it does |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `harness init` | Govern the project in this folder. `--dry-run` shows the plan; `--grant` makes the policy the allowlist (see Modes) |
|
|
116
|
+
| `harness init --user` | Govern every Claude Code session your account opens, in any folder. `--remove` undoes it |
|
|
117
|
+
| `harness init --managed` | Govern every session on the machine, for every account, through Claude Code's managed settings. Needs an admin shell |
|
|
118
|
+
| `harness demo` | The first proof: 5 decisions over this project's policy, replayed |
|
|
119
|
+
| `harness demo --story law-firm` | A story for a non-technical audience, with its own policy; `--html <file>` for a browser page |
|
|
120
|
+
| `harness doctor` | Check the installation and coverage in this project; `--json` for a machine-readable report |
|
|
121
|
+
| `harness replay-transcripts` | Replay past Claude Code sessions through the kernel and report what it would have decided |
|
|
122
|
+
| `harness console` | Local page to switch groups of actions between Allow, Ask and Off |
|
|
123
|
+
| `harness serve` | Local browser editor for policy files, backed by the real compiler and kernel |
|
|
124
|
+
|
|
125
|
+
**Integration** (what hooks, gateways and scripts call; you rarely type these)
|
|
126
|
+
|
|
127
|
+
| Command | What it does |
|
|
128
|
+
|---|---|
|
|
129
|
+
| `harness cc-hook` | The Claude Code hook. `init` wires it up for you. `--log <file>` keeps a decision log |
|
|
130
|
+
| `harness agy-hook` | The same hook for the Antigravity CLI (`agy`) |
|
|
131
|
+
| `harness gate` | Decide one proposed tool call: JSON request on stdin, verdict on stdout |
|
|
132
|
+
| `harness project` | Filter a host's offered tool list through the policy: tools the policy does not know are hidden |
|
|
133
|
+
| `harness mcp-gateway` | Put the kernel in front of a real MCP server: hide tools the policy does not declare, forward only allowed calls |
|
|
134
|
+
| `harness mcp-author` | Browser page to pick, rename and limit an MCP server's tools into a scoped surface |
|
|
135
|
+
| `harness approvals` | Review and answer approvals recorded by `mcp-gateway --approvals` |
|
|
136
|
+
| `harness export-otlp` | Convert a decision log to OpenTelemetry traces (OTLP/JSON) for a collector |
|
|
137
|
+
| `harness mock-jira` | A self-contained mock JIRA MCP server, the demo upstream for `mcp-gateway` |
|
|
138
|
+
|
|
139
|
+
`harness <command> --help` shows every option.
|
|
140
|
+
|
|
141
|
+
## Verdicts
|
|
142
|
+
|
|
143
|
+
Every call gets one of five answers:
|
|
144
|
+
|
|
145
|
+
| Verdict | Meaning |
|
|
146
|
+
|---|---|
|
|
147
|
+
| **ALLOW** | Permitted. The host goes ahead (or asks as it normally would, in the default mode) |
|
|
148
|
+
| **ASK** | A person must approve it first |
|
|
149
|
+
| **DENY** | Refused, with the rule and the reason |
|
|
150
|
+
| **ABSENT** | The policy does not declare this action. An MCP gateway hides such tools from the agent; the Claude Code hook leaves the call to Claude Code unless you pass `--enforce-absent` |
|
|
151
|
+
| **REPLAN** | Over a budget the policy sets, such as `max_commands_per_task`: the agent should take a smaller step. It is not a refusal. The Claude Code and Antigravity hooks have no way to say "smaller step", so they leave the call to the host, as with ALLOW |
|
|
152
|
+
|
|
153
|
+
The verdict is a pure function of the proposed call, what the session has already
|
|
154
|
+
read, and the compiled policy. The same inputs always give the same answer, which is
|
|
155
|
+
why a decision log can be replayed.
|
|
83
156
|
|
|
84
157
|
## Modes
|
|
85
158
|
|
|
86
159
|
| Command | Behaviour |
|
|
87
160
|
|---|---|
|
|
88
|
-
| `harness init` | **Additive.** Adds deny
|
|
89
|
-
| `harness init --grant` | **Replace.** The
|
|
90
|
-
| `harness init --dry-run` | Print the plan, write nothing. |
|
|
161
|
+
| `harness init` | **Additive.** Adds deny and ask on top of Claude Code's own permissions. Cannot lock you out. |
|
|
162
|
+
| `harness init --grant` | **Replace.** The policy becomes the allowlist and grants directly, so Claude Code stops asking for what it allows. |
|
|
91
163
|
|
|
92
164
|
## Turning it off
|
|
93
165
|
|
|
94
166
|
Effective on the very next tool call, no restart:
|
|
95
167
|
|
|
96
168
|
```bash
|
|
97
|
-
touch ~/.claude/ai2rules/off/<your-project> # this project
|
|
98
|
-
touch ~/.claude/gate-off
|
|
169
|
+
mkdir -p ~/.claude/ai2rules/off && touch ~/.claude/ai2rules/off/<your-project> # this project
|
|
170
|
+
touch ~/.claude/gate-off # every project
|
|
99
171
|
```
|
|
100
172
|
|
|
101
|
-
`harness init` prints the exact
|
|
102
|
-
|
|
103
|
-
|
|
173
|
+
`harness init` prints the exact command for this project, path quoted. In
|
|
174
|
+
PowerShell, create the same file with `New-Item -ItemType File -Force '<path>'`.
|
|
175
|
+
Both switches live **outside** the governed project on purpose: a switch inside it
|
|
176
|
+
is one the agent could flip itself. Delete the file to turn governance back on.
|
|
177
|
+
|
|
178
|
+
To remove it from a project for good, delete the hook entries that call
|
|
179
|
+
`world-gate.sh` from `.claude/settings.json`.
|
|
180
|
+
|
|
181
|
+
## How it installs, and why there is no install script
|
|
182
|
+
|
|
183
|
+
The binary arrives as a **platform package** (`ai2rules-harness-linux-x64` and the
|
|
184
|
+
others), listed in `optionalDependencies`. npm picks exactly one by operating system
|
|
185
|
+
and CPU and skips the rest.
|
|
186
|
+
|
|
187
|
+
So the package runs **no install script**: nothing of ours executes at install time,
|
|
188
|
+
downloads anything beyond what npm itself fetches from the registry, runs a shell or
|
|
189
|
+
changes file permissions. The binary is covered by the integrity hash npm writes into
|
|
190
|
+
your lockfile. Installs are reproducible, work offline from a cache, and work behind
|
|
191
|
+
a proxy or a mirrored registry.
|
|
192
|
+
|
|
193
|
+
Releases are published from CI with npm trusted publishing, not from a developer's
|
|
194
|
+
machine. Versions 0.2.0 to 0.7.0, built while the repository was public, also carry
|
|
195
|
+
[npm provenance](https://docs.npmjs.com/generating-provenance-statements), a
|
|
196
|
+
signature tying them to the workflow and commit that built them. npm does not
|
|
197
|
+
generate provenance for packages published from a private repository, so 0.8.0
|
|
198
|
+
and later do not have it.
|
|
104
199
|
|
|
105
200
|
## Honest boundaries
|
|
106
201
|
|
|
107
202
|
- **Governed is not sandboxed.** This decides what an agent may *do*; it does not
|
|
108
|
-
contain where it runs. Both matter and they are different properties.
|
|
109
|
-
- **Depth
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
MIT OR Apache-2.0 · [source](https://github.com/ai2rules/kernel)
|
|
203
|
+
contain where it runs. Both matter, and they are different properties.
|
|
204
|
+
- **Depth depends on the host.** Deep on hosts that offer a hook before each tool
|
|
205
|
+
call (Claude Code, Antigravity); at the MCP server boundary only on hosts that do
|
|
206
|
+
not.
|
|
207
|
+
- **Read the policy you install.** `.claude/cc-world.yaml` is a starter, not a
|
|
208
|
+
finished judgement about your project.
|
|
209
|
+
|
|
210
|
+
MIT OR Apache-2.0 · [ai2rules.dev](https://ai2rules.dev)
|
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai2rules-harness",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Deterministic governance for local CLI coding agents. `
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "Deterministic governance for local CLI coding agents. Install globally, then `harness init` governs a project in one command.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/ai2rules/kernel.git",
|
|
9
9
|
"directory": "npm"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://
|
|
12
|
-
"bugs": "https://github.com/ai2rules/kernel/issues",
|
|
11
|
+
"homepage": "https://ai2rules.dev",
|
|
13
12
|
"keywords": [
|
|
14
13
|
"ai",
|
|
15
14
|
"agent",
|
|
@@ -32,9 +31,9 @@
|
|
|
32
31
|
"node": ">=18"
|
|
33
32
|
},
|
|
34
33
|
"optionalDependencies": {
|
|
35
|
-
"ai2rules-harness-darwin-arm64": "0.8.
|
|
36
|
-
"ai2rules-harness-darwin-x64": "0.8.
|
|
37
|
-
"ai2rules-harness-linux-x64": "0.8.
|
|
38
|
-
"ai2rules-harness-windows-x64": "0.8.
|
|
34
|
+
"ai2rules-harness-darwin-arm64": "0.8.1",
|
|
35
|
+
"ai2rules-harness-darwin-x64": "0.8.1",
|
|
36
|
+
"ai2rules-harness-linux-x64": "0.8.1",
|
|
37
|
+
"ai2rules-harness-windows-x64": "0.8.1"
|
|
39
38
|
}
|
|
40
39
|
}
|