@getmarrow/mcp 3.9.101 → 3.9.103
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 +63 -29
- package/dist/cli.js +64 -1005
- package/dist/cli.js.map +1 -1
- package/dist/codex-plugin-pins.d.ts +19 -0
- package/dist/codex-plugin-pins.d.ts.map +1 -0
- package/dist/codex-plugin-pins.js +43 -0
- package/dist/codex-plugin-pins.js.map +1 -0
- package/dist/codex-plugins.d.ts +34 -0
- package/dist/codex-plugins.d.ts.map +1 -0
- package/dist/codex-plugins.js +240 -0
- package/dist/codex-plugins.js.map +1 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +229 -39
- package/dist/env.js.map +1 -1
- package/dist/hook-contract.d.ts +41 -3
- package/dist/hook-contract.d.ts.map +1 -1
- package/dist/hook-contract.js +126 -18
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +48 -2
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +199 -23
- package/dist/hook-pre-action.js.map +1 -1
- package/dist/hook-tool-policy.d.ts +3 -3
- package/dist/hook-tool-policy.d.ts.map +1 -1
- package/dist/hook-tool-policy.js +6 -22
- package/dist/hook-tool-policy.js.map +1 -1
- package/dist/hook.d.ts +2 -2
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +13 -6
- package/dist/hook.js.map +1 -1
- package/dist/host-approval-state.d.ts +9 -0
- package/dist/host-approval-state.d.ts.map +1 -1
- package/dist/host-approval-state.js +4 -0
- package/dist/host-approval-state.js.map +1 -1
- package/dist/host-approval.d.ts +6 -0
- package/dist/host-approval.d.ts.map +1 -1
- package/dist/host-approval.js +3 -1
- package/dist/host-approval.js.map +1 -1
- package/dist/host-session.d.ts +11 -0
- package/dist/host-session.d.ts.map +1 -1
- package/dist/host-session.js +49 -0
- package/dist/host-session.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -19
- package/dist/index.js.map +1 -1
- package/dist/normalized-action.d.ts +29 -6
- package/dist/normalized-action.d.ts.map +1 -1
- package/dist/normalized-action.js +497 -103
- package/dist/normalized-action.js.map +1 -1
- package/dist/own-server-identity.d.ts +123 -0
- package/dist/own-server-identity.d.ts.map +1 -0
- package/dist/own-server-identity.js +1052 -0
- package/dist/own-server-identity.js.map +1 -0
- package/dist/own-tool.d.ts +87 -0
- package/dist/own-tool.d.ts.map +1 -0
- package/dist/own-tool.js +169 -0
- package/dist/own-tool.js.map +1 -0
- package/dist/redact.d.ts +23 -0
- package/dist/redact.d.ts.map +1 -1
- package/dist/redact.js +181 -8
- package/dist/redact.js.map +1 -1
- package/dist/seatbelt/classifier-pin.d.ts +15 -0
- package/dist/seatbelt/classifier-pin.d.ts.map +1 -0
- package/dist/seatbelt/classifier-pin.js +26 -0
- package/dist/seatbelt/classifier-pin.js.map +1 -0
- package/dist/seatbelt/guards.d.ts +10 -0
- package/dist/seatbelt/guards.d.ts.map +1 -0
- package/dist/seatbelt/guards.js +509 -0
- package/dist/seatbelt/guards.js.map +1 -0
- package/dist/seatbelt/hook.d.ts +72 -0
- package/dist/seatbelt/hook.d.ts.map +1 -0
- package/dist/seatbelt/hook.js +362 -0
- package/dist/seatbelt/hook.js.map +1 -0
- package/dist/seatbelt/longopts.d.ts +68 -0
- package/dist/seatbelt/longopts.d.ts.map +1 -0
- package/dist/seatbelt/longopts.js +377 -0
- package/dist/seatbelt/longopts.js.map +1 -0
- package/dist/seatbelt/mapper.d.ts +83 -0
- package/dist/seatbelt/mapper.d.ts.map +1 -0
- package/dist/seatbelt/mapper.js +10248 -0
- package/dist/seatbelt/mapper.js.map +1 -0
- package/dist/seatbelt/record.d.ts +94 -0
- package/dist/seatbelt/record.d.ts.map +1 -0
- package/dist/seatbelt/record.js +776 -0
- package/dist/seatbelt/record.js.map +1 -0
- package/dist/seatbelt/tables.d.ts +82 -0
- package/dist/seatbelt/tables.d.ts.map +1 -0
- package/dist/seatbelt/tables.js +359 -0
- package/dist/seatbelt/tables.js.map +1 -0
- package/dist/seatbelt-deploy.d.ts +100 -0
- package/dist/seatbelt-deploy.d.ts.map +1 -0
- package/dist/seatbelt-deploy.js +393 -0
- package/dist/seatbelt-deploy.js.map +1 -0
- package/dist/seatbelt-fs.d.ts +30 -0
- package/dist/seatbelt-fs.d.ts.map +1 -0
- package/dist/seatbelt-fs.js +94 -0
- package/dist/seatbelt-fs.js.map +1 -0
- package/dist/seatbelt-git.d.ts +212 -0
- package/dist/seatbelt-git.d.ts.map +1 -0
- package/dist/seatbelt-git.js +844 -0
- package/dist/seatbelt-git.js.map +1 -0
- package/dist/seatbelt-mode.d.ts +77 -0
- package/dist/seatbelt-mode.d.ts.map +1 -0
- package/dist/seatbelt-mode.js +496 -0
- package/dist/seatbelt-mode.js.map +1 -0
- package/dist/seatbelt-path.d.ts +123 -0
- package/dist/seatbelt-path.d.ts.map +1 -0
- package/dist/seatbelt-path.js +482 -0
- package/dist/seatbelt-path.js.map +1 -0
- package/dist/seatbelt-scripts.d.ts +109 -0
- package/dist/seatbelt-scripts.d.ts.map +1 -0
- package/dist/seatbelt-scripts.js +1060 -0
- package/dist/seatbelt-scripts.js.map +1 -0
- package/dist/tool-catalog.d.ts +6852 -0
- package/dist/tool-catalog.d.ts.map +1 -0
- package/dist/tool-catalog.js +999 -0
- package/dist/tool-catalog.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/server.json +10 -3
- package/vendor/classifier/MANIFEST.json +25 -0
- package/vendor/classifier/classifier.js +1356 -0
- package/vendor/classifier/policy-baseline.js +187 -0
- package/vendor/classifier/redact.js +59 -0
- package/vendor/classifier/shell-parse.js +455 -0
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Use `@getmarrow/mcp` when your agent client supports the Model Context Protocol
|
|
|
27
27
|
npx -y @getmarrow/install@latest doctor --self-test
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
**What is enforced.** On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks let actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host and are not an external execution boundary: an agent or person who edits the host settings, or works outside the host, is not held.
|
|
30
|
+
**What is enforced.** On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks hold high-risk actions and let routine actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host and are not an external execution boundary: an agent or person who edits the host settings, or works outside the host, is not held.
|
|
31
31
|
|
|
32
32
|
## Agent Discovery
|
|
33
33
|
|
|
@@ -36,9 +36,7 @@ Use `@getmarrow/mcp` when your agent client supports the Model Context Protocol
|
|
|
36
36
|
- **Product category:** agent fleet governance and control layer.
|
|
37
37
|
- **Operator boundary:** configuring the server, creating an account, or submitting a diagnostic requires operator approval.
|
|
38
38
|
- **Public diagnostic privacy:** raw prompts, source code, credentials, customer data, and free-form work descriptions are not accepted.
|
|
39
|
-
- **
|
|
40
|
-
- **npm retrieval:** https://api.getmarrow.ai/v1/public/discovery/placements/plc_bdf1abadff99a79182556248
|
|
41
|
-
- **MCP registry retrieval:** https://api.getmarrow.ai/v1/public/discovery/placements/plc_d3e06cb7675296dfd0c1021e
|
|
39
|
+
- **Machine-readable product facts:** https://getmarrow.ai/llms.txt and https://getmarrow.ai/.well-known/marrow.json
|
|
42
40
|
|
|
43
41
|
Maintainers can validate local registry metadata with `npm run registry:check`. After an approved registry publication, `npm run registry:verify` confirms that the official registry returns the exact package name and version; package metadata alone is not treated as publication proof.
|
|
44
42
|
|
|
@@ -54,26 +52,26 @@ Public operating guides:
|
|
|
54
52
|
|
|
55
53
|
The assessment accepts bounded selections only. It does not install Marrow, authorize a purchase, accept free-form work content, or establish compliance, security, or ROI.
|
|
56
54
|
|
|
57
|
-
##
|
|
55
|
+
## Where Marrow fits
|
|
58
56
|
|
|
59
57
|
Marrow AI is the optional **agent fleet governance and control layer** around existing models, harnesses, and business workflows. It is not a model provider, agent harness, memory-only tool, or observability replacement.
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
Marrow fits when one or more of these is true:
|
|
62
60
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
61
|
+
- Two or more autonomous agents, models, or harnesses contribute to one accountable workflow (`multiple_autonomous_agents`).
|
|
62
|
+
- Agents can deploy, merge, publish, change production data, use privileged tools, spend money, or message customers (`production_or_privileged_access`).
|
|
63
|
+
- The workflow has repeated failures, retries, regressions, or known lessons that should affect the next action (`repeated_workflow_failures`).
|
|
64
|
+
- Work can be marked complete without proof, verification, or a recorded business outcome (`missing_completion_evidence`).
|
|
65
|
+
- Policy, approval, or completion requirements vary across agents, tools, environments, or teams (`inconsistent_policy_enforcement`).
|
|
66
|
+
- Agents operate around regulated, proprietary, personal, financial, health, legal, credential, or otherwise sensitive workflows (`regulated_or_sensitive_work`).
|
|
69
67
|
|
|
70
|
-
|
|
68
|
+
## Where Marrow is not a fit
|
|
71
69
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
70
|
+
- One advisory assistant performs no shared, privileged, production, or accountable business action (`single_low_risk_assistant`).
|
|
71
|
+
- The workflow has no need for policy, proof, outcome accountability, or fleet coordination (`no_governance_requirement`).
|
|
72
|
+
- The operator has declined Marrow evaluation or installation (`operator_declined_evaluation`).
|
|
75
73
|
|
|
76
|
-
|
|
74
|
+
Installing Marrow changes the operator's agent configuration: never install, create an account, or submit data without operator approval.
|
|
77
75
|
|
|
78
76
|
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).
|
|
79
77
|
|
|
@@ -97,7 +95,7 @@ Hooks-only setup (`marrow-mcp setup` writes hooks and `CLAUDE.md` instructions,
|
|
|
97
95
|
npx -y --package=@getmarrow/mcp@latest marrow-mcp setup
|
|
98
96
|
```
|
|
99
97
|
|
|
100
|
-
|
|
98
|
+
The MCP server and Claude Code's cooperative pre-action hook read the key only from the process environment or an owner-controlled `~/.marrow/env` (or `~/.marrow/env.local`) with owner-only permissions (`chmod 600`). An owner file that is a symlink, readable or writable by others, owned by another user, or in a directory others can write supplies nothing, key included; the missing-key message names it with the `chmod` fix. Repository-local files (`.env`, `.env.local`, `.marrow/env*` in the working directory or its parents) are never read for `MARROW_API_KEY` or any other `MARROW_*` setting, whatever their permissions, so project content cannot replace the account, agent, or API endpoint. If one holds a key, the missing-key message names that file and the fix: run `npx @getmarrow/install doctor`, or move the line to `~/.marrow/env`, then `chmod 600 ~/.marrow/env`. The public hook callback is still a client self-report, not certified host provenance or an external enforcement boundary.
|
|
101
99
|
|
|
102
100
|
Then configure the MCP server:
|
|
103
101
|
|
|
@@ -155,25 +153,59 @@ A direct `marrow_think` can receive a durable pending response before the backen
|
|
|
155
153
|
|
|
156
154
|
A saved `observed_unverified` outcome is terminal observation evidence, not a committed outcome. Receipt expiry cannot retroactively authorize completed work. Preserve the original decision, receipt, proof and key; an already authorized durable checkpoint may finish through its existing exact recovery path. Do not repeat the action merely to obtain a fresh receipt.
|
|
157
155
|
|
|
156
|
+
## Keyless seatbelt
|
|
157
|
+
|
|
158
|
+
When a pre-action hook has no usable Marrow key and the machine shows no sign of a Marrow account (for example an owner key file, a claim marker or Marrow's local approval state), the hook runs a local seatbelt instead of holding every protected action:
|
|
159
|
+
|
|
160
|
+
- **It stops seven kinds of action:** a change to Marrow's hooks, settings or plugins (including the Marrow plugin switch in Claude Code settings and the plugin files under `~/.claude/plugins`) or an owner-only Marrow command (S0), a force-push or delete of a protected branch (S1), a production deploy (S2), a package publish (S3), reading credentials or secrets, including a project `.env` file other than a template (S4), a recursive delete outside the workspace (S5), and decoded data run by a shell or interpreter (S-x). A protected file named to any program that is not a plain reader (such as `cat`, `grep`, `jq` or `diff`) stops too, so an editor or a tool the seatbelt does not know cannot rewrite it. A tool counts as a plain reader only with the long options it lists, spelled in full: GNU tools and git also accept a shortened spelling (`cp --target=DIR`, `git reset --har`), so a shortened or unknown long option on a command that names a protected file stops. Archiving (`tar -c`, `zip`), `tree` and `prettier --check` only read what they are given: only the archive and the files they write are checked. The stop is the host's own deny, with text that tells the agent to leave the action to the machine owner. On Grok the stop is Grok's fixed denial ("Marrow blocked this protected action."), the only denial its installed guard passes.
|
|
161
|
+
- **Everything else gets no Marrow decision, so the host's own approval step decides:** Claude Code and Codex get an empty answer, Cline is not cancelled and Windsurf gets no output. Gemini CLI gets `{"decision":"allow"}`, the only answer its installed guard passes without blocking. Cursor asks with its own approval prompt before a shell command that a hook without a key used to hold. Cursor's other tools (MCP calls included) and Grok have no neutral answer, so they keep holding what a hook without a key held before. An action that a hook without a key already let through gets the same answer as before.
|
|
162
|
+
- **Host tools and MCP calls:** the seatbelt reads each host's own file tools (for example Cline `write_to_file` and `replace_in_file`, Gemini CLI `read_file`, `replace` and `delete_file`, Grok `search_replace`, Cursor `Delete`) and MCP calls in every host form (`mcp__server__tool`, `MCP:server:tool`, Gemini `mcp_server_tool` and `server__tool`, Cline `use_mcp_tool` and `access_mcp_resource`). Every string value in an MCP call's arguments, at any depth, gets the S0 and S4 path checks. A tool it does not recognise, or MCP arguments it cannot read, never gets the seatbelt's pass: the hook gives the answer a hook without a key gave before, a hold where that held.
|
|
163
|
+
- **It fails closed:** an internal error, a check that runs past 300 ms, or input the host cut short stops the action. Windsurf and Cline do not tell the hook the working folder, so there a recursive delete outside the temporary folders stops.
|
|
164
|
+
- **Local receipts:** each seatbelt decision is written to `~/.marrow/seatbelt/receipts/` on this machine, as codes and keyed hashes, plus the built-in tool name and shell program names from fixed lists (any MCP tool is recorded only as `mcp`); no command text, argument, path or URL. Receipts are kept for up to 90 days or 50 MB. Nothing is uploaded. Where the seatbelt enforces (no working key), an agent cannot edit the receipts or read the device salt that keys them (S0, S4); with a working key the seatbelt only watches. Receipts are a record, not an authority.
|
|
165
|
+
- **Folder permissions:** the seatbelt runs only where your home folder and the agent settings folders (such as `~/.claude`) can be written by you alone. On Linux, a folder that your own private group can also write (the default with umask 002, mode 0775) still counts. A folder others can write, a group with other members, a folder reached through a symlink, or users and groups from a network directory (LDAP, SSSD) keep every hold, and the hold says "Marrow has no working key on this machine and its keyless mode is off here (strict mode, or a home folder it cannot trust); owner: run `npx -y @getmarrow/install@latest doctor`."
|
|
166
|
+
- **It is a seatbelt, not a vault:** it runs on the machine as your user and makes no network call. A determined agent can get around a local check, for example with a script it writes now and runs later, an interpreter, or a tool path with no hook.
|
|
167
|
+
- **With an account:** a machine linked to an account but with no working key keeps every hold it had, and these stops apply too. With a working key nothing changes; the seatbelt only checks the action after Marrow has answered, without changing the answer.
|
|
168
|
+
|
|
169
|
+
`marrow-mcp setup` and the installer both need a key; hooks without a key come from the Marrow plugins for Claude Code, Codex and Cursor.
|
|
170
|
+
|
|
158
171
|
## Hook behavior details
|
|
159
172
|
|
|
160
173
|
These behaviors shipped in 3.9.100 and still apply.
|
|
161
174
|
|
|
162
175
|
- **One Marrow entry per hook event:** `marrow-mcp setup` recognizes the installer's local-runtime hook commands exactly (same version throughout, no additions), keeps whichever form is there (local runtime or npx), and never adds a second entry. Your own hooks stay as they are.
|
|
163
|
-
- **Plain words without a key:** a protected action with no
|
|
176
|
+
- **Plain words without a key:** on a machine linked to a Marrow account, a protected action with no working key is denied with "Marrow is linked to an account but has no working key; owner: run `npx -y @getmarrow/install@latest doctor`." A machine with no account runs the [keyless seatbelt](#keyless-seatbelt). The hooks read the key from `MARROW_API_KEY` or an owner-only `~/.marrow/env.local` or `~/.marrow/env`, never from a file others can read.
|
|
164
177
|
- **First-prompt briefs say so:** the prompt hook marks its brief `context.prompt_brief: true`; a brief authorizes nothing.
|
|
165
178
|
- **Deploy text only word for word:** the exact command text is sent only for `sst deploy --stage <stage>` (optionally `--verbose`, optionally after one `npx` or `bunx`), with a stage of lower-case letters, digits and dashes, in a single clause with nothing else in it, so Marrow can judge the stage itself. Every other command, including other deploy tools, sends only the hash; no free-text word leaves the machine.
|
|
166
179
|
- **No lifecycle event id with two payloads:** an event id names its payload, so a later run is a new record and a resend carries the same bytes.
|
|
167
180
|
|
|
168
|
-
##
|
|
181
|
+
## Setup and key handling
|
|
182
|
+
|
|
183
|
+
These behaviors shipped in 3.9.101 and still apply.
|
|
184
|
+
|
|
185
|
+
- **Setup with no key stops:** `marrow-mcp setup` with no key, or with a key only in an untrusted place such as a project `.env`, stops, writes nothing and tells you how to get a key.
|
|
186
|
+
- **Keys are read from trusted places only:** the key comes from the environment or an owner-only `~/.marrow/env`.
|
|
187
|
+
- **Key-file steps include `chmod 700 ~/.marrow`** before `chmod 600 ~/.marrow/env`.
|
|
188
|
+
- **Hold messages say where to approve:** a held action says how to approve it where your host really asks.
|
|
189
|
+
- **One enforcement sentence:** the "what is enforced" wording matches the public site.
|
|
190
|
+
|
|
191
|
+
## Project files and Marrow's own tools
|
|
192
|
+
|
|
193
|
+
These behaviors shipped in 3.9.102 and still apply.
|
|
194
|
+
|
|
195
|
+
- **A cloned project's `.env` cannot redirect the MCP server:** repository-local `.env`, `.env.local` and `.marrow/env*` files are never read for `MARROW_API_KEY` or any other `MARROW_*` setting, so project content cannot point the server at another account, agent or API endpoint.
|
|
196
|
+
- **Safer key-file advice:** an owner file that is a symlink, readable or writable by others, owned by another user, or in a directory others can write supplies nothing, and the missing-key message names the file with the `chmod` fix.
|
|
197
|
+
- **Only Marrow's own tools skip the gate, by exact name:** a tool is Marrow's own only when its server is exactly `marrow` and its tool name is exactly one this package registers. Look-alike servers, other cases, extra spaces or suffixes go through the pre-action gate like any other MCP tool. Re-run `marrow-mcp setup` to refresh hooks written with the old matcher.
|
|
198
|
+
|
|
199
|
+
## What's New in v3.9.103
|
|
169
200
|
|
|
170
|
-
- **
|
|
171
|
-
- **
|
|
172
|
-
- **
|
|
173
|
-
- **
|
|
174
|
-
- **
|
|
201
|
+
- **Keyless seatbelt:** a hook with no key, on a machine with no sign of a Marrow account, stops seven kinds of action (Marrow's own settings, force-push or delete of a protected branch, production deploy, package publish, reading credentials, recursive delete outside the workspace, decoded data run by a shell) in shell commands, each host's own file tools and MCP calls, and leaves everything else to the host's own approval step. A tool it does not recognise keeps the answer a hook without a key gave before. Machines linked to an account keep every hold they had. A Linux home or agent settings folder that only your own private group can also write (umask 002) keeps the seatbelt. See [Keyless seatbelt](#keyless-seatbelt). Marrow's own plugins and the Marrow plugin switch are protected like its settings.
|
|
202
|
+
- **High-risk actions wait while Marrow is down:** with a key, if Marrow cannot be reached, a git push, publish, deploy, API delete, seatbelt-category command or other high-risk tool (for example an MCP tool) is held on every host until Marrow is back; words in a commit message or a path never hold a command, and routine actions keep running with a warning. If Marrow answers but cannot issue a permit, a high-risk action is denied and never allowed as offline.
|
|
203
|
+
- **Local receipts:** each seatbelt decision is written on this machine as codes and keyed hashes, plus the built-in tool name and shell program names from fixed lists (any MCP tool is recorded only as `mcp`); no command text, argument, path or URL. Kept for up to 90 days or 50 MB. Nothing is uploaded.
|
|
204
|
+
- **Approvals bind to the exact action:** an owner approval resumes only the exact action that was held. A held action whose sent form hides a value also carries `exact_hmac`, a keyed hash made with this machine's private device key (never sent); a retry that differs only in a certain credential, such as a new one-time password, still resumes. The action hash version is now v3: learned approvals and known workflows from earlier versions ask once more, then are learned again. See [Approvals in the Host Prompt](#approvals-in-the-host-prompt).
|
|
205
|
+
- **Hidden commands are checked:** commands inside an unquoted here-document body, a `${x:-$(...)}` default or an arithmetic expansion are checked like any other command.
|
|
206
|
+
- **`marrow-mcp keys create` reads every flag form:** `--name=`, `--type=` and `--expires=` (and `-n=`, `-t=`) are read like `--name value`; a flag that is present but blank, or a `--scopes` / `--agents` list with no entry, is a usage error (exit 2) and nothing is sent; leaving `--scopes` and `--agents` out sends neither.
|
|
175
207
|
|
|
176
|
-
|
|
208
|
+
Earlier behaviors are kept under [Project files and Marrow's own tools](#project-files-and-marrows-own-tools), [Setup and key handling](#setup-and-key-handling) and [Hook behavior details](#hook-behavior-details). v3.9.99 brought approvals in the host prompt; see [Approvals in the Host Prompt](#approvals-in-the-host-prompt).
|
|
177
209
|
|
|
178
210
|
Earlier release notes moved from this README to [CHANGELOG.md](https://github.com/getmarrow/marrow-mcp/blob/master/CHANGELOG.md).
|
|
179
211
|
|
|
@@ -191,7 +223,7 @@ Direct `marrow_model_usage` and Commit `model_usage` also accept billing host, t
|
|
|
191
223
|
|
|
192
224
|
With `MARROW_TOOL_PROFILE` unset, the default primary profile uses `marrow_agent_runtime` followed by `marrow_commit`. It exposes 17 tools; `marrow_auto` is available only after an explicit `core` or `full` selection and MCP restart. Primary status and lessons use `marrow_agent_status` and `marrow_fleet_lessons`.
|
|
193
225
|
|
|
194
|
-
On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks let actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host, so a host edited or bypassed by an agent or person is not held. Before deploys, merges, publishes, migrations, credential changes, financial operations, or customer-impacting work:
|
|
226
|
+
On the 30-day evaluation and Business, deploys and publishes are held in hooks and the governed runner. Team and Free warn. If Marrow is unreachable, hooks hold high-risk actions and let routine actions run with a warning, and the governed runner stops protected actions it cannot verify. Over MCP, the agent gets the decision and is expected to follow it. Hooks run inside the agent host, so a host edited or bypassed by an agent or person is not held. Before deploys, merges, publishes, migrations, credential changes, financial operations, or customer-impacting work:
|
|
195
227
|
|
|
196
228
|
1. Call `marrow_agent_runtime` or `marrow_decision_brief`.
|
|
197
229
|
2. Stop when the returned decision is `block` or `review_required`; otherwise follow its prior lesson and proof contract.
|
|
@@ -325,8 +357,10 @@ When Marrow holds an action for approval (`review_required`), the person approve
|
|
|
325
357
|
- **Codex with its approval prompt off holds quietly** (`--yolo`, `-a never`, `--full-auto`, `--approve-for-me`, `-s danger-full-access`, the same through `-c` or `$CODEX_HOME` config). Not read: Codex settings from managed or project configs. Not detected: Cline's auto-approve and Windsurf's Turbo mode (they live in editor state with no reliable signal). With those on, the host runs the action without asking; Marrow records it as not observed by Marrow, never as the person's answer. Owner-locked categories still hold.
|
|
326
358
|
- **Held actions at the next session.** At the first prompt of an interactive session the person sees "N held actions are waiting for you", with the action type and agent only, and approves one by retrying it there.
|
|
327
359
|
- **One approval, one run.** Of two identical calls on one approval, one runs and the other is denied.
|
|
328
|
-
- **The exact action, never its text.** Hook-classified calls send `normalized_action`: the tool kind and name, program names (and edit paths, with the home directory as `~`) and a SHA-256 of a normalized form. Event and correlation ids come from that normalized form, never from the raw command, input or prompt. Credentials are replaced where they stood, data a command reads is hashed so `SELECT` and `DROP` are different actions, and anything else that may be secret is withheld. An action that carried a credential or a withheld value is marked `truncated: true`: Marrow never
|
|
329
|
-
- **
|
|
360
|
+
- **The exact action, never its text.** Hook-classified calls send `normalized_action`: the tool kind and name, program names (and edit paths, with the home directory as `~`) and a SHA-256 of a normalized form. Event and correlation ids come from that normalized form, never from the raw command, input or prompt. Credentials are replaced where they stood, data a command reads is hashed so `SELECT` and `DROP` are different actions, and anything else that may be secret is withheld. An action that carried a credential or a withheld value is marked `truncated: true`: Marrow never learns a reusable approval for it, and the answer to a held one resumes only that exact action (see How approvals bind). The verdict, the hold and the prompt are the same as without the mark. A credential value ends only at whitespace, a quote, or a separator followed by another `name=` field, so actions that differ after it stay different actions and no part of a password with `#`, `,`, `&` or `;` in it stays in the hashed form. A password given as a plain argument to an unknown program (`./deploy.sh hunter2`) cannot be recognized; it stays only inside the hash.
|
|
361
|
+
- **How approvals bind.** Marrow binds an owner approval to the exact action that was held. The client hides possible secrets before sending an action; when it hides anything, it adds `exact_hmac`, a keyed hash of the exact action made with this machine's private device key (`~/.marrow/seatbelt/salt`, created once, mode 0600, never sent). An approval resumes only for the same exact action; a retry that differs only in a certain credential (for example a new one-time password) still resumes. If the device key is missing or unsafe, Marrow prints one note (it points to the installer's `npx -y @getmarrow/install@latest doctor`) and asks again instead of resuming.
|
|
362
|
+
- **Upgrade note:** the action hash version changed (v3). Learned approvals and known workflows from earlier versions ask once more, then are learned again.
|
|
363
|
+
- **Slow and down are different.** Codex and the 5-second hosts answer within their hook limits (Codex within 2 s of starting, and on Linux about 2.6 s from launch when npx starts in under about 1.6 s). A slow Marrow keeps a holdable action held. A real outage (Marrow never answered) holds a shell command only when it pushes with git, publishes a package or image, deploys, deletes through an API or a cloud CLI, or hits a seatbelt category (S0-S5, S-x); words in a commit message, a path, echo text or a comment never hold it, and neither does asking a listed tool for its help (`git push --help`). Other high-risk tools (for example MCP tools) are held, routine actions keep running with a warning, and a waiting hold or owner-locked category stays held. When Marrow answers but cannot issue a permit, a high-risk action is denied, never allowed as offline.
|
|
330
364
|
- **Honest labels and texts.** Without a dialog or typed-reply marker an approval is recorded as the host's allow rule. Text a person reads names no receipt ids. A refused action names a plain fix.
|
|
331
365
|
|
|
332
366
|
## Passive Use
|