@getmarrow/install 0.1.67 → 0.1.68
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 +174 -290
- package/package.json +1 -1
- package/src/controller-manager.js +3 -1
- package/src/first-hour.js +1 -1
- package/src/governed-runner.js +1978 -114
- package/src/installer.js +821 -72
- package/src/mcp-runtime.js +447 -0
- package/src/pins.js +19 -0
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ Never install, create an account, or submit data without operator approval.
|
|
|
50
50
|
|
|
51
51
|
Verify current claims through the [public evidence manifest](https://getmarrow.ai/.well-known/marrow-evidence.json), [reference graph](https://getmarrow.ai/.well-known/marrow-reference-graph.json), and [integration cards](https://getmarrow.ai/.well-known/marrow-integrations/index.json).
|
|
52
52
|
|
|
53
|
+
|
|
53
54
|
## Install
|
|
54
55
|
|
|
55
56
|
```bash
|
|
@@ -62,17 +63,29 @@ Required secret:
|
|
|
62
63
|
export MARROW_API_KEY=mrw_live_...
|
|
63
64
|
```
|
|
64
65
|
|
|
65
|
-
The bare command is the default-on path
|
|
66
|
+
The bare command is the default-on path. It detects supported surfaces, writes managed configuration byte-idempotently, runs the authenticated activation self-test, and starts the supported persistent controller. It prints a short summary that ends with the restart to do, naming the host (for example "Restart Claude Code"). The full report goes to `~/.marrow/logs/` (directory mode 700, files mode 600); `--verbose` prints it instead. The explicit `activate` command is equivalent.
|
|
67
|
+
|
|
68
|
+
Hooks start a verified local copy of the pinned MCP from `~/.marrow/runtime/mcp/<version>/` instead of through `npx`, so a gated tool call does not wait 0.6 to 1.3 seconds for `npx` first (see [Local MCP runtime](#local-mcp-runtime)).
|
|
69
|
+
|
|
70
|
+
Where the key comes from:
|
|
71
|
+
|
|
72
|
+
- The installer reads `MARROW_API_KEY`. When that is unset it reads the owner-only `~/.marrow/env.local`, then `~/.marrow/env`, and names the file it used. It warns when those two files hold different keys.
|
|
73
|
+
- With no key, the command prints the exact command to run and stops before writing anything.
|
|
74
|
+
- On a first install whose key came from `MARROW_API_KEY`, once the self-test passes, the installer stores it in the owner-only `~/.marrow/env` (mode 600) when no key is stored there yet, and says so in one line, so Claude Code opened from the desktop app, an IDE or a new terminal finds it. This holds with `--json` and `--verbose` too. A key passed with `--key` is not stored, and a different stored key is left unchanged and named.
|
|
75
|
+
- The governed runner and `controller` commands read the key from `MARROW_API_KEY` or `MARROW_KEY`, else from the same owner-only files (the runner also accepts `--key`, which is visible in process listings; prefer the variable). With no key the runner stops with: "Marrow can't find your key: run `npx @getmarrow/install` once in this machine's terminal."
|
|
76
|
+
- The key is never written to generated configuration, controller state or logs. It is written only to the owner-only `~/.marrow/env`: on a first install as above, and for Hermes wiring, described under Trust and Data Boundaries.
|
|
77
|
+
|
|
78
|
+
Flags: `--dry-run` previews without writing, `doctor` is a read-only health check (it prints to the terminal and writes no log), `--no-controller` installs and self-tests without starting the controller, `--no-self-test` skips the API self-test, `--mode auto|mcp|sdk|both|md` limits what is written, `--no-local-runtime` (or `MARROW_LOCAL_RUNTIME=0`) keeps hooks on `npx`, and `--yes` writes detected configuration. Run `npx @getmarrow/install --help` for the installer options and `npx @getmarrow/install run --help` for the runner.
|
|
66
79
|
|
|
67
80
|
### MCP tool profiles
|
|
68
81
|
|
|
69
82
|
Ordinary setup leaves `MARROW_TOOL_PROFILE` unset, which selects the documented 17-tool `primary` surface. Set `MARROW_TOOL_PROFILE=core` only for the legacy seven-tool minimal surface, or `MARROW_TOOL_PROFILE=full` for the complete advanced/legacy catalog. Explicit `primary`, `core`, and `full` values are accepted; any other value fails with an exact bounded repair and never falls back to a broader profile.
|
|
70
83
|
|
|
71
|
-
Tool visibility is not authorization. Every visible call still reaches Marrow's backend authentication, tenant, key-permission, plan, proof, and policy enforcement. `doctor --self-test` reports the configured and effective profile, the expected visible count, reloaded MCP visible names/count, and non-authorizing backend entitlement/upgrade projection. Until the owning harness restarts and matching MCP status is observed, actual visibility stays unavailable and the profile remains not-live. The self-test reads backend availability status; it does not invoke paid write tools to discover access.
|
|
84
|
+
Tool visibility is not authorization. Every visible call still reaches Marrow's backend authentication, tenant, key-permission, plan, proof, and policy enforcement. `doctor --self-test` reports the configured and effective profile, the expected visible count, reloaded MCP visible names/count, and non-authorizing backend entitlement/upgrade projection (`authorizes_calls: false`). Until the owning harness restarts and matching MCP status is observed, actual visibility stays unavailable and the profile remains not-live. The self-test reads backend availability status; it does not invoke paid write tools to discover access.
|
|
72
85
|
|
|
73
86
|
## Keeping Marrow Current
|
|
74
87
|
|
|
75
|
-
Marrow's hosted API, website, and dashboard update automatically
|
|
88
|
+
Marrow's hosted API, website, and dashboard update automatically. Local SDK dependencies, generated runtime files, MCP hooks/configuration, and pinned package versions do not silently rewrite themselves. Supported clients report their package version during authenticated status and runtime activity, and Marrow returns a `client_update` notice with the exact action when the version is behind or unknown. Notices distinguish recommended, unrecognized and security-required updates.
|
|
76
89
|
|
|
77
90
|
```bash
|
|
78
91
|
# One command: refreshes managed configuration, restarts an outdated controller,
|
|
@@ -86,15 +99,26 @@ npx -y @getmarrow/install@latest doctor --self-test
|
|
|
86
99
|
npx -y --package=@getmarrow/mcp@latest marrow-mcp ping
|
|
87
100
|
```
|
|
88
101
|
|
|
89
|
-
`update` resolves official npm metadata once, selects one exact verified MCP target, and synchronizes every Marrow-managed surface in the detected owning workspace while retaining unrelated user hooks and configuration. It also restarts a controller that a different installer version started, and runs the self-test with a one-line summary. Restart the detected owning harnesses once after it completes; running processes do not change before that restart. Run the doctor verification once after restart. Do not run separate `marrow-mcp setup` and restart cycles for the same detected workspace.
|
|
102
|
+
`update` resolves official npm metadata once, selects one exact verified MCP target, and synchronizes every Marrow-managed surface in the detected owning workspace while retaining unrelated user hooks and configuration. A newer local version is never propagated unless official registry metadata verifies it; offline, unverified-ahead surfaces are preserved. It also restarts a controller that a different installer version started, and runs the self-test with a one-line summary. Restart the detected owning harnesses once after it completes; running processes do not change before that restart. Run the doctor verification once after restart. Do not run separate `marrow-mcp setup` and restart cycles for the same detected workspace.
|
|
90
103
|
|
|
91
104
|
`update` and `--repair` only refresh an existing install. Run from a directory with no Marrow-managed files while your home directory is managed, they stop without writing and print the exact `update --cwd <home>` command; to add Marrow to that project, run the install command there instead. Managed JSON that differs only in key order or formatting, for example after a harness re-saves its settings, counts as present and is not rewritten.
|
|
92
105
|
|
|
93
|
-
`
|
|
106
|
+
`doctor` detects active and configured stale, mixed, or version-unknown Marrow MCP clients without exposing command lines, file paths, configuration contents, or credentials. When repair is needed it prints the pinned setup command, the separate owning-harness restart requirement, and a self-test command; it does not terminate harness processes. Generated MCP launches use the package-explicit `npx --package ... marrow-mcp` form; hooks start the verified local copy of that package and fall back to that form (see [Local MCP runtime](#local-mcp-runtime)).
|
|
107
|
+
|
|
108
|
+
After explicit activation, the local controller can restore drifted Marrow-managed hooks and configuration. Package upgrades, owner policy, credentials, explicitly disabled hooks, and unrelated local files remain explicit and subject to the operator's normal change policy.
|
|
109
|
+
|
|
110
|
+
### Hermes
|
|
111
|
+
|
|
112
|
+
Hermes is detected from `~/.hermes/config.yaml` (or `$HERMES_HOME`) or `hermes` on `PATH`. Install and update add or refresh `mcp_servers.marrow` with the pinned MCP server and `MARROW_CLIENT: hermes`:
|
|
113
|
+
|
|
114
|
+
- The rest of the file, comments included, is kept. The edit is verified before it is written.
|
|
115
|
+
- No copy of the file is made, because it holds other servers' credentials. The private log lists only the `mcp_servers.marrow` lines added or replaced, with values redacted, as undo steps.
|
|
116
|
+
- If the file cannot be edited safely, or the existing `marrow` entry has a custom command or custom arguments, it is left untouched and the exact block to add is printed.
|
|
117
|
+
- Restart Hermes if its config changed.
|
|
94
118
|
|
|
95
119
|
## Automatic Controller
|
|
96
120
|
|
|
97
|
-
On Linux, successful install, repair, and activation starts a loopback-only controller that survives individual agent sessions. It keeps the signed action-permit broker available, checks installer-managed hooks every five minutes, safely restores missing managed entries, and reports an exact fix when repair is not safe. The API key remains process-only; private controller state is owner-only and contains no Marrow credential.
|
|
121
|
+
On Linux, successful install, repair, and activation starts a loopback-only controller that survives individual agent sessions. It keeps the signed action-permit broker available, checks installer-managed hooks every five minutes, safely restores missing managed entries, and reports an exact fix when repair is not safe. It keeps each project's hooks in the form its install chose: on the verified local MCP runtime, or on `npx`. The API key remains process-only; private controller state is owner-only and contains no Marrow credential.
|
|
98
122
|
|
|
99
123
|
```bash
|
|
100
124
|
npx @getmarrow/install controller status
|
|
@@ -102,284 +126,36 @@ npx @getmarrow/install controller ensure
|
|
|
102
126
|
npx @getmarrow/install controller stop
|
|
103
127
|
```
|
|
104
128
|
|
|
105
|
-
Install and update restart a controller that a different installer version started, including one left under an earlier identity directory for the same project, and report the restart in one line. The replaced controller is identified by its private state and authenticated endpoint before it is stopped. Controllers for other projects are not touched, and the owner's local control setting is not changed. `controller stop` stops every Marrow controller for the current project.
|
|
129
|
+
`controller start` is also accepted. Install and update restart a controller that a different installer version started, including one left under an earlier identity directory for the same project, and report the restart in one line. The replaced controller is identified by its private state and authenticated endpoint before it is stopped. Controllers for other projects are not touched, and the owner's local control setting is not changed. `controller stop` stops every Marrow controller for the current project. The five-minute pass re-applies the controller's own agent id and base URL; a different value found in managed MCP configuration is reset and reported as needing attention, unless the owner allowlisted it.
|
|
106
130
|
|
|
107
131
|
Persistent controller lifecycle is currently Linux-only. On macOS or Windows, activation still writes supported configuration and verifies one server-side install self-test without certifying that hooks continuously ran; run `npx @getmarrow/install sidecar` under an owner-managed service and pass `--no-controller`. The controller does not silently upgrade packages, change governance policy, rotate credentials, or modify unrelated project configuration.
|
|
108
132
|
|
|
109
|
-
The controller is not a boot service. After a host restart, or any exit that skips its shutdown handler, doctor reports it as `stale` until the next install, update, or `controller ensure`. While local control is disabled, the controller is not started, and doctor reports a stopped or stale controller as not required instead of recommending `controller ensure`;
|
|
110
|
-
|
|
111
|
-
## What's New in v0.1.67
|
|
112
|
-
|
|
113
|
-
v0.1.67 installs MCP `3.9.98` (source `e40d3cb40479456fd937bce0b9488eb0c3f10863`, packed integrity `sha512-AmDT3afwdm7+Dc555zDs+yGIG4RyC/YbaQm+9O1mThlC6g/9EujTr7y7UvRMEtYDvVWAAaG6CFM7/u/ytjKhwQ==`), which makes `npx @getmarrow/mcp ...` commands work again. SDK `3.7.64` and everything else are unchanged.
|
|
114
|
-
|
|
115
|
-
### Previous release: v0.1.66
|
|
116
|
-
|
|
117
|
-
v0.1.66 keeps MCP `3.9.97` (source `be607e1dffd4d9e6a3c40f01151e509c115fba3f`, packed integrity `sha512-wab1kvgec8WhDDrpkajauLu2QdADXudIxkic0BAgzV96FZVHY0ME45hrOyQmqfkI+OtKriYdgIFp90peWGh2mA==`) and SDK `3.7.64` unchanged. It fixes the governed runner's gate and permit path, makes updating one command, and removes internal publishing tooling from the public package.
|
|
118
|
-
|
|
119
|
-
#### Update: one command
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
MARROW_API_KEY=mrw_live_... npx -y @getmarrow/install@latest update
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
First install is the same command without `update`. On its own, the command now:
|
|
126
|
-
|
|
127
|
-
- restarts a running controller that a different installer version started, so `controller stop` and `controller ensure` are no longer separate steps. Local control stays enabled or disabled as the owner left it;
|
|
128
|
-
- detects Hermes from `~/.hermes/config.yaml` (or `$HERMES_HOME`) or `hermes` on `PATH`, and adds or refreshes `mcp_servers.marrow` with the pinned MCP server and `MARROW_CLIENT: hermes`. The rest of the file, comments included, is kept. No copy of the file is made, because it holds other servers' credentials; the private log lists only the `mcp_servers.marrow` lines added or replaced, with values redacted, as undo steps. The edit is verified before it is written. If the file cannot be edited safely, or the existing `marrow` entry has a custom command or custom arguments, it is left untouched and the exact block to add is printed;
|
|
129
|
-
- needs no `MARROW_AGENT_ID`: Marrow uses the API key's bound agent or the plan's agent seat. `MARROW_AGENT_ID` still overrides;
|
|
130
|
-
- runs the self-test and prints a short summary: healthy with the committed decision id, or the failure (including a decision recorded without trusted closure) and one fix command, with a non-zero exit. The full report goes to `~/.marrow/logs/` (mode 600); `--verbose` prints it instead;
|
|
131
|
-
- reads the key from `MARROW_API_KEY`, or from the owner-only `~/.marrow/env.local` or `~/.marrow/env`, and names the file it used. It warns when those two files hold different keys. With no key it prints the command to run and stops before writing anything.
|
|
132
|
-
|
|
133
|
-
Restart the owning harness afterwards so new hooks and MCP configuration load; restart Hermes if its config changed.
|
|
134
|
-
|
|
135
|
-
#### Fixes
|
|
136
|
-
|
|
137
|
-
- **Governed runner gate and permits.** `gate`, `run` and `permit` read Marrow's real gate decision. Previously the runtime's default package response lacked the fields the runner read, so `gate` printed `unknown`, and every protected `run` sent an empty gate receipt, got HTTP 400 and exited 13.
|
|
138
|
-
- `gate` now prints the decision with its mode (enforced or advisory), and exits 12 when an enforced gate blocks or needs owner approval. It used to exit 0.
|
|
139
|
-
- A protected `run` passes the gate receipt to permit issue and closes the runtime's own decision instead of opening a second one.
|
|
140
|
-
- **Advisory plans.** Where the plan's gate is advisory (`enforced: false`), a protected `run` shows the warning, runs the command and records the outcome; it no longer asks for a permit the plan cannot issue. Enforced plans keep the permit requirement.
|
|
141
|
-
- **Retries and time limits.** The runner's runtime, think and commit calls, and the self-test's runtime and first-value calls, retry HTTP 429/502/503/504, timed-out attempts and pending answers up to three times with the same `Idempotency-Key`. Each attempt has a 10-second limit, and all attempts share a 25-second deadline. Every `run`, `gate` and `permit` uses fresh keys, so a later command in the same session is never answered with an earlier command's stored result. Client errors are not retried.
|
|
142
|
-
- **Self-test cleanup.** The self-test closes the decision its runtime check creates, instead of leaving it open.
|
|
143
|
-
- **Claude Code hook identity.** Claude Code hooks use the Claude-specific entrypoints (`claude-pre-action-hook`, `claude-hook`, `claude-context-hook`, `claude-session-hook`), the same spelling `marrow-mcp setup` writes. Hook activity is labelled `claude-code` instead of the generic `mcp-client`, and the installer and MCP setup no longer rewrite each other's entries. Existing entries are migrated in place without duplicates.
|
|
144
|
-
- **Agent identity.** No generated `<client>-<hash>` agent id is sent or written to MCP configuration or the SDK preload; one written by an earlier version is removed from `.mcp.json`. With an unbound key, activation reports that no single agent can be confirmed and how to bind one, instead of failing the install.
|
|
145
|
-
- **`run -- -- <command>`.** The documented form now runs the command; one `--` is enough.
|
|
146
|
-
- **Codex detection.** An `AGENTS.md` that holds only the Marrow block no longer marks a project as Codex.
|
|
147
|
-
- **Controller maintenance.** The five-minute maintenance pass re-applies the controller's own agent id and base URL instead of the generated id and default URL. A different value found in managed MCP configuration is reset and reported as needing attention, unless the owner allowlisted it.
|
|
148
|
-
- **`proof`.** `proof --decision-id` works again: the shared option parser had rejected it. It exits non-zero unless Marrow returns `committed: true`, and accepts `--gate-receipt` and `--session` for decisions created by `gate`.
|
|
149
|
-
- **Controller commands.** `controller ensure|stop|status` act on the controller that install and update started.
|
|
150
|
-
- **Removed.** `--repair` and `update` no longer read an npm token from `~/.openclaw` or write `~/.npmrc`; that was internal publishing tooling. Two internal credential-file hints were removed with it. Installer output no longer suggests invented agent ids such as `--agent hermes-prod`.
|
|
151
|
-
|
|
152
|
-
Plan semantics are unchanged: where a plan's gate is advisory, it stays advisory.
|
|
153
|
-
|
|
154
|
-
### Previous release: v0.1.65
|
|
155
|
-
|
|
156
|
-
v0.1.65 pins MCP `3.9.97` (source `be607e1dffd4d9e6a3c40f01151e509c115fba3f`, packed integrity `sha512-wab1kvgec8WhDDrpkajauLu2QdADXudIxkic0BAgzV96FZVHY0ME45hrOyQmqfkI+OtKriYdgIFp90peWGh2mA==`) while keeping SDK `3.7.64` unchanged. Changes:
|
|
157
|
-
|
|
158
|
-
- `doctor` no longer reports hooks as missing after a harness re-saves its settings file.
|
|
159
|
-
- `update` refuses to write into an unrelated folder and only touches Marrow-managed roots.
|
|
160
|
-
- The install self-test handles pending decisions and never commits one as a success.
|
|
161
|
-
- Controller reporting is clearer; a disabled controller stays quiet while exact fixes for non-benign states are still shown.
|
|
162
|
-
- Enforcement heartbeats back off after repeated failures and retry once an hour.
|
|
163
|
-
- The agent id is never derived from the OS username.
|
|
164
|
-
- Permit verification sends `protocol_version`.
|
|
165
|
-
- The test suite is isolated from the real HOME and Marrow credentials.
|
|
166
|
-
|
|
167
|
-
Restart the owning harness, review hook trust and run `doctor --self-test` after updating.
|
|
168
|
-
|
|
169
|
-
### Previous release: v0.1.64
|
|
170
|
-
|
|
171
|
-
v0.1.64 pins MCP `3.9.96` (source `031c944936271fd6e8768ad2619ee0430b68e2c7`, packed integrity `sha512-kuBpuWaWAvusS+FbXXFw1fOEGja4T8ahj/vkmXTd/CWjz0t6teT6g9c1HfJhAK6KLzesZtcvUdZLn6pBErKP9Q==`) while keeping SDK `3.7.64` unchanged. The embedded MCP pin requires this installer patch to deliver the native pre-action hook permit fix: protected actions are no longer denied after an allowing runtime gate, and unprotected actions stop at the gate without creating a decision or permit. Policy decisions, proof requirements and fail-closed behavior are unchanged. `activate` and `doctor --self-test` now resend the identical self-test decision and commit with a stable `Idempotency-Key` after a transient 429/502/503/504 or a durable pending acknowledgement (at most three attempts, about one second apart), instead of failing with "self-test did not return decision_id"; client errors still fail immediately, and a final failure names the last state. Restart the owning harness, review hook trust and run `doctor --self-test` after updating.
|
|
172
|
-
|
|
173
|
-
### Previous release: v0.1.63
|
|
174
|
-
|
|
175
|
-
v0.1.63 pins MCP `3.9.95` (source `967b17735b26534b7dc0536ec93c481a5dc07297`, packed integrity `sha512-Sw8RIyxHkjxllwwh+9za5ItoM9X0NwN4R8+Qdd7nvOuU6qAm9LotIC09GOJDim3o9jc9m8yTqxKciroRTS12EQ==`) while keeping SDK `3.7.64` unchanged. The embedded MCP pin requires this installer patch to deliver the stdin usage-loss correction and safe bounded native Codex capture. Supported transcript schema is Codex `0.157.1`; capture covers only the latest proven model-call delta. Unknown versions, missing model/turn or billing metadata, unsafe paths and unproven subagent bindings remain incomplete or unpriced. Capture does not prove a baseline, complete overhead or savings. Restart the owning harness and run `doctor --self-test` after updating.
|
|
176
|
-
|
|
177
|
-
### Previous release: v0.1.62
|
|
178
|
-
|
|
179
|
-
v0.1.62 delivers the model-cost capture corrections in MCP `3.9.94` (source `9456bc63de4cc92f16726d996695516be9395f26`, packed integrity `sha512-gEQejUWkcuKd1p930TLsWCSMM4rjmr/Wzz0++qa69B6hj/e64lMdT9xO+jZP8+yl4WLKgcfo0raHANllUe96/A==`) and SDK `3.7.64` (source `40b68dee609e9351fa6c79aee629fc88869a3b4f`, packed integrity `sha512-8qJj/8ouHEz1NnZkmujtFxUm/fWldqR/rHv62/sqabaxT0H90xCCHxodLOkV0SVxDscAtnahioZakqkeGNUwyA==`). Published installer0.1.61 pins older bytes and cannot deliver these fixes. Only observed usage with sufficient host, model, token and pricing evidence becomes calculated cost; unobservable host usage, unsupported streams and mixed cache TTL writes stay incomplete. No baseline or net savings is invented. Update once, restart the owning harness and run `doctor --self-test` to verify actual active versions.
|
|
180
|
-
|
|
181
|
-
### Previous release: v0.1.61
|
|
182
|
-
|
|
183
|
-
v0.1.61 pins MCP `3.9.93` from source `2174aa09c9bba2f38a15bef4d8020803d6d36073` with packed integrity `sha512-X3ccZUKJqQxiEWq5jJE3xQzcBZbMxEcYxIuU0aKNNo5U1iji9N99pPa2Awm0fdZaRzYOYtdVbWrAmfPDvuYaKQ==`. This corrects the full11 canary operation identity so valid numeric UUIDs reach Auto and terminal outcome closure without weakening privacy validation. SDK remains `3.7.63`. The published `0.1.60` installer cannot deliver this pin. Update once, restart the owning harness, then run `doctor --self-test` before relying on the new client.
|
|
184
|
-
|
|
185
|
-
### Previous release: v0.1.60
|
|
186
|
-
|
|
187
|
-
v0.1.60 pins MCP `3.9.92` from source `d0d97d1b584c661d9a72696de7af02566fb317e3` with packed integrity `sha512-CAVbzDFanzI/b9EPennC1dUr8/Qq8wMiIl71/25puAfuW7CPSZ+qkhmMDIEnP50k3EgZHEdJo3sUTOJ1P7dzwA==`. This delivers the MCP reliability fix that keeps response-body reads inside the existing request deadline, preserves cancellation, and reports bounded, sanitized control-path errors. SDK remains `3.7.63`. The `0.1.59` installer cannot deliver this pin. Update once, restart the owning harness, then run `doctor --self-test` before relying on the new client.
|
|
188
|
-
|
|
189
|
-
### Previous release: v0.1.59
|
|
190
|
-
|
|
191
|
-
v0.1.59 pins published MCP `3.9.91` from source `96b58c9e5ec0356d5672edbb89275e3fbb6d3233` with packed integrity `sha512-2xbKhq1LQ2TlOM4XBpoLcBQNS1fnjxZFbSFwC/lwCUppU1M5NQ6fFCxcLrvHTNt0FM16WlVzxUDBtG8OzoFbuA==`. SDK remains `3.7.63`. This stops a later install from rewriting managed hooks back to MCP `3.9.89`. Restart the owning harness after update before relying on the new pin. The published `0.1.58` installer cannot deliver this pin.
|
|
192
|
-
|
|
193
|
-
### Previous release: v0.1.58
|
|
194
|
-
|
|
195
|
-
v0.1.58 pins MCP `3.9.89` from source `ff229e17419f65aeebd7fa7754dd61cbda61900d` with packed integrity `sha512-KC/P4dStzOOfZKxSwigQE4TWCt1TBgYINQzlXrnA5jpYHRrT2Jo73vaV4FiucVPOT+xyU1uCci+bmJoC35aZ0g==`; SDK remains `3.7.63`. Supported native hooks now include their host read, search, and status surfaces so MCP's private local session loop guard can stop unchanged successful checks, polls, and failed retries without adding routine backend writes. Install and update run `marrow-mcp loop-guard-self-test` against isolated temporary state and report configuration, isolated proof, and live host observation separately. Missing local control state stays enabled by default; an explicit owner disable is preserved byte-for-byte and prevents the controller from starting. Grok's trusted global hook file is created only at its direct owner-safe path, managed files are reconciled, and unmanaged files are preserved for owner review. Restart and complete each host's hook trust or review flow before relying on live enforcement.
|
|
196
|
-
|
|
197
|
-
### Previous release: v0.1.57
|
|
198
|
-
|
|
199
|
-
v0.1.57 pins the npm-verified MCP `3.9.88` and SDK `3.7.63` packages. Doctor now recognizes an installed and lockfile-verified SDK `3.7.63` instead of suggesting `3.7.62`. If a workspace has a newer stable SDK version, doctor preserves it and asks for official registry verification before replacement. The generated MCP setup, hooks, and update instructions target `3.9.88`; restart the owning harness and run `npx @getmarrow/install@latest doctor --self-test` after activation.
|
|
200
|
-
|
|
201
|
-
## Previous: v0.1.56
|
|
202
|
-
|
|
203
|
-
v0.1.56 pins the officially verified MCP `3.9.80` release from source `ee1eda3f201965a6530256accbdf175660dd8ad6` with registry integrity `sha512-uou3X18pESV39EMmddDrYN7yd6MrZzosrnQ1eRtvK5j3yuBLAlupj5kQVrrKEWAL6xwuLebXq2isivK2O/2WrA==`; SDK remains `3.7.62`. Doctor now directs stale, mixed, or version-unknown MCP installations through one `npx -y @getmarrow/install@latest update`, followed by one owning-harness restart and one `doctor --self-test` verification. The update resolves one official target and applies it consistently across detected Marrow-managed instructions, MCP launch configuration, and supported native hooks without claiming that already-running processes changed.
|
|
204
|
-
|
|
205
|
-
## Previous: v0.1.55
|
|
206
|
-
|
|
207
|
-
v0.1.55 pins sealed MCP candidate `3.9.79` from source `11f00049043d0aba90704ecbf69f32d2278a4573` for ordinary setup, generated launch configuration, and native hooks. Doctor, update, and repair retain exact-version resolution and never propagate a newer local version unless official registry metadata verifies it; offline operation preserves unverified-ahead owner surfaces and uses the sealed candidate for new managed targets.
|
|
208
|
-
|
|
209
|
-
## Previous: v0.1.54
|
|
210
|
-
|
|
211
|
-
v0.1.54 pins sealed MCP candidate `3.9.77` from source `1e782d8ba6bbb54bfaa322f0300565c7176f1969` and makes ordinary setup use the primary tool surface without writing a profile variable. Explicit `core` and `full` selections remain preserved, invalid values fail closed with a bounded repair, and human/JSON self-test output distinguishes configured/effective profile, expected visibility, actual post-reload visibility, and backend-projected entitlement state. Backend projections are status evidence only and always report `authorizes_calls: false`.
|
|
212
|
-
|
|
213
|
-
## Previous: v0.1.53
|
|
214
|
-
|
|
215
|
-
v0.1.53 pins the native-gate MCP candidate `3.9.75` and reconciles only Marrow-owned native hook surfaces. Codex uses `.codex/hooks.json`; Cursor and Composer use `.cursor/hooks.json`; Cline uses bounded executables under `.clinerules/hooks/`; Windsurf uses `.windsurf/hooks.json`; Gemini CLI receives named BeforeTool, AfterTool, and AfterAgent groups in `.gemini/settings.json`; Grok receives trusted global hooks in `~/.grok/hooks/marrow.json`. Grok PreToolUse validates strict private allow/deny JSON and fails closed with exit `2` when the child cannot provide an exact decision; PostToolUse/PostToolUseFailure emit compact results; one nonblocking Stop hook closes the turn with no duplicate SessionEnd hook. Grok hooks remain user-toggleable, so restart plus `/hooks` inspection is required and configuration never proves observed coverage.
|
|
216
|
-
|
|
217
|
-
The integration boundary is explicit: native hooks remain cooperative/client-reported until authoritative server receipts exist; MCP tools are on demand; Codex requires restart plus owner `/hooks` trust review; Windsurf requires restart, workspace trust review, and Restricted Mode to be off; Gemini CLI requires restart and `/hooks panel` fingerprint review/approval, with `/hooks enable-all` reserved for an explicitly disabled configuration after owner review; Grok requires restart and `/hooks` inspection because its trusted global hooks remain user-toggleable; the governed wrapper remains an explicit bounded fallback; owned Node processes use the SDK passive runtime while installed; and custom hosts require a bounded event adapter. Exact package SHA/integrity can prove artifact provenance, not runtime coverage.
|
|
218
|
-
|
|
219
|
-
## Previous: v0.1.52
|
|
220
|
-
|
|
221
|
-
v0.1.52 keeps MCP `3.9.74` and SDK `3.7.62`, and makes generated passive runtime identity follow the current process: `MARROW_FLEET_AGENT_ID` first, then `MARROW_AGENT_ID`, with the installer-captured identity retained only as a fallback. This prevents a stale installed harness identity from overriding the current Codex, Bob, or other canonical process identity. Managed MCP config does not store an API key or shell-style credential placeholder; the owning harness inherits the key from trusted environment or secret-manager state.
|
|
222
|
-
|
|
223
|
-
The integration boundary is explicit: native Claude hooks are installed only where supported and remain cooperative/client-reported until authoritative server receipts exist; MCP tools are on demand; Codex, Grok, Gemini, and similar CLIs use the governed wrapper for consequential control; owned Node processes use the SDK passive runtime while installed; and custom hosts require a bounded event adapter. Exact package SHA/integrity can prove artifact provenance, not runtime coverage. Activation-profile delivery is authenticated `client_self_reported` telemetry with `certified_coverage: false`; it acknowledges delivery but cannot attest that a hook, wrapper, or adapter ran.
|
|
224
|
-
|
|
225
|
-
## Previous: v0.1.48
|
|
226
|
-
|
|
227
|
-
v0.1.48 pinned MCP `3.9.72` and SDK `3.7.61`. The SDK kept passive capture enabled without intercepting its own Marrow control-plane requests, while every generated MCP setup and repair command used the supported MCP release.
|
|
228
|
-
|
|
229
|
-
## Previous: v0.1.47
|
|
230
|
-
|
|
231
|
-
v0.1.47 makes activate honest about reload and the first capture path:
|
|
232
|
-
|
|
233
|
-
- after writing MCP or hooks, activate reports that this process is not live until harness restart and `doctor --self-test`;
|
|
234
|
-
- first capture is Claude native hooks, Cursor on-demand `marrow_agent_runtime`, or the Codex/Grok governed runner;
|
|
235
|
-
- generated MCP setup, launch, and certified hook commands pin the release current at that time;
|
|
236
|
-
- SDK detection and operator-approved upgrade rules pinned the release current at that time;
|
|
237
|
-
- empty token savings stay zero until observed model usage lands.
|
|
238
|
-
|
|
239
|
-
## Previous: v0.1.46
|
|
240
|
-
|
|
241
|
-
v0.1.46 makes default install cover every workspace honestly:
|
|
242
|
-
|
|
243
|
-
- auto mode now writes MCP plus agent instructions in every project, and the SDK passive runtime whenever Node is present;
|
|
244
|
-
- Claude native hooks still install only when `.claude` is present; detected Cursor workspaces get `.cursor/hooks.json` plus `.cursor/mcp.json`, and Composer uses that same Cursor-native lifecycle path;
|
|
245
|
-
- Hermes, OpenClaw, and custom hosts stay event-contract only and are not claimed as native interception;
|
|
246
|
-
- generated MCP setup, launch, and certified hook commands pin current MCP `3.9.64` from source `ed8293165247e89161045c7fbf68aeee4d51c6da`;
|
|
247
|
-
- SDK detection and operator-approved upgrade rules pin exact public `3.7.59`;
|
|
248
|
-
- empty token savings stay zero until observed model usage lands.
|
|
249
|
-
|
|
250
|
-
## Previous: v0.1.45
|
|
251
|
-
|
|
252
|
-
v0.1.45 pins the one-command setup path to the published receipt-safe MCP release:
|
|
253
|
-
|
|
254
|
-
- generated MCP setup, launch, and certified hook commands pin current MCP `3.9.62`;
|
|
255
|
-
- adapter provenance records exact MCP source `c025d720af8fe9b16702ba764ff85c822adc2a26` and the live public registry integrity;
|
|
256
|
-
- MCP versions older than `3.9.62` are treated as stale so new installs receive the fail-closed runtime authorization contract;
|
|
257
|
-
- `npx @getmarrow/install@latest update` is the owner-approved one-command refresh of certified install/SDK/MCP pins; doctor and status print an owner notice so agents can tell the user to update;
|
|
258
|
-
- self-test and governed-runner requests report install, SDK, and MCP versions together so the API can notify on any stale package;
|
|
259
|
-
- SDK `3.7.56` detection and operator-approved upgrade rules are unchanged.
|
|
133
|
+
The controller is not a boot service. After a host restart, or any exit that skips its shutdown handler, doctor reports it as `stale` until the next install, update, or `controller ensure`. Local control can be inspected and changed with `npx @getmarrow/install control status|disable --yes|enable`. While local control is disabled, the controller is not started, and doctor reports a stopped or stale controller as not required instead of recommending `controller ensure`; missing state means enabled, and an explicit owner disable is preserved. Unsafe controller state or an unverified or unresponsive controller process keeps its exact fix.
|
|
260
134
|
|
|
261
|
-
##
|
|
135
|
+
## What's New in v0.1.68
|
|
262
136
|
|
|
263
|
-
v0.1.
|
|
137
|
+
v0.1.68 installs MCP `3.9.100`. In short (the full entry is in the [CHANGELOG](https://github.com/getmarrow/marrow-install/blob/master/CHANGELOG.md)):
|
|
264
138
|
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
139
|
+
- **Approvals in chat and terminal.** A held action is approved where people work: in the host's own prompt, at the runner's terminal, or by the account owner's one-tap link for owner-only holds and arbitration. See [Approvals in Chat and Terminal](#approvals-in-chat-and-terminal).
|
|
140
|
+
- **Local policy never loosens a gate.** `--policy warn` and `--policy audit` (and `MARROW_GOVERN_POLICY`) no longer let a command run when Marrow enforces the gate. Only a gate Marrow marks advisory runs with a warning.
|
|
141
|
+
- **Key storage.** A first install stores a key from `MARROW_API_KEY` in the owner-only `~/.marrow/env` once the self-test passes, and the runner reads it there.
|
|
142
|
+
- **Local MCP runtime.** Hooks start a verified local copy of the pinned MCP instead of `npx`. See [Local MCP runtime](#local-mcp-runtime).
|
|
143
|
+
- **Governed runner.** Only secret values are redacted, so commands that differ after a secret stay different actions; held commands are picked up on rerun by exactly the same command.
|
|
144
|
+
- **Day one.** Claude Code is detected from your installation too, and only detected hosts get files.
|
|
145
|
+
- **Uninstall.** `uninstall --yes` removes only Marrow's own entries. See [Uninstall](#uninstall).
|
|
269
146
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
v0.1.43 hardens the MCP control path and makes stale client recovery explicit:
|
|
273
|
-
|
|
274
|
-
- `doctor` detects active and configured stale, mixed, or version-unknown Marrow MCP clients without exposing command lines, file paths, configuration contents, or credentials;
|
|
275
|
-
- every generated MCP launch and hook uses the package-explicit `npx --package ... marrow-mcp` form so npm can resolve the executable reliably;
|
|
276
|
-
- when repair is needed, `doctor` reports the pinned setup command, the separate owning-harness restart requirement, and a self-test verification command; it does not terminate harness processes itself;
|
|
277
|
-
- certified hooks pinned MCP `3.9.59` and SDK `3.7.56` so the installed runtime matched that release's advertised control contract;
|
|
278
|
-
- existing harnesses retain their honest coverage level: native hooks where supported, MCP calls where available, and governed wrappers or event contracts elsewhere;
|
|
279
|
-
- package upgrades remain operator-approved and never rotate keys or rewrite unrelated configuration.
|
|
280
|
-
|
|
281
|
-
## Previous: v0.1.42
|
|
282
|
-
|
|
283
|
-
v0.1.42 added deterministic active-process detection, including direct `node_modules/.bin/marrow-mcp` launches, while keeping repair operator-approved.
|
|
284
|
-
|
|
285
|
-
## Previous: v0.1.40
|
|
286
|
-
|
|
287
|
-
v0.1.40 binds governed runs to a privacy-safe workspace fingerprint and separates observed execution from verified completion:
|
|
288
|
-
|
|
289
|
-
- ordinary prompts receive one compact context read; risky or mutating prompts receive one fresh runtime gate instead;
|
|
290
|
-
- passive prompt telemetry is buffered locally rather than delaying the agent turn;
|
|
291
|
-
- transient read failures can use clearly labeled owner-only last-known guidance, while authentication failures never use cache;
|
|
292
|
-
- `doctor` prints the exact `npx -y --package=@getmarrow/mcp@latest marrow-mcp ping` command for measured current/p50/p99 latency, last success, and backlog health;
|
|
293
|
-
- certified hook commands pin MCP `3.9.56` and SDK `3.7.55` so advertised behavior matches that release's deployed server contract;
|
|
294
|
-
- governed runtime requests attach a stable privacy-safe project fingerprint and harness label without sending the raw working-directory path;
|
|
295
|
-
- successful command exit remains observed execution, not verified business completion, unless a verification command or explicit proof file supplies evidence;
|
|
296
|
-
- the integration matrix now reports prompt injection, pre-action, action result, closure, proof, cached brief, restart survival, evidence adapter, and safe repair separately.
|
|
297
|
-
|
|
298
|
-
It preserves the intervention receipts introduced in v0.1.38.
|
|
299
|
-
|
|
300
|
-
## Previous: v0.1.38
|
|
301
|
-
|
|
302
|
-
v0.1.38 makes a meaningful Marrow intervention visible without adding manual work to routine agent sessions:
|
|
303
|
-
|
|
304
|
-
- generated instructions tell agents to retrieve and relay one factual intervention receipt after Marrow changes consequential work;
|
|
305
|
-
- Fleet Reports surface the same receipt for owners, including the required workflow, proof status, permit follow-through, and recorded outcome;
|
|
306
|
-
- agents remain quiet for routine low-risk work, and receipts exclude raw context, raw outcomes, proof values, credentials, and cross-tenant data.
|
|
307
|
-
|
|
308
|
-
It preserves the automatic local control lifecycle introduced in v0.1.37.
|
|
309
|
-
|
|
310
|
-
## Previous: v0.1.37
|
|
311
|
-
|
|
312
|
-
v0.1.37 adds the automatic local control lifecycle after explicit owner activation:
|
|
313
|
-
|
|
314
|
-
- a project-and-agent-scoped loopback controller survives individual agent sessions;
|
|
315
|
-
- installer-managed hooks are checked and safely restored without changing unrelated files;
|
|
316
|
-
- the governed runner automatically classifies consequential commands and requires fresh signed permits for protected actions;
|
|
317
|
-
- pre-action, execution, result, proof, and outcome receipts share stable correlation;
|
|
318
|
-
- integration coverage states exactly what is native, MCP-routed, governed-wrapper controlled, or adapter-required;
|
|
319
|
-
- in-session value messages use measured evidence only and report unavailable data instead of synthetic savings.
|
|
320
|
-
|
|
321
|
-
It preserves the update and permit controls introduced in v0.1.36.
|
|
322
|
-
|
|
323
|
-
## Previous: v0.1.36
|
|
324
|
-
|
|
325
|
-
v0.1.36 combines guided, operator-controlled client updates with a signed permit boundary for protected actions. Installer status, activation reports, and the Fleet Operator expose request-specific update advisories with exact update and verification commands while keeping local mutation explicit:
|
|
326
|
-
|
|
327
|
-
- official installer requests identify the installed `@getmarrow/install` version;
|
|
328
|
-
- status, self-test, and Fleet Operator output show recommended, unrecognized, and security-required update states without conflating them;
|
|
329
|
-
- generated agent instructions tell the agent to notify the operator and obey local change policy;
|
|
330
|
-
- certified activation pins the matching MCP and SDK releases, including exact SDK registry integrity;
|
|
331
|
-
- `activate`, `doctor`, and `--repair` remain explicit commands and preserve unrelated hooks and configuration.
|
|
332
|
-
|
|
333
|
-
The governed runner makes protected actions executable only through a short-lived, signed Marrow permit bound to the exact account, agent, session, action, target, canonical action surfaces, runtime gate, and decision before starting the child process. It then closes that permit with exact evidence and the real outcome:
|
|
334
|
-
|
|
335
|
-
- deploy, publish, merge, migration, credential, and other protected work fails closed when its permit cannot be verified;
|
|
336
|
-
- the child process receives only the scoped permit, never the Marrow API key through a new broker interface;
|
|
337
|
-
- permits are single-use, expire within minutes, and cannot be replayed for another agent, action, target, or session;
|
|
338
|
-
- `permit` and `verify-permit` provide deterministic CI choke points;
|
|
339
|
-
- the loopback `sidecar` keeps private state owner-only and reports hook/configuration drift;
|
|
340
|
-
- `coverage` reports permit closure, bypasses, stale sidecars, and hook health with exact repair steps;
|
|
341
|
-
- correlated result hooks can close evidence automatically, while incomplete protected work remains visible;
|
|
342
|
-
- controlled break-glass access requires an authenticated account owner, a current runtime gate, a reason, a short expiry, and evidence closure.
|
|
343
|
-
|
|
344
|
-
It preserves the measurable passive-governance coverage introduced in v0.1.34:
|
|
345
|
-
|
|
346
|
-
- Claude Code installation includes exact `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, and `Stop` hooks;
|
|
347
|
-
- matching pre-action/result receipts use one tool correlation, and activation fingerprints the exact hook contract without uploading configuration contents;
|
|
348
|
-
- the capability registry distinguishes native hooks, MCP, SDK passive runtime, governed wrappers, and custom event contracts;
|
|
349
|
-
- `activate` fails when the local integration is incomplete or the server does not accept the exact activation profile;
|
|
350
|
-
- `doctor` and `--repair` use the same configuration evidence without exposing configuration contents;
|
|
351
|
-
- the harness certification suite prevents support claims from overstating what is automatic;
|
|
352
|
-
- unavailable coverage remains “insufficient data” instead of a synthetic percentage.
|
|
353
|
-
|
|
354
|
-
It preserves agent-disagreement visibility from v0.1.33 and the server-confirmed first-run self-test introduced in v0.1.29:
|
|
355
|
-
|
|
356
|
-
- GitHub and npm now advertise separate signed discovery placements;
|
|
357
|
-
- package metadata identifies the installer as agent governance rather than a general memory utility;
|
|
358
|
-
- the README tells agents and operators when to use the installer and what public discovery will not collect;
|
|
359
|
-
- bounded positive and negative recommendation criteria stop agents from forcing Marrow into irrelevant workflows;
|
|
360
|
-
- current evidence, integration paths, and published references are linked from one review-dated contract;
|
|
361
|
-
- `npx @getmarrow/install activate` detects the current harness, writes supported passive controls, creates and closes a harmless decision, and asks Marrow to verify that exact outcome;
|
|
362
|
-
- activation succeeds only when the API returns a tenant-scoped receipt bound to the exact test decision, agent, runtime gate, and closed successful outcome;
|
|
363
|
-
- that receipt verifies only the install self-test; activation returns `activation_scope: server_self_test_only`, `coverage_verified: false`, `passive_live: false`, and `reload_required: true`;
|
|
364
|
-
- existing setup, governed runner, and TUI commands remain compatible.
|
|
365
|
-
|
|
366
|
-
Use `activate` when you want one command with an explicit success contract. Use `--yes` when an existing automation already handles setup prompts and verification output.
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
npx @getmarrow/install activate
|
|
370
|
-
```
|
|
147
|
+
Earlier release notes are in the [CHANGELOG](https://github.com/getmarrow/marrow-install/blob/master/CHANGELOG.md).
|
|
371
148
|
|
|
372
149
|
## What It Detects
|
|
373
150
|
|
|
374
|
-
The installer detects
|
|
151
|
+
The installer detects these from project and home-directory signals:
|
|
375
152
|
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
- MCP client configuration;
|
|
379
|
-
- Node.js and Python projects;
|
|
380
|
-
- CI, deploy, publish, merge, migration, and custom shell workflows.
|
|
153
|
+
- Claude Code (`.claude/settings.json` or `CLAUDE.md` in the project, or your installation: `~/.claude/`, `~/.claude.json` or `claude` on `PATH`; a project marker of another host still ranks first), Cursor and Cursor Composer (`.cursor`), Cline (`.clinerules`), Windsurf (`.windsurf`), Gemini CLI (`.gemini`), Grok (`~/.grok` or `.grok`), Codex (a `.codex` directory or an `AGENTS.md` with owner content; one holding only the Marrow block is not a signal), Hermes (see above) and OpenClaw;
|
|
154
|
+
- MCP client configuration, Node.js and Python projects.
|
|
381
155
|
|
|
382
|
-
|
|
156
|
+
OpenCode, DeepSeek, Qwen, Kimi, MiniMax and GLM are not detected by the installer. They are governed through the runner, labelled with `MARROW_CLIENT` or `--client`. `MARROW_CLIENT` also overrides detection for the others.
|
|
157
|
+
|
|
158
|
+
Marrow does not replace these models or harnesses. It adds a common business control, proof, and outcome layer around the actions they perform. Auto mode writes only for what it detects: the MCP configuration and native hooks for each detected host; the Marrow block in `AGENTS.md` only for a host that reads it (Codex, Windsurf, Gemini CLI, Cline, Grok, Hermes, OpenClaw) or when the file already carries the block, so a Claude-Code-only repository gets none; and the SDK passive runtime and SDK advice only where the project declares or installs `@getmarrow/sdk` or already has the runtime. `--mode both` or `--mode md` writes `AGENTS.md` regardless.
|
|
383
159
|
|
|
384
160
|
## First-Run Activation
|
|
385
161
|
|
|
@@ -391,12 +167,43 @@ With a valid key, `activate`:
|
|
|
391
167
|
4. closes its outcome;
|
|
392
168
|
5. sends the exact self-test decision ID to Marrow for server-side verification;
|
|
393
169
|
6. reads agent status and the one-call runtime;
|
|
394
|
-
7. registers the detected capability, expected hooks, and one-way configuration fingerprint as authenticated
|
|
170
|
+
7. registers the detected capability, expected hooks, and one-way configuration fingerprint as authenticated `client_self_reported` telemetry with `certified_coverage: false`. This acknowledges delivery; it cannot attest that a hook, wrapper, or adapter ran;
|
|
395
171
|
8. returns a server-confirmed self-test receipt plus an explicit restart and `doctor --self-test` next action.
|
|
396
172
|
|
|
397
|
-
|
|
173
|
+
Activation succeeds only when the API returns a tenant-scoped receipt bound to the exact test decision, agent, runtime gate, and closed successful outcome. It fails when the local integration is incomplete or the server does not accept the exact activation profile. The receipt verifies only the install self-test: activation returns `activation_scope: server_self_test_only`, `coverage_verified: false`, `passive_live: false`, and `reload_required: true`. It does not verify continuous passive interception or certify installed coverage. After writing MCP or hooks, the owning harness must restart, then `npx @getmarrow/install@latest doctor --self-test` must pass. A local file write, integration event, or client-supplied `verified: true` value cannot elevate coverage.
|
|
174
|
+
|
|
175
|
+
The self-test retries 429/502/503/504 and pending answers with the same `Idempotency-Key` (at most three attempts, about one second apart) and closes the decision its runtime check creates. Client errors fail immediately, and a final failure names the last state. Use `--yes` when an existing automation already handles setup prompts.
|
|
176
|
+
|
|
177
|
+
The installer does not claim identical automation for every harness. Configured native hooks remain cooperative/client-reported; MCP covers only on-demand MCP-routed actions; the SDK covers only owned Node processes where its runtime is installed; the governed runner covers only commands launched through it; custom harnesses must map their own lifecycle events. Exact package SHA/integrity proves artifact provenance, not runtime coverage.
|
|
178
|
+
|
|
179
|
+
## Native Hooks
|
|
398
180
|
|
|
399
|
-
The installer
|
|
181
|
+
The installer reconciles only Marrow-owned hook entries and keeps unrelated hooks and configuration.
|
|
182
|
+
|
|
183
|
+
| Harness | Written to | Events |
|
|
184
|
+
| --- | --- | --- |
|
|
185
|
+
| Claude Code | `.claude/settings.json` | `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `Stop` |
|
|
186
|
+
| Codex | `.codex/hooks.json` | prompt, pre-action, action result, session end |
|
|
187
|
+
| Cursor, Composer | `.cursor/hooks.json`, `.cursor/mcp.json` | `preToolUse`, `postToolUse`/`postToolUseFailure`, `stop` |
|
|
188
|
+
| Cline | `.clinerules/hooks/` (non-overwriting executables) | `PreToolUse`, `PostToolUse`, `TaskCancel` |
|
|
189
|
+
| Windsurf | `.windsurf/hooks.json` | pre-action, action result, response closeout |
|
|
190
|
+
| Gemini CLI | `.gemini/settings.json` | `BeforeTool`, `AfterTool`, `AfterAgent` |
|
|
191
|
+
| Grok | `~/.grok/hooks/marrow.json` | `UserPromptSubmit`, `PreToolUse`, `PostToolUse`/`PostToolUseFailure`, one nonblocking `Stop` |
|
|
192
|
+
|
|
193
|
+
- Claude Code hooks are written whenever Claude Code is detected, from the project or your installation. They use the Claude-specific entrypoints (`claude-pre-action-hook`, `claude-hook`, `claude-context-hook`, `claude-session-hook`), and hook activity is labelled `claude-code`. Existing entries are migrated in place without duplicates.
|
|
194
|
+
- Hooks cover read, search and status tools as well, so the local loop guard can stop unchanged successful checks, polls and failed retries without routine backend writes. Install and update run `marrow-mcp loop-guard-self-test` against isolated temporary state and report configuration, isolated proof and live host observation separately.
|
|
195
|
+
- Grok's pre-action hook validates strict private allow/deny JSON and fails closed with exit `2` when the child cannot give an exact decision. Its global hook file is created only at its direct owner-safe path; unmanaged files are preserved for owner review.
|
|
196
|
+
- Hooks are cooperative/client-reported until authoritative server receipts exist. After install: Codex needs a restart and owner `/hooks` trust review; Cursor needs a restart and `/hooks` trust review; Cline needs Enable Hooks, executable and workspace trust, and a restart; Windsurf needs a restart, workspace trust review, and Restricted Mode off; Gemini CLI needs a restart and `/hooks panel` fingerprint review (use `/hooks enable-all` only for an explicitly disabled configuration, after review); Grok needs a restart and `/hooks` inspection because its hooks stay user-toggleable.
|
|
197
|
+
- With an MCP that answers approval hooks, the installer also writes the approval hooks listed under [Hooks the installer writes](#hooks-the-installer-writes).
|
|
198
|
+
- A configured hook never proves observed coverage. Run `doctor --self-test` after the restart.
|
|
199
|
+
|
|
200
|
+
### Local MCP runtime
|
|
201
|
+
|
|
202
|
+
Starting the MCP through `npx` costs 0.6 to 1.3 seconds per gated tool call before Marrow is even contacted. A write run of install or update installs the pinned `@getmarrow/mcp` (or the registry-verified update target) into the owner-only `~/.marrow/runtime/mcp/<version>/` (directories 700) with `npm install --ignore-scripts`, and keeps it only when the installed package's integrity equals the pinned integrity (and the SDK's, at the pinned SDK version). The node binary is captured at install as an absolute path, so the hooks need no `PATH` lookup.
|
|
203
|
+
|
|
204
|
+
Hook commands reach the runtime through `$HOME`, so project hook files name no local path and stay the same for every user; the entrypoints and their arguments are unchanged. Each start checks the runtime's files against the recorded integrity; when the copy is missing, any file changed, was added or was removed, or its node binary is gone, the same entrypoint runs through `npx` as before, with the same fail-closed behaviour. The controller's maintenance, which restores managed hooks when it starts and every 5 minutes, keeps a project's hooks on the verified local copy when its install put them there; it checks the copy and never installs one. npm gets at most 30 seconds, after a one-line notice; if it does not finish, hooks keep using `npx`. `update` installs the runtime for a new pin and removes older versions; `uninstall` removes `~/.marrow/runtime`. Cursor's 15-second fail-closed timeout and every other hook budget are unchanged. Windows keeps `npx`. Set `MARROW_LOCAL_RUNTIME=0` or pass `--no-local-runtime` to keep a project's hooks on `npx`; the controller's maintenance keeps each project's hooks in the form its install chose, so such a project stays on `npx` even when another project's install put a local copy on the machine.
|
|
205
|
+
|
|
206
|
+
Measured on Linux (Node 22, MCP 3.9.98, wall time per pre-action hook call, no network): through `npx` 1.2 to 1.3 seconds with an empty npm cache and 0.67 to 0.77 seconds warm; from the local runtime 0.11 to 0.17 seconds for the first call and 0.11 to 0.13 seconds after, for Claude Code, Codex, Cursor and Gemini CLI.
|
|
400
207
|
|
|
401
208
|
## Govern TUI
|
|
402
209
|
|
|
@@ -406,7 +213,7 @@ Open the interactive setup panel:
|
|
|
406
213
|
npx @getmarrow/install govern
|
|
407
214
|
```
|
|
408
215
|
|
|
409
|
-
The TUI shows detected harnesses and project risks, recommends passive, pilot, or enforce mode with reasons, lets the owner accept or override the recommendation, runs the self-test, and confirms the active controls.
|
|
216
|
+
The TUI shows detected harnesses and project risks, recommends passive, pilot, or enforce mode with reasons, lets the owner accept or override the recommendation, runs the self-test, and confirms the active controls. Exit with `q`, `Esc` or `Ctrl+C`.
|
|
410
217
|
|
|
411
218
|
For non-interactive environments:
|
|
412
219
|
|
|
@@ -426,20 +233,26 @@ npx @getmarrow/install run \
|
|
|
426
233
|
-- wrangler deploy
|
|
427
234
|
```
|
|
428
235
|
|
|
429
|
-
The agent is the one Marrow resolves for the API key (its bound agent or the plan seat). Set `MARROW_AGENT_ID
|
|
236
|
+
The agent is the one Marrow resolves for the API key (its bound agent or the plan seat). Set `MARROW_FLEET_AGENT_ID` or `MARROW_AGENT_ID` (the first wins), or pass `--agent <id>`, only for an agent already registered with Marrow. One `--` separates the command; `run -- -- <command>` also works. The runner binds each run to a privacy-safe workspace fingerprint and harness label, never the raw working-directory path.
|
|
430
237
|
|
|
431
238
|
The runner:
|
|
432
239
|
|
|
433
240
|
1. requests the Marrow runtime gate and reads its decision, mode (enforced or advisory) and gate receipt;
|
|
434
241
|
2. uses the decision the runtime created, or records one against that exact gate;
|
|
435
|
-
3. where the plan enforces the gate, requests and verifies a single-use permit bound to the exact action, target, canonical action surfaces and gate receipt;
|
|
436
|
-
4. blocks protected work if an enforced gate, policy or permit verification fails. Where the gate is advisory, it shows the warning and runs the command;
|
|
242
|
+
3. where the plan enforces the gate, requests and verifies a single-use permit bound to the exact account, agent, session, action, target, canonical action surfaces and gate receipt;
|
|
243
|
+
4. blocks protected work if an enforced gate, policy or permit verification fails. Deploy, publish, merge, migration, credential and other protected work fails closed when its permit cannot be verified. Where the gate is advisory, it shows the warning and runs the command. When Marrow holds the action for approval, the runner asks where the operator is, or asks the account owner (see [Approvals in Chat and Terminal](#approvals-in-chat-and-terminal)), and runs the command only after Marrow has recorded the approval;
|
|
437
244
|
5. runs the original command with the scoped permit, not the Marrow API key;
|
|
438
245
|
6. records success or failure with the gate receipt, supplies every exact server-required proof field through a redacted proof pack, and closes the permit. It reports an outcome that Marrow did not commit as trusted instead of skipping it.
|
|
439
246
|
|
|
440
|
-
|
|
247
|
+
What leaves the machine is the command, `--action` and `--target` (or `MARROW_ACTION_TARGET`) with each secret value replaced by `[redacted]`, and nothing else of the secret. A secret value is the value of a name that contains token, secret, password, passwd, passphrase, key, credential, auth or webhook, or whose part is `pass` or `pwd` (`TF_TOKEN=`, `SECRET_KEY_BASE=`, `X_API_KEY_ID=`, `DB_PASS=`, `"client_secret":`, `password:`, `-H "apikey: …"`, indented YAML), except names that hold no secret (`max_tokens`, `keyspace`, `tokenizer`, `author`, `oauth`, `public_key` and the like) and names that say where a secret is (`--key-file`, `KEY_VAULT_NAME`: ending in file, path, name, region and the like); an `Authorization` credential (all of a Digest one) or a `Bearer`/`Basic` credential; the password in `user:password@` in a URL and in an HTTP client's `-u user:password`; the value after `--token`, `--github-token`, `--db-password` and other flags ending in token, password, secret or key, after `config set NAME` for such a name (not a plain `true` or `off`), after `docker login -p`, `redis-cli -a`, `gh secret set --body` and `mysql -p`; and known key formats. Only the value is replaced and the text around it stays, so two commands that differ after a secret (`?token=…&env=staging` and `?token=…&env=production`) reach Marrow as two different action texts, and a hold or a permit for one never carries over to the other. A value is a whole shell word: quoted pieces glued to it (`TOKEN='a'"'"'b'`) belong to it, and in a command word the shell already unquoted (`env PASSWORD="a b"`) spaces and quotes do too. A value may span lines: a quoted value, a key block from `-----BEGIN …` to `-----END …` whose lines are key data, a YAML block (`password: |`), and in a command word the following lines that are key data or indented. The quoted argument of `-d`, `--data`, `--json`, `-F`, `--form`, `-H` or `--header` is one field or header, so its value runs to the closing quote or the next field. It ends before another `name=`; at a shell operator or command substitution in a shell script (`bash -c '…'`, the remote command after `ssh`, `su -c`, `eval`, and a script quoted inside one of these, so `ssh host 'TOKEN=…; rm -rf /data'` keeps `rm -rf /data` visible); and in other text at `;` or `|` followed by a command, at `&&`, `||` or `&` before a space. `#` and `,` end it only before another `name=`. A whole-word setting (`NAME=value` as its own word, after `env`, `-e`, `--env` or `--build-arg`, or in free text) runs to the end of its word; only a URL query, an HTTP client's form or header argument, a field inside a longer word and shell text end a value before the next `name=`. A hidden value that holds a blank, a quote, a shell operator or a separator is written as Marrow's `[REDACTED_AMBIGUOUS]`, and Marrow never binds an action carrying it to an approval, so a SELECT approval can never be reused for a DROP hidden behind the same secret. A URL, endpoint or host under a credential name (`SECRET_URL`, `TOKEN_URL`, a webhook) is hidden too. Risk is judged on both the command as typed (locally) and its redacted text, and the stricter verdict counts; the type is the command's own (a DROP stays a migration). An unknown option is named in an error only when it is a plain option name, never with its value.
|
|
248
|
+
|
|
249
|
+
A successful exit is observed execution, not verified business completion, unless a verification command or a `--proof-file` supplies evidence. Permits are short-lived, expire within minutes and cannot be replayed for another agent, action, target or session.
|
|
250
|
+
|
|
251
|
+
Runtime, think and commit calls retry HTTP 429/502/503/504, timed-out attempts and pending answers up to three times with the same `Idempotency-Key`. Each attempt has a 10-second limit and all attempts share a 25-second deadline. Client errors are not retried. Each `run`, `gate` and `permit` uses its own keys. An answer in which Marrow withholds authorization (`allow: false` or observation-only) blocks the command under every plan and policy. `--policy warn` or `audit` (and `MARROW_GOVERN_POLICY`) never loosen a gate Marrow enforces: a block or a hold stops the command under every local policy. Only a gate Marrow reports as advisory runs with a warning.
|
|
441
252
|
|
|
442
|
-
`gate` exits 0 when the action may proceed, 12 when an enforced gate blocks it or needs owner approval, and 13 when no gate decision is available, so `gate ... && deploy` stops on a block. When the gate creates a decision, it prints the exact `proof` command, with `--session` and `--gate-receipt`, that records the outcome afterwards. `proof` exits non-zero unless Marrow returns `committed: true`.
|
|
253
|
+
`gate` prints the decision with its mode (enforced or advisory). It exits 0 when the action may proceed, 12 when an enforced gate blocks it or needs owner approval, and 13 when no gate decision is available, so `gate ... && deploy` stops on a block. When the gate creates a decision, it prints the exact `proof` command, with `--session` and `--gate-receipt`, that records the outcome afterwards. `proof` exits non-zero unless Marrow returns `committed: true`.
|
|
254
|
+
|
|
255
|
+
`run` exits 12 when a held action is declined, not answered, held with nobody present to approve it, or still waiting when the link or `--approval-wait` runs out; the command never ran. How a hold is approved is under [Approvals in Chat and Terminal](#approvals-in-chat-and-terminal).
|
|
443
256
|
|
|
444
257
|
Useful commands:
|
|
445
258
|
|
|
@@ -448,21 +261,73 @@ npx @getmarrow/install gate --type deploy --action "deploy production"
|
|
|
448
261
|
npx @getmarrow/install permit --type deploy --action "deploy production"
|
|
449
262
|
MARROW_ACTION_PERMIT=... npx @getmarrow/install verify-permit --type deploy --action "deploy production"
|
|
450
263
|
npx @getmarrow/install proof --session <session> --decision-id <id> --gate-receipt <receipt> --success --summary "smoke passed"
|
|
264
|
+
npx @getmarrow/install status
|
|
451
265
|
npx @getmarrow/install coverage
|
|
452
266
|
npx @getmarrow/install sidecar
|
|
453
|
-
npx @getmarrow/install
|
|
454
|
-
npx @getmarrow/install status
|
|
455
|
-
npx @getmarrow/install doctor
|
|
267
|
+
npx @getmarrow/install integrations --json
|
|
456
268
|
npx @getmarrow/install --repair
|
|
457
269
|
```
|
|
458
270
|
|
|
271
|
+
`permit` and `verify-permit` are deterministic CI choke points. `coverage` reports permit closure, bypasses, stale sidecars and hook health with exact repair steps. The loopback `sidecar` keeps private state owner-only and reports hook and configuration drift.
|
|
272
|
+
|
|
273
|
+
## Approvals in Chat and Terminal
|
|
274
|
+
|
|
275
|
+
When Marrow holds an action for approval (`review_required`), it is approved where people already work, and nobody is interrupted by default. Nobody logs in to approve; the dashboard lists receipts and reports. No runner, hook, or installer output names the dashboard as the step to approve.
|
|
276
|
+
|
|
277
|
+
Who can approve is Marrow's decision, read from the runtime for each hold:
|
|
278
|
+
- **By default** the operator's answer in the host's own prompt (or the runner's terminal prompt) counts, recorded as client-attested.
|
|
279
|
+
- **With nobody at a prompt** (a background or scheduled run, CI, a script, an agent's own shell) the action holds quietly: it does not run, nothing is sent, and the person approves it at their next session by retrying it where they get a prompt.
|
|
280
|
+
- **The account owner gets a one-tap link** (to the owner's own channel, email today) only for a category the owner approves personally, for arbitration, to reverse the owner's own decline when the operator asks, or when the owner turned on unattended pings. The link never reaches a hook, an agent, or the runner.
|
|
281
|
+
- **When Marrow cannot read the approval state**, the action is denied and nothing is sent; retry it in a moment.
|
|
282
|
+
|
|
283
|
+
Approvals given in your tool's prompt are reported by software on your machine. An agent running as your user could fake one for a single held action. For actions that must have your own approval, lock that category (verified only); then only your one-tap link or the dashboard counts, and Marrow never learns from or reuses tool-reported approvals across agents.
|
|
284
|
+
|
|
285
|
+
Never connect an agent to the email inbox that receives Marrow approval mail. An agent that can read that inbox can open the one-tap link itself.
|
|
286
|
+
|
|
287
|
+
### Hooks the installer writes
|
|
288
|
+
|
|
289
|
+
These hooks are written with MCP `3.9.99` and later (`MCP_HOST_APPROVAL_HOOKS_SINCE` in `src/pins.js`). v0.1.68 installs MCP `3.9.100`, so `install` and `update` write them; with an older MCP the earlier layout stays. `update` also uses a registry-verified MCP at or above that version.
|
|
290
|
+
|
|
291
|
+
| Host | Hooks for approvals | How the operator answers |
|
|
292
|
+
| --- | --- | --- |
|
|
293
|
+
| Claude Code | `PermissionRequest` → `claude-permission-request-hook` and `PostToolBatch` → `claude-hook`, both `async: true`, next to the existing hooks; the same entries `marrow-mcp setup` writes | In Claude Code's own permission dialog. The pass-through marker never answers or delays the dialog; a permission rejection is recorded as a decline, an interruption never is |
|
|
294
|
+
| Cursor | `beforeShellExecution` → `cursor-pre-action-hook` and `beforeMCPExecution` → the same entrypoint through a small guard, both `failClosed: true` with a 15-second timeout; `afterShellExecution` and `afterMCPExecution` → `cursor-hook`; `sessionStart` → `cursor-session-hook`; `beforeSubmitPrompt` → `cursor-context-hook`. Shell calls leave the `preToolUse` matcher. MCP calls stay in it, because cloud agents never run `beforeMCPExecution`: there `preToolUse` holds them, and in a local interactive session it lets `beforeMCPExecution` ask. The guard answers Marrow's own `marrow_*` tools at once, as the old matcher exempted them | Cursor's own prompt for shell and MCP calls in a local interactive session; the typed reply the hook shows the user (`marrow approve CODE`) for its other tools there. Background and cloud agents hold quietly |
|
|
295
|
+
| Gemini CLI | `BeforeAgent` → `gemini-context-hook`. The `BeforeTool` guard passes a denial that carries a code for the user only (`systemMessage`); any other output, a crash, or no answer within 4.5 seconds still blocks the call | The typed reply, in a local interactive session (`gemini`); `gemini -p` holds quietly |
|
|
296
|
+
| Codex | `UserPromptSubmit` → `codex-context-hook` (unchanged). Codex is never configured to "ask", because Codex lets an asked call run | The typed reply, in a local interactive session; `codex exec` holds quietly |
|
|
297
|
+
|
|
298
|
+
With an older MCP the earlier hook layout stays exactly as it was. Restart the host and complete its hook review before relying on them.
|
|
299
|
+
|
|
300
|
+
### Governed runner
|
|
301
|
+
|
|
302
|
+
For a held `run`:
|
|
303
|
+
|
|
304
|
+
- **At an interactive terminal**, when the operator may approve, the runner asks once: `Approve and run it now? [y/N]`. `y` is reported as the operator's answer from the runner's prompt (host `other`, labelled an allow rule because Marrow cannot see that prompt); the command then runs and closes on its gate receipt. `n` records a decline and closes the decision as a gate denial. No answer records nothing. A terminal driven by an agent host (Claude Code, Codex, Gemini CLI, Cursor's agent, OpenCode: their environment markers or an agent process above the runner) counts as no person present.
|
|
305
|
+
- **With nobody present** (no terminal, `CI`, `--no-interactive`, an agent host), the runner never answers for anyone. The command does not run, the runner exits 12 with "held until a person approves it", and nothing is sent unless Marrow says a link would be sent (above). `--approval-wait <seconds>` waits that long for an answer instead of exiting at once. `--policy warn|audit` does not change this: a hold Marrow enforces holds under every local policy (see [Governed Runner](#governed-runner)).
|
|
306
|
+
- **Owner-only holds** (a category the owner approves personally, arbitration) ask Marrow for the owner's one-tap link. For arbitration, a service that asks for it is told `person_present: true` only when a person at this terminal runs the command; an unattended or agent-terminal run sends nothing extra, and Marrow then holds it quietly unless the owner turned on unattended pings. When the owner already has a live link, the runner waits on that one (no new email). The runner prints only the channel and the link's expiry. At a terminal it waits until the owner answers or the link expires; without one it exits held. The hold is recorded before any wait starts, so Ctrl+C (or a kill, such as an agent host's tool timeout) stops only the wait: the run exits 12, held, and the next run uses the same receipt and link, with no new email, and picks up the owner's answer. It requests a link at most three times per run, and only when Marrow says a retry can help.
|
|
307
|
+
- **After the account owner declined** the action, the decline stands for 30 minutes across reruns. The runner asks the owner again only when the operator asks: `--request-owner-link`, or `y` to the terminal's "ask the owner" question. After an operator's own `n`, that answer stands for 30 minutes too.
|
|
308
|
+
- **Reruns pick the hold up.** The runner keeps an owner-only record of each held command under `~/.marrow/runner-holds` (gate receipt, decision and session ids, states and times; no command text). A record is filed under a keyed hash (with a private random salt kept in that directory) of the exact command as typed, with its `--action`, `--target` and `--type`, the agent, the API key that runs it (as its own keyed hash), the profile and policy, the project directory, the OS user and the Marrow service. The hash never leaves this machine, and a record is picked up only by exactly that command: a command that differs anywhere, including in text after a secret, starts its own hold. Rerunning the same command uses the same gate receipt: no new receipt and no new email. An approval that arrived after an earlier run stopped waiting is picked up and runs once; a second identical run started at the same time does not run.
|
|
309
|
+
- **The default session** is one per agent, project directory, OS user and Marrow service, per UTC day, so Marrow sees reruns as the same session. `--session` or `MARROW_SESSION_ID` still sets it.
|
|
310
|
+
- **Running an approved hold:** an approved ordinary hold runs on its gate receipt without an action permit, as with the MCP hooks, and the commit closes that receipt. An approved arbitration hold runs only with a permit, which Marrow issues only when the proposal the owner approved is this exact action; the commit carries the arbitration and owner approval receipts. When Marrow refuses that permit the hold is spent; when Marrow cannot issue it right now, the run stops and the next run picks up the same approval.
|
|
311
|
+
- **Older Marrow services** that cannot take approvals from a terminal hold the action and say so; the runner sends nothing there.
|
|
312
|
+
|
|
313
|
+
`--owner-approved` no longer does anything. It is accepted so older scripts keep working, prints a one-line notice, and never unblocks a hold. The runner never writes `proof.owner_approval` and drops one that a proof file carries: an approval is what Marrow records, not something a caller claims.
|
|
314
|
+
|
|
459
315
|
## Fleet Operator TUI
|
|
460
316
|
|
|
461
317
|
```bash
|
|
462
318
|
npx @getmarrow/install fleet
|
|
463
319
|
```
|
|
464
320
|
|
|
465
|
-
The fleet view shows live agents, active workflows, agent disagreements and their latest arbitration receipt, risky actions waiting for proof, stale or failed outcomes, capture health, recent decisions, and exact repair commands. Press Enter on **Agent disagreements** to inspect the bound decision, selected proposal, whether Marrow selected a proposal, synthesized a safe sequence, held the action for owner review, or blocked the conflicting actions. Review-required work
|
|
321
|
+
The fleet view shows live agents, active workflows, agent disagreements and their latest arbitration receipt, risky actions waiting for proof, stale or failed outcomes, capture health, recent decisions, and exact repair commands. Press Enter on **Agent disagreements** to inspect the bound decision, the selected proposal, and whether Marrow selected a proposal, synthesized a safe sequence, held the action for owner review, or blocked the conflicting actions. Review-required work is approved in the host's prompt or by the owner's one-tap link, as described under [Approvals in Chat and Terminal](#approvals-in-chat-and-terminal); the TUI does not let an agent approve itself. It is an operator surface for the authenticated account, not a public status dashboard.
|
|
322
|
+
|
|
323
|
+
## Uninstall
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
npx @getmarrow/install uninstall # preview: lists what would be removed, changes nothing
|
|
327
|
+
npx @getmarrow/install uninstall --yes # removes Marrow's own entries
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Uninstall removes only what Marrow wrote: Marrow's hook entries for every host (Claude Code, Codex, Cursor, Windsurf, Gemini CLI, Grok), the Marrow MCP server entry in `.mcp.json` and `.cursor/mcp.json`, and the Marrow block in `AGENTS.md`. The owner's own hooks, servers and settings in the same files are kept as they were. Files only Marrow writes (Cline hooks, the Cursor rule, Grok's `~/.grok/hooks/marrow.json`) are deleted only while they still hold exactly what Marrow wrote; an edited one is left in place and named. A `marrow` MCP server entry with a custom command is kept. Uninstall stops the project's Marrow controller first, because the controller restores missing managed hooks. It also removes the local MCP runtime in `~/.marrow/runtime` (hooks in other projects then start through `npx` until the next install there). It never edits the Hermes config, the SDK passive runtime or the env example; it names them with the step to take. Output lists paths and counts only. Restart the hosts afterwards.
|
|
466
331
|
|
|
467
332
|
## Integration Paths
|
|
468
333
|
|
|
@@ -478,14 +343,14 @@ These are integration surfaces for one Marrow product, not separate products.
|
|
|
478
343
|
|
|
479
344
|
## Exact Integration Coverage
|
|
480
345
|
|
|
481
|
-
Run `npx @getmarrow/install integrations --json` for the machine-readable matrix. The table below
|
|
346
|
+
Run `npx @getmarrow/install integrations --json` for the machine-readable matrix. The table below distinguishes full automatic interception from MCP-routed, wrapper-bounded, and adapter-required coverage.
|
|
482
347
|
|
|
483
348
|
| Harnesses | Prompt / pre-action / result | Closure and proof | Cached brief | Restart survival | Evidence adapter | Safe repair |
|
|
484
349
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
485
350
|
| Claude Code | Configured native hooks where supported; cooperative/client-reported until authoritative receipts exist | Correlated when determinable; proof is evaluated and is advisory or enforced according to plan policy | Owner-only bounded cache | Installed config and durable spool | Native hook evidence | Managed config after activation |
|
|
486
351
|
| Cursor, Composer | Native hooks plus MCP on demand | Native pre-action/result/closeout; explicit proof | Owner-only MCP cache | Hook/MCP config and durable spool | Client-self-reported lifecycle evidence | Managed config after activation and trust review |
|
|
487
352
|
| Cline | Native PreToolUse/PostToolUse/TaskCancel plus MCP on demand | Native pre-action/result/cancel closeout; TaskComplete unverified | Owner-only MCP cache | Non-overwriting executable hooks and durable spool | Client-self-reported lifecycle evidence | Enable Hooks, executable/workspace trust, and restart required |
|
|
488
|
-
| Windsurf |
|
|
353
|
+
| Windsurf | Native pre-action, success-result and response-closeout hooks plus MCP on demand | Native pre-action/result/closeout; explicit proof | Owner-only MCP cache | Hook/MCP config and durable spool | Client-self-reported lifecycle evidence | Restart, workspace trust review and Restricted Mode off required |
|
|
489
354
|
| Codex, Gemini, Grok | Native hooks plus MCP on demand | Native pre-action/result/turn closeout; Grok Stop never blocks or retries | Owner-only MCP cache | Hook/MCP config and durable spool | Client-self-reported lifecycle evidence | Restart and host hook review required |
|
|
490
355
|
| OpenCode, DeepSeek, Qwen, Kimi, MiniMax, GLM | Automatic only inside governed runner | Automatic when result is known; proof is evaluated and is advisory or enforced according to plan policy | Runner/runtime cache | Activated controller and durable buffer | Command, test, deployment, or owner evidence | Managed config after activation |
|
|
491
356
|
| Hermes | MCP tools on demand after install or update adds `mcp_servers.marrow` to its config; no native pre-action hook | Explicit `marrow_commit`, or the governed runner for CLI commands | Owner-only MCP cache | Hermes config and durable spool | MCP lifecycle evidence | Install or update only; the controller does not edit the Hermes config |
|
|
@@ -505,7 +370,7 @@ Owners can inspect pending outcomes in Fleet Operations and recent intervention
|
|
|
505
370
|
|
|
506
371
|
When the installer writes `.marrow/passive-runtime.mjs` and the harness exposes usage metadata, Marrow can capture compact provider/model, token, latency, and optional cost counts. It does not require raw prompts, completions, command output, tool output, or plaintext secrets.
|
|
507
372
|
|
|
508
|
-
After meaningful work, supported runtime and commit responses can return observed usage, trend direction, evidence confidence, and the next capture improvement. Savings are only reported when the available evidence supports them.
|
|
373
|
+
After meaningful work, supported runtime and commit responses can return observed usage, trend direction, evidence confidence, and the next capture improvement. Savings are only reported when the available evidence supports them. Only observed usage with sufficient host, model, token and pricing evidence becomes calculated cost; unobservable host usage stays incomplete, and no baseline or net savings is invented. Empty token savings stay zero until observed model usage lands.
|
|
509
374
|
|
|
510
375
|
## Trust and Data Boundaries
|
|
511
376
|
|
|
@@ -524,14 +389,33 @@ See the [Trust Center](https://getmarrow.ai/trust/) for implemented controls, cu
|
|
|
524
389
|
|
|
525
390
|
| Variable | Required | Purpose |
|
|
526
391
|
| --- | --- | --- |
|
|
527
|
-
| `MARROW_API_KEY` | Yes for live verification | Account or agent-bound API key |
|
|
392
|
+
| `MARROW_API_KEY` | Yes for live verification | Account or agent-bound API key. `MARROW_KEY` is accepted by the runner and controller |
|
|
528
393
|
| `MARROW_BASE_URL` | No | API base override |
|
|
529
394
|
| `MARROW_FLEET_AGENT_ID`, `MARROW_AGENT_ID` | No | A registered agent id. Unset, Marrow uses the key's bound agent or the plan seat |
|
|
530
395
|
| `MARROW_CLIENT` | No | Harness label; overrides detection |
|
|
396
|
+
| `MARROW_TOOL_PROFILE` | No | `primary` (default when unset), `core` or `full` |
|
|
397
|
+
| `MARROW_GOVERN_PROFILE`, `MARROW_GOVERN_POLICY` | No | Runner defaults for `--profile` and `--policy` (`enforce`, `warn` or `audit`) |
|
|
398
|
+
| `MARROW_ACTION_PERMIT`, `MARROW_ACTION_TARGET` | No | Permit and target for `verify-permit` and runner calls (the target is redacted before it is sent) |
|
|
399
|
+
| `MARROW_LOCAL_RUNTIME` | No | `0` keeps hooks on `npx`, like `--no-local-runtime` |
|
|
400
|
+
| `MARROW_SESSION_ID`, `MARROW_SIDECAR_PORT` | No | Runner session id (by default one per agent, project, user, service and UTC day) and sidecar port |
|
|
531
401
|
| `HERMES_HOME` | No | Hermes home, when not `~/.hermes` |
|
|
532
402
|
| `MARROW_ALLOWED_BASE_URLS`, `MARROW_ALLOWED_AGENT_IDS` | No | Comma-separated values that install, update and controller maintenance keep in managed MCP configuration instead of resetting them |
|
|
533
403
|
|
|
534
|
-
The installer never
|
|
404
|
+
The installer never sends or writes a generated agent id to Marrow, MCP configuration or the SDK preload; the controller keeps a local identity for its own state only. Only a configured id (`MARROW_FLEET_AGENT_ID`, `MARROW_AGENT_ID` or `--agent-id`) goes into the managed MCP entry and SDK preload; without one, Marrow resolves the API key's bound agent or the plan's agent seat, and the self-test reports that server-resolved id. The generated passive runtime reads `MARROW_FLEET_AGENT_ID`, then `MARROW_AGENT_ID`, and uses the installer-captured id only as a fallback. A key bound to no single agent still passes the self-test; activation then reports how to bind one. The installer never copies `MARROW_API_KEY` into MCP configuration or generated runtime source; the owning harness must inherit the key from trusted environment or secret-manager configuration, or from the owner-only `~/.marrow/env`.
|
|
405
|
+
|
|
406
|
+
## Files
|
|
407
|
+
|
|
408
|
+
| Path | Purpose |
|
|
409
|
+
| --- | --- |
|
|
410
|
+
| `.mcp.json`, `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/marrow.mdc` | MCP entry and Marrow instruction block (`<!-- marrow:passive-start -->`) |
|
|
411
|
+
| Hook files listed under Native Hooks | Marrow-owned hook entries |
|
|
412
|
+
| `.marrow/passive-runtime.mjs`, `.marrow/env.example` | SDK passive runtime and an env template (no key) |
|
|
413
|
+
| `~/.marrow/env`, `~/.marrow/env.local` | Owner-only key files; the installer writes `~/.marrow/env` only on a first install after a passing self-test and for Hermes, as described above |
|
|
414
|
+
| `~/.marrow/runtime/mcp/<version>/` | The verified local MCP runtime the hooks start (directories 700) |
|
|
415
|
+
| `~/.marrow/runner-holds/` | The runner's hold records: ids, states and times under a keyed hash of the command, never the command text (owner-only) |
|
|
416
|
+
| `~/.marrow/logs/` | Install, `activate` and `update` reports (directory 700, files 600) |
|
|
417
|
+
| `~/.marrow/controllers/` | Private controller state, owner-only, no credential |
|
|
418
|
+
| `~/.marrow/control-bypass-receipts.json` | Local record of governed-run bypasses while local control is disabled |
|
|
535
419
|
|
|
536
420
|
Use the host's secret manager first. The shared resolver can also check documented Marrow and project env files for owned development environments. Run `doctor` when a key or hook cannot be found.
|
|
537
421
|
|