@getmarrow/mcp 3.9.97 → 3.9.99

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.
Files changed (52) hide show
  1. package/README.md +57 -338
  2. package/dist/cli.js +249 -47
  3. package/dist/cli.js.map +1 -1
  4. package/dist/hook-context.d.ts.map +1 -1
  5. package/dist/hook-context.js +135 -9
  6. package/dist/hook-context.js.map +1 -1
  7. package/dist/hook-contract.d.ts +26 -5
  8. package/dist/hook-contract.d.ts.map +1 -1
  9. package/dist/hook-contract.js +144 -10
  10. package/dist/hook-contract.js.map +1 -1
  11. package/dist/hook-pre-action.d.ts +40 -1
  12. package/dist/hook-pre-action.d.ts.map +1 -1
  13. package/dist/hook-pre-action.js +429 -35
  14. package/dist/hook-pre-action.js.map +1 -1
  15. package/dist/hook-session.d.ts.map +1 -1
  16. package/dist/hook-session.js +32 -0
  17. package/dist/hook-session.js.map +1 -1
  18. package/dist/hook.d.ts +12 -0
  19. package/dist/hook.d.ts.map +1 -1
  20. package/dist/hook.js +149 -5
  21. package/dist/hook.js.map +1 -1
  22. package/dist/host-approval-state.d.ts +137 -0
  23. package/dist/host-approval-state.d.ts.map +1 -0
  24. package/dist/host-approval-state.js +510 -0
  25. package/dist/host-approval-state.js.map +1 -0
  26. package/dist/host-approval.d.ts +436 -0
  27. package/dist/host-approval.d.ts.map +1 -0
  28. package/dist/host-approval.js +1417 -0
  29. package/dist/host-approval.js.map +1 -0
  30. package/dist/host-session.d.ts +82 -0
  31. package/dist/host-session.d.ts.map +1 -0
  32. package/dist/host-session.js +570 -0
  33. package/dist/host-session.js.map +1 -0
  34. package/dist/index.d.ts +150 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +748 -33
  37. package/dist/index.js.map +1 -1
  38. package/dist/lifecycle-spool.d.ts.map +1 -1
  39. package/dist/lifecycle-spool.js +6 -5
  40. package/dist/lifecycle-spool.js.map +1 -1
  41. package/dist/normalized-action.d.ts +120 -0
  42. package/dist/normalized-action.d.ts.map +1 -0
  43. package/dist/normalized-action.js +1109 -0
  44. package/dist/normalized-action.js.map +1 -0
  45. package/dist/runtime-contract.d.ts +108 -4
  46. package/dist/runtime-contract.d.ts.map +1 -1
  47. package/dist/runtime-contract.js +178 -35
  48. package/dist/runtime-contract.js.map +1 -1
  49. package/dist/types.d.ts +128 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +21 -25
  52. package/server.json +15 -4
package/README.md CHANGED
@@ -1,8 +1,12 @@
1
- # @getmarrow/mcp
1
+ # Marrow AI MCP Server
2
2
 
3
- > MCP-native runtime control, proof, and fleet intelligence for AI agents.
3
+ > `@getmarrow/mcp`: the control layer for AI agents. Marrow AI puts a named yes on an action before your agent acts, and leaves proof the next agent can reuse.
4
4
 
5
- Marrow is the runtime control and proof layer for teams running AI agents. It applies policy and prior lessons before consequential actions, then records the evidence and outcome afterward.
5
+ **Which Marrow?** This is Marrow AI from [getmarrow.ai](https://getmarrow.ai) (npm `@getmarrow/mcp`, MCP Registry `ai.getmarrow/marrow`). It is not affiliated with marrow.id, HyperMarrow, marrow.works or other projects named Marrow.
6
+
7
+ [getmarrow.ai](https://getmarrow.ai) · [Docs](https://getmarrow.ai/docs/) · [Marrow AI for MCP](https://getmarrow.ai/marrow-for-mcp) · [MCP Registry entry](https://registry.modelcontextprotocol.io/v0.1/servers/ai.getmarrow%2Fmarrow/versions/latest) · [Changelog](https://github.com/getmarrow/marrow-mcp/blob/master/CHANGELOG.md) · [![getmarrow/marrow-mcp MCP server](https://glama.ai/mcp/servers/getmarrow/marrow-mcp/badges/score.svg)](https://glama.ai/mcp/servers/getmarrow/marrow-mcp)
8
+
9
+ Marrow AI is the runtime control and proof layer for teams running AI agents. It applies policy and prior lessons before consequential actions, then records the evidence and outcome afterward.
6
10
 
7
11
  Use `@getmarrow/mcp` when your agent client supports the Model Context Protocol and you want Marrow available inside the agent's normal workflow. It works with Claude Code, Claude Desktop, Cursor and other MCP-compatible clients without replacing the model or harness.
8
12
 
@@ -130,29 +134,24 @@ A direct `marrow_think` can receive a durable pending response before the backen
130
134
 
131
135
  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.
132
136
 
133
- ### Previous release: v3.9.87
134
-
135
- v3.9.87 hardens the authenticated control-path canary against single-sample transport blips so monitoring stops flapping on a healthy service. The canary now retries transport-class delivery failures (`request_failed`, `service_unavailable`, `connection_reset`, `dns_unavailable`, `tls_failure`, `edge_access_denied`, `rate_limited`) in-run with the same idempotent operation before declaring a failure, gives the asynchronous `marrow_auto` and `marrow_first_value` calls a separate deadline ceiling (thirty seconds via `MARROW_MCP_CANARY_ASYNC_TOOL_TIMEOUT_MS`), and raises the default total canary budget to forty-five seconds so bounded retries fit. Results recovered by a retry are annotated with `recovered_on_retry: true`. Authentication, authorization, contract, and package-identity failures remain immediate hard failures with no retry. Tool surface, client contracts, and request deadlines are unchanged.
136
-
137
- v3.9.86 was published with the adapter version constant still at `3.9.85`, so the strict canary identity check rejected it; it is deprecated — use `3.9.87`. SDK `3.7.62` and installer `0.1.56` are unchanged; install MCP `3.9.87`, reload the host, review hook trust, and verify before claiming the updated client is active.
138
-
139
- ## What's New in v3.9.97
140
-
141
- v3.9.97 makes native hook control easier to live with. Free and starter gates are advisory again, so an advisory gate no longer hard-blocks work; a `block` decision still denies on every plan. In Claude Code's default, acceptEdits and auto permission modes, an enforced review now shows an owner-approval prompt instead of a denial. In plan, dontAsk and bypassPermissions modes, and for arbitration reviews, the action is still denied. Read-only commands such as `git show`, `git log` and `ls` no longer trigger false blocks, and denial messages now say plainly why an action was stopped and what to do next. The hook sends `protocol_version` when it verifies an action permit. When an action is denied, the hook makes a best-effort attempt, capped at 2.5 s, to close the decision with a denied outcome; if the backend does not confirm, the decision stays open. Hooks return faster because telemetry is delivered by a detached background process that honors opt-outs and never blocks the action (see `MARROW_HOOK_BACKGROUND_NUDGE` in Environment). Pending writes are retried more reliably: the client honors `retry_after_ms` and the optional `lease_remaining_ms`, and resumes the same write instead of starting a new one (see `MARROW_WRITE_RECONCILIATION_BUDGET_MS`). Hook lifecycle receipts are much less likely to be dropped when many hook processes write the spool at once: each event takes the spool lock fewer times, and the lock wait is a 10 s time budget with randomized polling. A receipt can still be lost if the lock is held for the full 10 s. Policy decisions, proof requirements and fail-closed behavior are unchanged, except that an enforced review now asks the owner (in the modes above) instead of denying. Update, reload the host and review hook trust before relying on the new hook.
142
-
143
- ### Previous release: v3.9.96
144
-
145
- v3.9.96 fixes native pre-action hooks that denied protected actions after the runtime gate allowed them. The hook sent `source_meta` fields that Think rejects, and without a risk level the runtime answered protected actions on its low-risk fast path, whose receipt cannot back an action permit. Protected actions now request a durable gate and create their decision with accepted metadata only; unprotected actions stop at the gate without creating a decision or permit. A rejected control call now names its HTTP status and failure code without echoing service text. Policy decisions, proof requirements and fail-closed behavior are unchanged. Update, reload the host and review hook trust before relying on the new hook.
137
+ ## What's New in v3.9.99
146
138
 
147
- ### Previous release: v3.9.95
139
+ v3.9.99 lets people approve held actions where they already work, and nobody has to log in. See [Approvals in the Host Prompt](#approvals-in-the-host-prompt).
148
140
 
149
- v3.9.95 fixes supplied model usage lost when native session hooks consumed stdin. It also captures the latest proven Codex model-call delta from bound token-usage events or a bounded transcript using the supported Codex `0.157.1` schema. Unknown versions, model/turn identity, unsafe paths, counter resets and unproven child bindings abstain. Billing dimensions remain unknown unless explicitly supplied. Capture is not proof of complete coverage, a comparable baseline, overhead or savings. Update and reload the owning host before claiming active capture.
141
+ These approvals turn on when the Marrow service update ships; until then held actions work as in 3.9.98: Claude Code asks in its dialog and other hosts hold for the account owner.
150
142
 
151
- ### Previous release: v3.9.94
143
+ - **Approvals in the host prompt:** one click in the host's own permission prompt, a short typed reply where a host has no dialog, or no ask at all for routine work. `marrow-mcp setup` adds Claude Code's `PermissionRequest` and `PostToolBatch` hooks.
144
+ - **Quiet holds:** unattended runs, and hosts that cannot ask, hold the action without emailing anyone; the person sees the waiting actions at their next interactive session.
145
+ - **The exact action, never its text:** `normalized_action` binds an approval to the exact command; only program names and a SHA-256 of a normalized, secret-free form leave the machine.
146
+ - **Slow is not down:** a slow Marrow keeps holdable actions held, within each host's hook time limit.
147
+ - **`marrow_auto`** waits on the approval status and resumes on the same gate receipt. New `request_owner_link` parameter.
148
+ - **Plain fixes:** a refused protected action names what to do next, and a `marrow_commit` retry that conflicts with the stored outcome lists the proof that is still missing.
149
+ - **New registry name:** the MCP Registry name moves from `io.github.getmarrow/marrow` to `ai.getmarrow/marrow`, with a title, website and icon. The npm package name `@getmarrow/mcp` and its commands are unchanged, so existing `npx` configurations keep working.
150
+ - On a service without host approvals, Claude Code asks in its dialog as 3.9.98 did. SDK `3.7.65`.
152
151
 
153
- v3.9.94 preserves compact model-cost evidence through native capture, direct usage submission and Commit. It captures OpenAI Chat/Responses cache subsets and Anthropic cache reads/writes with their actual token semantics and stable provider response identity. Published 3.9.93 strips these fields, so this correction requires updating MCP and reloading the host. It does not change authentication, plans, or claim baseline savings.
152
+ Earlier release notes moved from this README to [CHANGELOG.md](https://github.com/getmarrow/marrow-mcp/blob/master/CHANGELOG.md).
154
153
 
155
- ### Observed usage and calculated cost
154
+ ## Observed usage and calculated cost
156
155
 
157
156
  Session-hook commands retain observed usage supplied on stdin for capture. Session totals remain cumulative and unpriced without a proven delta; this does not add transcript collection or manufacture missing model usage.
158
157
 
@@ -162,315 +161,6 @@ A connector tool call does not automatically expose the upstream chat model's us
162
161
 
163
162
  Direct `marrow_model_usage` and Commit `model_usage` also accept billing host, token semantics, cache writes, response/event identity, occurrence time, pricing dimensions and explicit coverage/comparison metadata. Invalid supplied values fail validation; absent counts do not become observed zero. Stable IDs retain retry identity. Session totals and partial stream-start observations remain cumulative and unpriced without a proven delta. This hook does not assemble SSE streams or read transcripts. If cost is unavailable, inspect the returned reason and coverage: missing host/model/counts/variant evidence cannot be recovered from a successful tool call. No capture infers complete coverage, overhead or a causal baseline; baseline and net savings stay pending until those are proven.
164
163
 
165
- ### Previous release: v3.9.93
166
-
167
- v3.9.93 fixes the full eleven-tool canary's Auto operation identifiers. The canary now uses Auto's canonical UUID namespace, so valid numeric UUIDs reach Think and Commit instead of failing locally before a request. Privacy validation, authentication, proof requirements, deadlines, and retries are unchanged. Published 3.9.92 cannot provide this harness correction; update and reload the host before verifying activation. SDK 3.7.63 is unchanged.
168
-
169
- ### Previous release: v3.9.92
170
-
171
- v3.9.92 keeps response-body consumption and cancellation inside the existing MCP request deadline, including Orient, First Value, buyer proof, and other JSON control calls. Malformed secondary-call responses fail explicitly. The full eleven-tool canary retains bounded backend error categories and elapsed operation timings, and closes any outcome-eligible fixture decisions before reporting success. These are client reliability corrections that the published 3.9.91 bytes cannot provide; they do not establish the cause of older unavailable receipts. Reload the host after updating and verify the installed version before claiming activation.
172
-
173
- ### Previous release: v3.9.91
174
-
175
- v3.9.91 keeps the unreachable-control allow, and stops treating every control failure as an outage. A rejected key, a permission denial, a malformed response, or any other reached-and-rejected control call still denies a protected action. Only a timeout, a network failure, or an unavailable service warns and allows. The pre-action wait is 8 seconds so the deployed auth grace can finish before the hook gives up. The published `3.9.90` package cannot deliver this distinction. SDK `3.7.63` is unchanged.
176
-
177
- ### Previous release: v3.9.90
178
-
179
- v3.9.90 is a reliability fix for every supported native hook. When Marrow or the MCP control path is unreachable, the hook warns, allows the action, and leaves the record in the local spool so it is sent after Marrow accepts traffic again. A real block or review decision still stops the action. A missing local key, an unsafe local control file, and malformed input still stop it. The published `3.9.89` package cannot deliver this behavior. SDK `3.7.63` is unchanged. Installer `0.1.58` still pins MCP `3.9.89` until the installer release that follows this publish.
180
-
181
- ### Previous release: v3.9.89
182
-
183
- v3.9.89 adds a default-enabled, private local session loop guard for every supported native-hook installation, independent of Marrow plan or fleet entitlement. It hashes bounded operation inputs and results into owner-only state under `~/.marrow`, stops unchanged successful verification repeats, stops the third unchanged poll or failed attempt, resets after meaningful mutation or a new owner prompt, and clears the session at close. Routine read-only results remain local, so ordinary checks add no Marrow API or database writes; one compact client-reported block marker is emitted only when a configured hook actually denies a repeat. Official Marrow tools remain excluded. `MARROW_AUTO_HOOK=false` and the existing owner local-control disable remain the explicit opt-outs.
184
-
185
- The pre-action path now reuses a valid runtime-created decision and calls Think only when the runtime completion contract explicitly requires decision creation. Setup reports the loop guard as configured without claiming live enforcement before host restart, trust review, and an observed hook invocation. `marrow-mcp loop-guard-self-test` verifies the local behavior against isolated temporary state without touching the user's ledger. SDK `3.7.62` and installer `0.1.57` are unchanged.
186
-
187
- ### Earlier v3.9.88 changes
188
-
189
- v3.9.88 makes the lifecycle spool self-healing so users never need a manual `drain-spool` for ordinary failures. Dead letters are now classified: authentication rejections (401/403) stay `attention_required` with credential-restore guidance and are never auto-retried; conflicts (409) are marked `server_owned` because the server already holds durable evidence for that event id, and are never replayed; every other dead letter (transport, schema, or legacy rows without a status) is `recoverable` and retried automatically by the passive nudge — at most 5 events per nudge, 3 recovery attempts each, with a 15-minute cooldown between attempts, inside the existing bounded nudge budget. Recovery bookkeeping stays local and never changes the server request. `spool-status` gains `recoverable`, `server_owned`, and `recovery_exhausted` counts, and `failed` now counts only auth-class dead letters that genuinely need the operator. Explicit `drain-spool` keeps full authority: it still retries every operator-fixable dead letter including the auth class, clears recovery exhaustion for a fresh budget, and skips server-owned events. SDK `3.7.62` and installer `0.1.56` are unchanged.
190
-
191
- ### Previous release: v3.9.85
192
-
193
- v3.9.85 keeps the existing Marrow Auto request and response deadlines active through response-body consumption and JSON parsing, so a server that sends headers and then stalls ends with the same typed bounded timeout as a stalled header response. The retry owner, four-second write-attempt ceiling, and eight-second Auto response budget are unchanged.
194
-
195
- Auto responses now include a capped, privacy-safe HTTP attempt trace with route phase, duration, status or typed error category, pending and replay state, exact numeric response auth/parse spans when exposed, and requested and measured wait. Timing coverage is explicitly partial or unavailable because detailed backend DB and Durable Object stages are not returned in these responses. The control-path canary preserves each outer Auto attempt and its inner HTTP trace on success and failure, so a slow first attempt is no longer overwritten by a later fast continuation. The trace contains no request bodies, credentials, action text, or identifiers. SDK `3.7.62` and installer `0.1.56` are unchanged; install MCP `3.9.85`, reload the host, review hook trust, and verify before claiming the updated client is active.
196
-
197
- ### Previous release: v3.9.84
198
-
199
- v3.9.84 adds bounded direct-think recovery without inventing a decision ID, and an exact scoped pending receipt for manual continuation. Saved unverified observations remain terminal untrusted evidence. It also preserves confirmation of pending automatic writes by replaying the same authenticated operation and request, with one retry owner and a four-second attempt ceiling inside the unchanged eight-second total budget. Numeric and date-based server retry delays are preserved. Conflicting receipts never confirm closure, and unavailable or unverified results remain pending.
200
-
201
- Post-action commit lookup now preserves the original general/empty-surface defaults and optional explicit target. It remains observation-only. Receipt expiry retains unverified observation evidence unless an existing historically authorized checkpoint supports exact recovery; it does not extend the old receipt or grant retrospective permission. Transient lifecycle delivery retries preserve the queued event and its stable identity across restart within bounded scheduling and attempt limits. Queued, server-accepted, and committed remain separate facts.
202
-
203
- Before upgrading, finish existing pending auto operations with their current verified client. Older auto requests omitted supplied surfaces from think; correcting nonempty surfaces can therefore expose an idempotency conflict for that old operation. Do not reinterpret the conflict, open a replacement operation, use a silent legacy fallback, or automatically downgrade. Omitted/empty surface operations preserve their original canonical scope. This is a scope-correctness change, not a promise that every pending old-client operation can resume across an upgrade.
204
-
205
- Default primary guidance uses runtime followed by commit and exposes exactly 17 tools. Auto remains available in explicitly selected core/full profiles. SDK `3.7.62` and installer `0.1.56` are unchanged; install MCP `3.9.84`, reload the host, review hook trust, and verify before claiming the updated client is active.
206
-
207
- ### Previous release: v3.9.82
208
-
209
- v3.9.82 batches client reliability fixes for `marrow_auto`. Continuations honor the server's finite retry delay within the existing eight-second core budget; when the delay cannot fit, the same operation remains pending with retry guidance. Gated auto reuses the server-created decision after checking its canonical scope, and ordinary owner approval can resume that decision when the backend explicitly declares the supported proof contract. The installed bytes of v3.9.81 cannot provide these client changes; update MCP for this behavior. SDK and installer versions are unchanged.
210
-
211
- Auto now durably queues its lifecycle receipt before responding and starts the existing bounded background delivery afterward. A queued receipt is not server acceptance, while `live_delivery.committed` separately reports confirmed governed closure. New numeric response timings distinguish core work, durable enqueue, and response construction. The canary preserves these measurements and distinguishes pending completion, owner approval, and missing proof from malformed responses or transport failures; an uncommitted canary still fails. These changes do not promise fixed latency or eliminate outages.
212
-
213
- ### Previous release: v3.9.81
214
-
215
- v3.9.81 adds bounded structured failure evidence to the authenticated eleven-tool control-path canary. Failed runs identify the observed stage, tool, error class, timing, and completed checks without retaining credentials, customer payloads, or arbitrary error text. Protocol and write failures observed after the final response or during shutdown now fail closed; the canary's own bounded cleanup remains compatible with a successful run. The eleven live-tool requirements, client deadlines, package identity checks, and retry limits are unchanged.
216
-
217
- ### Previous release: v3.9.80
218
-
219
- v3.9.80 is a reliability patch for direct `marrow_think` and `marrow_commit` calls. Each invocation now carries one stable bounded idempotency key. Only the backend's documented pending-persistence states are reconciled, using the byte-identical request and key after a fixed one-second delay for at most three reconciliation rounds. The existing transport layer permits up to two attempts per round, for up to six HTTP requests with the same key and body. A 202 response is never reported as successful completion; unknown, malformed, correlation-drifted, or exhausted pending responses fail closed with a structured error. Explicit caller-supplied idempotency keys remain unchanged, and durable `observed_unverified` outcomes retain their terminal, non-authorizing semantics.
220
-
221
- ### Previous release: v3.9.79
222
-
223
- v3.9.79 aligns `marrow_replay_compare` with the production replay contract. Its public MCP schema now exposes two exclusive modes: fetch an existing comparison with `comparison_id`, or create one with `source_decision_id`, `baseline.decision_id`, and `candidate.decision_id`. Empty, incomplete, mixed-mode, blank-ID, unsafe-ID, same-decision, and undeclared content-bearing fields fail locally before any request, while comparison fetches and valid distinct-decision comparisons keep their existing behavior. Outbound baseline and candidate references contain only validated decision IDs and optional privacy-safe identifier labels. Replay comparison still uses only already-recorded durable evidence and never runs a model or replays customer content. This release requires SDK `^3.7.62`, keeping the active MCP dependency floor aligned with the current SDK release.
224
-
225
- ## Previous: v3.9.78
226
-
227
- v3.9.78 separates durable post-action observation from action authorization. For outcome closure only, `marrow_commit` sends the existing `decision_id` to runtime and can use the backend's exact `outcome_observation_only` response to submit the already-completed result without forwarding its non-durable correlation ID as receipt evidence. That response never permits an action: it has `allow: false`, `durable: false`, and no authorization. The accepted result remains `committed: false`, `outcome_state: "observed_unverified"`, `authorization_granted: false`, and `trusted_learning_applied: false`; it is terminal delivery and is not retried from the local queue. Trusted promotion requires an explicit new commit attempt with the backend-required authorization and proof for the exact observed payload. Missing, malformed, conflicting, or cross-scope runtime truth still fails closed, and privacy-unsafe `instruction_ref` values such as dates and long numeric IDs now fail locally before any network call.
228
-
229
- ## Previous: v3.9.77
230
-
231
- v3.9.77 makes `primary` the ordinary MCP profile when `MARROW_TOOL_PROFILE` is unset. The default surface now matches the 17 documented Primary MCP Tools, while explicit `core` preserves the seven-tool control loop and explicit `full` preserves the complete catalog. Invalid values fail with an exact bounded repair instead of broadening visibility. Status responses report the effective profile, visible names/count, and fresh backend-projected entitlement states when provided; local visibility and cached evidence never authorize access. The exact-version 11-tool control-path canary remains pinned to `full`.
232
-
233
- ## Previous: v3.9.76
234
-
235
- v3.9.76 fixes owner-approved `marrow_auto` closeout by binding an arbitrated operation to the exact server-created arbitration decision, rejecting decision mismatches before commit, and returning an honest terminal action for non-arbitrated `review_required` gates. Chat and proof text cannot substitute for a dashboard-issued approval receipt, and only a backend `committed: true` response closes the operation.
236
-
237
- ## Previous: v3.9.75
238
-
239
- v3.9.75 adds explicit Codex, Cursor/Composer, Cline, Windsurf, and Gemini CLI native hook entrypoints. Gemini BeforeTool returns strict fixed allow/deny JSON, AfterTool returns neutral JSON after compact outcome capture, and AfterAgent closes one turn without reading prompt/response content or requesting a retry. Project hook trust and enablement remain user-controlled, and configuration stays client-self-reported rather than certified coverage.
240
-
241
- ## Previous: v3.9.74
242
-
243
- v3.9.74 keeps one automatic operation bound to its original runtime authorization and decision across timeout and proof-required retries, then closes that exact decision once verified proof is supplied. One outer `marrow_auto` invocation normally completes think and commit in-band within its bounded eight-second client budget. The release canary allows that complete client budget plus bounded response overhead rather than cutting the operation off at five seconds.
244
-
245
- ## Previous: v3.9.72
246
-
247
- v3.9.72 requires SDK `3.7.61` so MCP installations cannot resolve to an SDK that recursively intercepts its own Marrow control-plane traffic. The MCP tool contract is unchanged; this release aligns the tested package chain.
248
-
249
- ## Previous: v3.9.71
250
-
251
- v3.9.71 makes the advertised Grok control loop true:
252
-
253
- - default tools include `marrow_think` so the official loop can create a `decision_id` without `MARROW_TOOL_PROFILE=full`;
254
- - process identity prefers `MARROW_KEY_<ROLE>` when it matches `MARROW_AGENT_ID`, so a leaked fleet env cannot 403 every status call;
255
- - Grok native hooks are installed under `~/.grok/hooks/marrow.json` and hook parsers accept Grok camelCase envelopes;
256
- - Grok native PreToolUse, PostToolUse/PostToolUseFailure, and nonblocking Stop hooks provide bounded client-reported gating, result evidence, and one turn closeout. The governed wrapper remains an explicit bounded fallback;
257
- - idle spool nudge drains up to 40 current-namespace events so the queue does not sit as a nag;
258
- - if `risk_gate.enforced` is false, the gate is advisory — do not describe it as a live block;
259
- - `marrow_commit.decision_id` comes from `marrow_think`, `marrow_auto`, or an arbitration runtime that actually created a decision. A normal runtime may create or reuse a decision: follow runtime.decision_id and completion_contract. Keep runtime.runtime_authorization.id separate as gate_receipt_id.
260
-
261
- ## Previous: v3.9.69
262
-
263
- v3.9.69 keeps the always-on spool from growing into a nag queue:
264
-
265
- - status, runtime, and ask quarantine leftover credential-namespace files instead of replaying them;
266
- - pending current-namespace events are nudged in the background so 8 queued receipts are not a healthy idle state;
267
- - explicit `drain-spool` still retries failed current-namespace events.
268
-
269
- ## Previous: v3.9.68
270
-
271
- v3.9.68 stops Ask from fighting a real lesson:
272
-
273
- - `marrow_ask` does not concatenate "Historical guidance is warming" onto a lesson;
274
- - `decisions_matched` follows the server count, not a similar-failure sum that can be 0;
275
- - `low_history` is false when hive memory or a lesson is already present.
276
-
277
- ## Previous: v3.9.67
278
-
279
- v3.9.67 gives writes room to finish:
280
-
281
- - `marrow_commit` uses an 8s transport ceiling instead of aborting on the 4s read cliff;
282
- - the MCP tool deadline for commit matches that write ceiling.
283
-
284
- ## Previous: v3.9.66
285
-
286
- v3.9.66 keeps the slim runtime honest for live sessions:
287
-
288
- - slim `marrow_agent_runtime` echoes the requested action instead of an empty string;
289
- - `marrow_ask` returns a real lesson/`top_outcomes` line when hive memory exists;
290
- - local `client_update` no longer reports `latest_version: null` when the adapter version is known;
291
- - tool payloads only ask for a spool drain when the current namespace has pending or failed events.
292
-
293
- ## Previous: v3.9.65
294
-
295
- v3.9.65 makes the first hour useful and closes the session honestly:
296
-
297
- - prompt context prints first-hour copy: the gate is live, empty savings are healthy, and the next deploy, merge, or publish goes through Marrow;
298
- - Stop hooks and `marrow_session_end` auto-commit open work;
299
- - session usage is recorded only when the host emits counts.
300
-
301
- ## Previous: v3.9.64
302
-
303
- v3.9.64 prints the live habit loop and records observed model usage without inventing savings:
304
-
305
- - `marrow_status` and other control tools include `habit_loop_copy` from `marrow.habit-loop.v1`;
306
- - PostToolUse hooks send compact token counts only when the tool result actually includes usage;
307
- - empty savings stay honest until those observed counts land.
308
-
309
- ## Previous: v3.9.63
310
-
311
- v3.9.63 closes identified-workflow reuse on the MCP control path:
312
-
313
- - `marrow_commit` sends `identified_workflow_id` from auto-gate runtime when Marrow already identified the path;
314
- - hook context tells the agent not to rediscover a matched workflow and only mentions token savings when evidence exists;
315
- - the live API still attributes reuse from the gate receipt if a client omits the id.
316
-
317
- ## Previous: v3.9.62
318
-
319
- v3.9.62 integrates four model-neutral reliability and capability contracts:
320
-
321
- - standalone `marrow_status` uses the bounded compact API contract and can return a fresh, owner-only last-known status projection without treating it as a live gate or authorization;
322
- - ordinary runtime responses expose typed `runtime_authorization` backed by the authoritative gate receipt and omit `decision_id` unless the server actually created a decision;
323
- - `spool-status` and `drain-spool` report the active credential namespace separately from isolated legacy debt, and a clear active namespace exits successfully without replaying, merging, editing, or deleting old-key files;
324
- - initialize, prompt, setup, and tool responses qualify coverage by `host_capability`: MCP tools are on demand, while client-self-reported hook activity remains visible but never certifies coverage or control.
325
-
326
- In v3.9.62, the default surface was seven tools (runtime, think, commit, ask, status, auto, handoff status) and the prompt remained named `marrow-always-on`. Host and model labels are display-only and never change auth, tenant, plan, policy, proof, schema, or API behavior. Grok hook activity is client-self-reported and does not certify observed coverage; the governed wrapper remains an explicit bounded fallback.
327
-
328
- ## Previous: v3.9.61
329
-
330
- v3.9.61 keeps an authoritative proof-pack rejection distinct from a control-path outage:
331
-
332
- - backend `MARROW_PROOF_PACK_INCOMPLETE` responses are reported as `validation` / `proof_required`, not infrastructure failures;
333
- - the exact missing proof fields and backend repair instruction remain visible to the agent;
334
- - live proof validation does not return a stale outage brief or unavailable authorization state;
335
- - proof enforcement remains fail-closed, and successful commit behavior is unchanged.
336
-
337
- ## Previous: v3.9.60
338
-
339
- v3.9.60 restores the complete control-and-proof loop for ordinary MCP clients:
340
-
341
- - cached guidance no longer cuts live status, ask, runtime, or handoff reads down to an impossible 500 ms deadline;
342
- - `marrow_auto` normally waits for the bounded think-and-commit path and reports the live decision and proof result in-band; if the client deadline is reached, the returned operation ID continues that same decision;
343
- - `marrow_commit` now shares the same abort and deadline contract as the other control calls;
344
- - transient retries use a one-second delay so a slow edge path is not immediately hit again;
345
- - spool status surfaces backlogs under older credential namespaces without replaying them across an unverified tenant boundary;
346
- - a plan-gated handoff is reported as unavailable for the current plan, not as an API or authentication outage;
347
- - the release canary runs with the customer's default client deadlines instead of silently overriding them.
348
-
349
- The current package gives MCP-only hosts the same model-neutral control instructions and seven-tool default surface, but MCP transport alone remains on demand. A host or model label never changes that coverage contract. Public lifecycle callbacks and hook activity are client-self-reported and cannot verify or certify passive coverage; independent authority is required. Codex, Grok, and Gemini can use configured native hooks after restart and host hook review; the governed wrapper remains an explicit bounded fallback.
350
-
351
- ## Previous: v3.9.59
352
-
353
- v3.9.59 makes the six-tool control path reliable and honest across ordinary edge and geographic latency:
354
-
355
- - the default health deadline is 2.5 seconds instead of an unrealistically narrow 400 ms;
356
- - `MARROW_PING_TIMEOUT_MS` can tune the probe between 500 ms and 5 seconds;
357
- - authenticated control reads tolerate cold network/TLS paths while cached reads still return quickly;
358
- - status, ask, runtime, and handoff responses report measured current/p50/p99 latency plus owner-only queue health;
359
- - a first-session outage returns a clearly labeled local safety brief, and infrastructure failures are never mislabeled as policy denials;
360
- - timeout errors return a concrete retry delay instead of an unresolved placeholder;
361
- - Cloudflare edge denials are separated from key-scope or Marrow policy rejections;
362
- - MCP initialization carries the capability-qualified control/proof instructions even when a client does not request the optional prompt template;
363
- - update, launch, setup, spool, and ping commands use the unambiguous `npx --package ... marrow-mcp` form;
364
- - explicit spool drains tolerate slow edge delivery without extending passive hook latency.
365
-
366
- ## Previous: v3.9.58
367
-
368
- v3.9.58 makes latency evidence accurate by reusing one initialized MCP process for the complete control-path canary:
369
-
370
- - startup, initialization, and tool discovery are measured separately from authenticated tool calls;
371
- - hot-path steering and report latency are reported as separate p50, p95, p99, and maximum groups;
372
- - response IDs, malformed output, RPC failures, timeouts, and incomplete tool contracts fail closed;
373
- - one bounded process prevents package and process startup time from being mistaken for API latency.
374
-
375
- The compact agent control path introduced in v3.9.57 remains the default:
376
-
377
- - `marrow_status`, `marrow_ask`, and `marrow_agent_runtime` use authenticated routes with bounded retries and typed failures;
378
- - transient read failures return an owner-only last-known brief when available, while cached guidance can never authorize high-risk work;
379
- - normal tool errors return structured `ok`, `error_code`, `exact_fix`, `stale_brief`, and `client_update` data instead of raw MCP `fetch failed` errors;
380
- - the v3.9.58 default agent surface was seven tools: runtime, think, commit, ask, status, auto, and handoff status; `MARROW_TOOL_PROFILE=full` selected legacy or advanced integrations;
381
- - risky `marrow_auto` calls obtain a fresh runtime gate automatically and cannot self-close as successful without required proof;
382
- - `marrow_run` requires an explicit outcome and never invents proof or a successful result;
383
- - the package includes an exact-version control-path canary covering every route reported in the production incident.
384
-
385
- ## Previous: v3.9.56
386
-
387
- v3.9.56 adds tenant-scoped coordination and evidence-only replay to the existing MCP governance surface:
388
-
389
- - each normal user prompt performs one compact `/v1/agent/context` read; risky or mutating prompts perform one `/v1/agent/runtime` call instead;
390
- - prompt lifecycle receipts are accepted into the owner-only local spool immediately and delivered asynchronously by later lifecycle activity;
391
- - the prompt read deadline is 400 ms, injected guidance is limited to 3–8 concise lines, and raw prompts are not stored in the guidance cache;
392
- - transient failures can use an owner-only, account/key/agent-scoped last-known brief for at most one hour, clearly labeled with its age;
393
- - 401 and 403 responses never use cached guidance, and cached runtime guidance cannot authorize high-risk work;
394
- - `marrow_ask` now maps to the canonical decision brief contract instead of a separate route;
395
- - `npx -y --package=@getmarrow/mcp@latest marrow-mcp ping` reports current latency, rolling measured p50/p99, last success, and lifecycle backlog health;
396
- - `marrow_coordinate` acquires/releases tenant-scoped resource leases and carries compact child proof packets without sharing transcripts;
397
- - `marrow_replay_compare` compares already-recorded baseline and candidate outcomes with durable proof and never executes either model;
398
- - both new tools preserve agent-bound key scope, reject unsafe path identifiers, and return unavailable or incomplete evidence rather than manufacturing a winner.
399
-
400
- The package remains backward compatible with supported server aliases while advertising only implemented tools.
401
-
402
- This release is paired with SDK `3.7.56` and installer `0.1.41`. The deterministic release order is SDK first, MCP second, installer third, and the API release last.
403
-
404
- ## Previous: v3.9.54
405
-
406
- v3.9.54 makes Marrow's intervention visible through the existing decision-trace workflow:
407
-
408
- - `marrow_decision_trace` returns an owner-readable receipt for an evidence-backed block, warning, or review;
409
- - passive setup tells agents to relay one factual receipt after a meaningful intervention and remain quiet for routine low-risk work;
410
- - the receipt reports required workflow, proof, permit follow-through, and recorded outcome without raw context, proof values, credentials, or cross-tenant data.
411
-
412
- It preserves the bounded MCP lifecycle recovery introduced in v3.9.53.
413
-
414
- ## Previous: v3.9.53
415
-
416
- v3.9.53 adds exact lifecycle backlog visibility and bounded recovery for MCP-routed agent activity:
417
-
418
- - compact, redacted receipts remain in an owner-only spool through transient failures;
419
- - `spool-status` reports exact pending, failed, capacity, and oldest-receipt evidence;
420
- - `drain-spool` retries queued receipts without manufacturing a new lifecycle event;
421
- - a successful current receipt performs one bounded best-effort retry of older queued work;
422
- - terminal rejections and exhausted retries remain explicit dead letters for operator action.
423
-
424
- It preserves the signed action-permit and update controls introduced in v3.9.52.
425
-
426
- ## Previous: v3.9.52
427
-
428
- v3.9.52 combines operator-controlled client update notices with signed, action-bound permit verification in the cooperative Claude Code hook path. That permit flow does not authenticate hook provenance or certify always-on coverage. Official MCP requests identify the installed package version, and passive context renders a request-specific server advisory with exact update and verification commands:
429
-
430
- - update availability or unrecognized version metadata appears during normal authenticated runtime/status activity;
431
- - messaging clearly states that hosted Marrow services are already current and that no local change was applied;
432
- - agents are instructed to tell the operator and respect local change policy instead of silently changing packages or configuration;
433
- - unknown versions do not imply a vulnerability, while server-designated security requirements remain distinct;
434
- - existing MCP tools and older server responses remain compatible when no advisory is returned.
435
-
436
- The Claude Code `PreToolUse` hook cooperatively verifies the permit before returning control to that harness. It obtains the runtime gate, records the exact governed decision, requests a permit bound to that gate, decision, target, and canonical action surfaces, and consumes it before returning. The callback itself remains client-self-reported and is not a certified external choke point:
437
-
438
- - protected deploy, publish, merge, migration, credential, and production actions fail closed on timeout or permit failure;
439
- - the permit is bound to the authenticated account, key, agent, session, action, target, canonical action surfaces, decision, and runtime gate;
440
- - raw tool input and permit tokens are never written into hook output or lifecycle telemetry;
441
- - matching result and closure hooks preserve one correlation so every exact server-required proof field can close the consumed permit automatically;
442
- - the bounded hook timeout prevents a control-plane wait from hanging the agent indefinitely;
443
- - low-risk work retains passive/advisory behavior unless account policy requires stronger enforcement.
444
-
445
- It preserves native-hook activity diagnostics introduced in v3.9.50, with the current trust boundary applied:
446
-
447
- - agents and owners can distinguish “MCP configured” from client-reported pre-action, result, and session activity without treating either as certification;
448
- - `PreToolUse` requests the Marrow runtime gate before matched actions and maps `block` to deny and `review_required` to operator review;
449
- - matching `PreToolUse` and result hooks share Claude Code's tool-use correlation while the session shares one workflow identity;
450
- - generic integration events and public hook entrypoints cannot claim certified native-hook coverage;
451
- - retries preserve correlation and explicitly `client_self_reported` activity in the owner-only durable spool;
452
- - configuration drift can be diagnosed without sending configuration contents;
453
- - missing outcome closure remains visible rather than treating tool or session exit as business success;
454
- - existing MCP tools and lifecycle inputs remain compatible.
455
-
456
- It preserves `marrow_arbitrate` from v3.9.49, the session-orientation hardening introduced in v3.9.48, and the always-on lifecycle introduced in v3.9.44:
457
-
458
- - `server.json` and `mcpName` identify the stdio server, required secret, source repository, and package version for registry consumers;
459
- - GitHub, npm, and MCP registry surfaces use separate signed discovery placements;
460
- - package language consistently describes agent governance, runtime control, proof, and fleet intelligence;
461
- - bounded positive and negative recommendation criteria stop agents from forcing Marrow into irrelevant workflows;
462
- - current evidence, integration paths, and published references are linked from one review-dated contract;
463
- - `UserPromptSubmit` obtains relevant task guidance without storing raw prompt text;
464
- - `PreToolUse` checks matched tool actions before execution without sending raw tool input;
465
- - `PostToolUse` and `PostToolUseFailure` record compact result receipts;
466
- - `Stop` keeps unfinished outcomes visible instead of silently treating a session exit as success;
467
- - transient lifecycle delivery failures use an owner-only, bounded local spool with stable event IDs;
468
- - `marrow_decision_trace` explains the tenant-scoped path from prior failure and lesson through gate, proof, workflow, and outcome, and returns an owner-readable intervention receipt.
469
-
470
- Existing MCP tools and stable context API names remain compatible. Authentication, policy, proof, and validation failures are surfaced rather than retried as network failures.
471
-
472
- Client hook activity alone never produces certified coverage percentages. An installed config or API-key-authenticated callback is shown as client-self-reported activity; certification requires an independent authority not supplied by the public MCP hook entrypoints.
473
-
474
164
  ## Governed Action Flow
475
165
 
476
166
  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`.
@@ -491,9 +181,9 @@ A `review_required`, `block`, or `outcome_observation_only` result never permits
491
181
 
492
182
  If a receipt expires while the same decision remains open, explicitly request normal runtime again with the original action, type, surfaces, agent and session. A fresh request key is required: replaying the old runtime key replays its old receipt. Verify the returned `runtime.decision_id` still matches the original, keep the new `runtime.runtime_authorization.id` as `gate_receipt_id`, and satisfy the current proof and approval contract. For a scope with an explicit target, use the `marrowAgentRuntime` library or `POST /v1/agent/runtime` preserving that target; the public MCP runtime schema does not expose target. Do not renew through post-action `auto_gate`: it only obtains observation truth. A fresh receipt never retrospectively authorizes an action taken without permission, and a changed scope is a different decision. Expired or used receipts may return an accepted `observed_unverified` result with `committed:false`; that is not closure.
493
183
 
494
- For an ordinary gate, continue only when the server declares `completion_contract.owner_approval.mode: "ordinary_non_arbitrated"`. Auto waits in `owner_approval_required` until the caller actually obtains explicit owner approval for the exact work and supplies `proof.owner_approval = { approved_by: "owner", reference: "approved-release-bundle" }` together with required measured proof. Then call auto once with the same operation ID and original decision/receipt scope. The object records actual approval; it is not permission to infer approval from action text, a model response, or `human_directed`. Unknown ordinary completion contracts remain stopped without automatically starting arbitration. The backend checks receipt ownership, scope, expiry, and proof before confirming closure.
184
+ For an ordinary hold (`completion_contract.owner_approval.mode: "ordinary_non_arbitrated"`), auto waits in `owner_approval_required` and reads the gate receipt's approval status as the server advises. Call auto again with the same operation ID after `retry_after_ms`; once the server has recorded an approval (see [Approvals in the Host Prompt](#approvals-in-the-host-prompt)), auto resumes on the same decision and gate receipt. A decline closes the decision as a gate denial when the action has not run, and a spent gate receipt is final: auto reports the operation as closed and never asks to run it again. A caller-written `proof.owner_approval` is never an approval: MCP strips it, and only an approval the server records counts. Unknown ordinary completion contracts remain stopped without automatically starting arbitration.
495
185
 
496
- For arbitration, the ordinary proof marker is not accepted. Approve the exact arbitration decision in the authenticated Marrow dashboard, then call auto with the same operation ID, `arbitration_receipt_id`, and server-issued `owner_approval_receipt_id`. Proof or chat text cannot substitute for this dashboard receipt. A CLI closed response reports `phase: "closed"`, `live_delivery.committed: true`, and `resumable: false`; the library result uses `committed: true`. Neither an ordinary marker nor an outcome record changes a stopped action into an allowed action.
186
+ For arbitration, the account owner picks and approves one proposal through a one-tap link (see [Approvals in the Host Prompt](#approvals-in-the-host-prompt)); auto waits on the status read and commits with the `owner_approval_receipt_id` it returns. Otherwise call auto with the same operation ID, `arbitration_receipt_id`, and the server-issued `owner_approval_receipt_id`. Proof or chat text cannot substitute for this receipt. A CLI closed response reports `phase: "closed"`, `live_delivery.committed: true`, and `resumable: false`; the library result uses `committed: true`. An outcome record never changes a stopped action into an allowed action.
497
187
 
498
188
  The CLI's lifecycle `receipt.queued: true` means its stable event is stored locally for later bounded delivery; `receipt.accepted: false` must not be read as server acceptance. Transient failures preserve the queued event and retry schedule for later bounded delivery, including after restart. Server retry guidance is respected. Authentication failures remain failed with explicit credential-repair guidance and are never auto-retried; conflicted events are server-owned evidence and are never replayed; every other dead letter self-heals through bounded automatic recovery during passive nudges. Process exit can interrupt the background nudge, leaving the event for a later run. `phase_timings_ms.total` measures core auto phases. `response_timings_ms` contains numeric `core`, `durable_enqueue`, and `full_response`; the last ends at response construction and excludes subsequent stdout drain and host processing. Canary `latency_ms` independently measures the MCP round trip, while `attempts` and `retry_wait_ms` describe measured outer tool retries, not internal database or network calls.
499
189
 
@@ -575,9 +265,10 @@ Marrow resolves agent roles from the account rather than trusting caller claims.
575
265
  Evidence references must be opaque identifiers; do not send raw prompts, logs,
576
266
  URLs, paths, credentials, or customer content. The arbitration response owns the
577
267
  `decision_id`, gate receipt, and arbitration receipt used at commit. A
578
- `review_required` result must be approved from an authenticated Marrow dashboard
579
- session; pass its short-lived, single-use `owner_approval_receipt_id` to
580
- `marrow_commit`. An agent cannot authorize itself with a proof field.
268
+ `review_required` result needs the account owner's approval of one proposal
269
+ through a one-tap link; pass the resulting short-lived, single-use
270
+ `owner_approval_receipt_id` to `marrow_commit`. An agent cannot authorize itself
271
+ with a proof field.
581
272
 
582
273
  Use `marrow_coordinate` when parallel agents could edit the same file, service,
583
274
  deployment, or workflow. An acquired lease returns a one-time release capability.
@@ -589,9 +280,34 @@ Use `marrow_replay_compare` after two model or workflow variants have each
589
280
  recorded an outcome. It compares that existing evidence under one tenant task;
590
281
  it does not run models, retain prompts, or infer a winner from labels.
591
282
 
283
+ ## Approvals in the Host Prompt
284
+
285
+ These approvals turn on when the Marrow service update ships; until then held actions work as in 3.9.98: Claude Code asks in its dialog and other hosts hold for the account owner.
286
+
287
+ When Marrow holds an action for approval (`review_required`), the person approves it where they already work, and nobody has to log in. The hooks record the answer with Marrow; the agent never reports or claims an approval. The Marrow dashboard shows receipts and history; it is not where approvals happen.
288
+
289
+ | Host and session | What the person does |
290
+ | --- | --- |
291
+ | Claude Code (`default`, `acceptEdits`; `auto` from v2.1.257) | Answers Claude Code's own permission dialog. In `plan`, `dontAsk` and `bypassPermissions` modes they switch to the default mode and retry. |
292
+ | Cursor shell and MCP calls, local session | Answers Cursor's own approval prompt |
293
+ | Codex and Gemini CLI, local interactive session with their own approval prompt on | Types the reply the hook showed them only, such as `marrow approve CODE` |
294
+ | MCP clients with elicitation (`marrow_auto`) | Answers the client's own dialog (client-attested) |
295
+ | Codex TUI before its prompt hook, Cline and Windsurf in the editor | Uses the host's own approval step, if they have it on: the hook answers neutrally, never with an explicit allow, and Marrow records the result as not observed by Marrow |
296
+ | Grok, Gemini without its prompt hook, Cursor at `preToolUse` and Cursor's other tools, Codex with its approval prompt off, Gemini CLI in YOLO mode (`--yolo`, `-y`, `--approval-mode yolo`), or no evidence of a person | No typed reply and no code (the agent could answer one itself); the action waits quietly for the owner |
297
+ | Unattended runs (headless Claude Code, `codex exec`, `gemini -p`, Cursor cloud) | Nothing in the run: the action waits quietly and the agent carries on |
298
+ | Arbitration review | The account owner picks one proposal through a one-tap link |
299
+
300
+ - **The owner's email link is the exception.** It is sent only for a category the owner locked, for the owner's own standing decline once the operator asks to reverse it (retrying, or `request_owner_link: true` on `marrow_auto`), for an unattended run when the owner turned on unattended pings, or for an arbitration review when the operator asks. An ordinary hold never emails anyone.
301
+ - **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.
302
+ - **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.
303
+ - **One approval, one run.** Of two identical calls on one approval, one runs and the other is denied.
304
+ - **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 reuses an approval for it, so a held one asks each time. 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.
305
+ - **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 keeps the outage policy, and a waiting hold or owner-locked category stays held.
306
+ - **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.
307
+
592
308
  ## Passive Use
593
309
 
594
- `npx -y --package=@getmarrow/mcp@latest marrow-mcp setup` configures supported prompt, pre-action, tool-result, and session-stop hooks. Configuration, public hook argv, and API-key-authenticated callbacks are client self-reports. They preserve raw lifecycle activity but do not prove that the host invoked a hook or certify passive control.
310
+ `npx -y --package=@getmarrow/mcp@latest marrow-mcp setup` configures supported prompt, pre-action, tool-result, permission-marker, and session-stop hooks. Configuration, public hook argv, and API-key-authenticated callbacks are client self-reports. They preserve raw lifecycle activity but do not prove that the host invoked a hook or certify passive control.
595
311
 
596
312
  ### Capability and coverage contract
597
313
 
@@ -603,13 +319,13 @@ it does not run models, retain prompts, or infer a winner from labels.
603
319
  | Governed runner | Only the command launched through the wrapper |
604
320
  | Custom host | Requires a bounded event adapter; covers only the lifecycle events whose receipts Marrow observes |
605
321
 
606
- This contract is model-neutral. A model name, host header, API key, public hook entrypoint, config file, installed hook entry, successful MCP handshake, or client-self-reported lifecycle callback does not certify passive coverage or enforcement. An unknown MCP host therefore gets the generic `mcp-client` identity and the same on-demand tools, schemas, and API semantics as a named host.
322
+ This contract is model-neutral. A model name, host header, API key, public hook entrypoint, config file, installed hook entry, successful MCP handshake, or client-self-reported lifecycle callback does not certify passive coverage or enforcement. An unknown MCP host therefore gets the generic `mcp-client` identity and the same on-demand tools, schemas, and API semantics as a named host. Public lifecycle callbacks and hook activity are client-self-reported and cannot verify or certify passive coverage; independent authority is required.
607
323
 
608
324
  When invoked by a supported host, the configured hooks send compact classifications and lifecycle receipts. They do not need raw prompts, completions, command output, tool output, or credentials. A completed tool or session does not automatically become a successful business outcome; explicit success/failure closure is required.
609
325
 
610
326
  Setup installs distinct Claude Code and Grok hook entrypoints. The public entrypoint supplies only a client-reported display label; it is not host provenance. Hook event JSON cannot select the lifecycle harness or agent. Agent identity comes only from owner configuration when present, otherwise the request omits it so the authenticated service can derive the credential-bound identity. Every hook lifecycle event is marked `source: client_self_reported` and omits `capability_level: native_hooks`, adapter certification, configuration fingerprints, expected hooks, and observed-hook certification fields. Legacy, unknown, and custom entrypoints stay generic.
611
327
 
612
- Claude Code hooks may cooperatively request guidance and apply the harness permission response, but that does not certify always-on control. Codex native hooks map both block and review-required gates to the supported synchronous deny response. Cursor and Composer use the same Cursor-native pre-action, result, failure, and stop adapters. Cline uses native pre-action and post-tool adapters plus TaskCancel closeout; its documented TaskComplete hook remains coming soon and is not claimed as observed coverage. Windsurf uses native pre-action, success-result, and response-closeout adapters and requires Restricted Mode to be off. Gemini CLI uses native BeforeTool, AfterTool, and AfterAgent adapters; AfterAgent is the deterministic per-turn closeout and no SessionEnd delivery is claimed. Grok uses global native PreToolUse, PostToolUse/PostToolUseFailure, and one nonblocking Stop closeout; Marrow's generated Grok file contains no duplicate SessionEnd closeout. These native paths keep MCP on demand and require restart plus host hook review. Cursor, Cline, Windsurf, Gemini, and Grok deny protected review-required or unavailable-control work when their native contracts cannot make a generic ask enforceable. All activity remains client-self-reported rather than verified host telemetry, and the governed wrapper remains an explicit bounded fallback. Unknown and custom hosts remain on demand unless they provide a bounded event adapter, whose activity is still not certification without an independent authority.
328
+ Claude Code hooks may cooperatively request guidance and apply the harness permission response, but that does not certify always-on control. Codex native hooks map a block to the supported synchronous deny response; a review-required hold follows [Approvals in the Host Prompt](#approvals-in-the-host-prompt). Cursor and Composer use the same Cursor-native pre-action, result, failure, and stop adapters. Cline uses native pre-action and post-tool adapters plus TaskCancel closeout; its documented TaskComplete hook remains coming soon and is not claimed as observed coverage. Windsurf uses native pre-action, success-result, and response-closeout adapters and requires Restricted Mode to be off. Gemini CLI uses native BeforeTool, AfterTool, and AfterAgent adapters; AfterAgent is the deterministic per-turn closeout and no SessionEnd delivery is claimed. Grok uses global native PreToolUse, PostToolUse/PostToolUseFailure, and one nonblocking Stop closeout; Marrow's generated Grok file contains no duplicate SessionEnd closeout. These native paths keep MCP on demand and require restart plus host hook review. Where a native contract cannot make a generic ask enforceable (Cursor at `preToolUse`, Gemini, and Grok), protected review-required or unavailable-control work is denied and waits for approval; Cline and Windsurf hand an ordinary hold to the host's own prompt when a person is evidenced. All activity remains client-self-reported rather than verified host telemetry, and the governed wrapper remains an explicit bounded fallback. Unknown and custom hosts remain on demand unless they provide a bounded event adapter, whose activity is still not certification without an independent authority.
613
329
 
614
330
  Transient lifecycle receipts use a bounded owner-only spool and are retried with stable event IDs. Dead letters self-heal: recoverable failures are retried automatically with bounded attempts and cooldown during passive nudges, and conflicted events are recognized as server-owned evidence that is never replayed. Operators can inspect and drain it without exposing event content:
615
331
 
@@ -665,6 +381,9 @@ The template tools expose 24 configurable workflow examples. They are starting p
665
381
  - Sanitized aggregate contribution is optional and never means sharing raw prompts, code, secrets, proof packs, account identifiers, agent identifiers, or customer identities.
666
382
  - Existing API keys are never returned after creation; key material should be supplied through the client's secret store.
667
383
  - Marrow returns guidance and policy data. Agents must not execute returned text as shell input.
384
+ - An agent cannot approve itself: a caller-written `proof.owner_approval` is stripped, chat or proof text is never an approval receipt, and only an approval the server records counts.
385
+ - 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.
386
+ - 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.
668
387
 
669
388
  See the [Trust Center](https://getmarrow.ai/trust/) for implemented controls, current limits, and roadmap status.
670
389