@getmarrow/mcp 3.9.73 → 3.9.75
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 +28 -19
- package/dist/cli.js +31 -27
- package/dist/cli.js.map +1 -1
- package/dist/control-state.d.ts +25 -0
- package/dist/control-state.d.ts.map +1 -0
- package/dist/control-state.js +112 -0
- package/dist/control-state.js.map +1 -0
- package/dist/hook-context.d.ts +1 -1
- package/dist/hook-context.d.ts.map +1 -1
- package/dist/hook-context.js +18 -9
- package/dist/hook-context.js.map +1 -1
- package/dist/hook-contract.d.ts +43 -15
- package/dist/hook-contract.d.ts.map +1 -1
- package/dist/hook-contract.js +358 -44
- package/dist/hook-contract.js.map +1 -1
- package/dist/hook-pre-action.d.ts +19 -1
- package/dist/hook-pre-action.d.ts.map +1 -1
- package/dist/hook-pre-action.js +208 -30
- package/dist/hook-pre-action.js.map +1 -1
- package/dist/hook-session.d.ts +1 -1
- package/dist/hook-session.d.ts.map +1 -1
- package/dist/hook-session.js +86 -41
- package/dist/hook-session.js.map +1 -1
- package/dist/hook-tool-policy.d.ts +2 -0
- package/dist/hook-tool-policy.d.ts.map +1 -1
- package/dist/hook-tool-policy.js +23 -2
- package/dist/hook-tool-policy.js.map +1 -1
- package/dist/hook.d.ts +14 -2
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +51 -29
- package/dist/hook.js.map +1 -1
- package/dist/host-capability.d.ts +23 -16
- package/dist/host-capability.d.ts.map +1 -1
- package/dist/host-capability.js +41 -61
- package/dist/host-capability.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -120
- package/dist/index.js.map +1 -1
- package/dist/lifecycle-spool.d.ts +1 -5
- package/dist/lifecycle-spool.d.ts.map +1 -1
- package/dist/lifecycle-spool.js +11 -28
- package/dist/lifecycle-spool.js.map +1 -1
- package/package.json +1 -1
- package/scripts/control-path-canary.cjs +28 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Set the key through trusted secret storage:
|
|
|
66
66
|
export MARROW_API_KEY=mrw_live_...
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
For
|
|
69
|
+
For Claude Code's cooperative pre-action hook, Marrow accepts the process environment or an owner-controlled `~/.marrow/env` file with owner-only permissions. Repository-local `.env` files are intentionally ignored so project content cannot replace the account, agent, or API endpoint used for guidance. The public hook callback is still a client self-report, not certified host provenance or an external enforcement boundary.
|
|
70
70
|
|
|
71
71
|
Then configure the MCP server:
|
|
72
72
|
|
|
@@ -104,9 +104,13 @@ npx -y --package=@getmarrow/mcp@latest marrow-mcp ping
|
|
|
104
104
|
|
|
105
105
|
Detection and notification are automatic. After explicit installer activation, the local controller may restore only Marrow-managed hooks/configuration. Package upgrades, owner policy, credentials, and unrelated configuration remain explicit and subject to the operator's normal change policy.
|
|
106
106
|
|
|
107
|
-
## What's New in v3.9.
|
|
107
|
+
## What's New in v3.9.75
|
|
108
108
|
|
|
109
|
-
v3.9.
|
|
109
|
+
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.
|
|
110
|
+
|
|
111
|
+
## Previous: v3.9.74
|
|
112
|
+
|
|
113
|
+
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.
|
|
110
114
|
|
|
111
115
|
## Previous: v3.9.72
|
|
112
116
|
|
|
@@ -119,6 +123,7 @@ v3.9.71 makes the advertised Grok control loop true:
|
|
|
119
123
|
- default tools include `marrow_think` so the official loop can create a `decision_id` without `MARROW_TOOL_PROFILE=full`;
|
|
120
124
|
- process identity prefers `MARROW_KEY_<ROLE>` when it matches `MARROW_AGENT_ID`, so a leaked fleet env cannot 403 every status call;
|
|
121
125
|
- Grok native hooks are installed under `~/.grok/hooks/marrow.json` and hook parsers accept Grok camelCase envelopes;
|
|
126
|
+
- 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;
|
|
122
127
|
- idle spool nudge drains up to 40 current-namespace events so the queue does not sit as a nag;
|
|
123
128
|
- if `risk_gate.enforced` is false, the gate is advisory — do not describe it as a live block;
|
|
124
129
|
- `marrow_commit.decision_id` comes from `marrow_think`, `marrow_auto`, or an arbitration runtime that actually created a decision. A normal runtime authorization is a gate receipt, not a decision.
|
|
@@ -186,9 +191,9 @@ v3.9.62 integrates four model-neutral reliability and capability contracts:
|
|
|
186
191
|
- 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;
|
|
187
192
|
- ordinary runtime responses expose typed `runtime_authorization` backed by the authoritative gate receipt and omit `decision_id` unless the server actually created a decision;
|
|
188
193
|
- `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;
|
|
189
|
-
- initialize, prompt, setup, and tool responses qualify coverage by `host_capability`: MCP tools are on demand, while
|
|
194
|
+
- 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.
|
|
190
195
|
|
|
191
|
-
The default surface is seven tools (runtime, think, commit, ask, status, auto, handoff status) and the prompt remains named `marrow-always-on`. Host and model labels are display-only and never change auth, tenant, plan, policy, proof, schema, or API behavior. Grok
|
|
196
|
+
The default surface is seven tools (runtime, think, commit, ask, status, auto, handoff status) and the prompt remains 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.
|
|
192
197
|
|
|
193
198
|
## Previous: v3.9.61
|
|
194
199
|
|
|
@@ -204,14 +209,14 @@ v3.9.61 keeps an authoritative proof-pack rejection distinct from a control-path
|
|
|
204
209
|
v3.9.60 restores the complete control-and-proof loop for ordinary MCP clients:
|
|
205
210
|
|
|
206
211
|
- cached guidance no longer cuts live status, ask, runtime, or handoff reads down to an impossible 500 ms deadline;
|
|
207
|
-
- `marrow_auto` waits for the bounded think-and-commit path and reports the live decision and proof result in-band;
|
|
212
|
+
- `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;
|
|
208
213
|
- `marrow_commit` now shares the same abort and deadline contract as the other control calls;
|
|
209
214
|
- transient retries use a one-second delay so a slow edge path is not immediately hit again;
|
|
210
215
|
- spool status surfaces backlogs under older credential namespaces without replaying them across an unverified tenant boundary;
|
|
211
216
|
- a plan-gated handoff is reported as unavailable for the current plan, not as an API or authentication outage;
|
|
212
217
|
- the release canary runs with the customer's default client deadlines instead of silently overriding them.
|
|
213
218
|
|
|
214
|
-
MCP-only hosts
|
|
219
|
+
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.
|
|
215
220
|
|
|
216
221
|
## Previous: v3.9.59
|
|
217
222
|
|
|
@@ -290,7 +295,7 @@ It preserves the signed action-permit and update controls introduced in v3.9.52.
|
|
|
290
295
|
|
|
291
296
|
## Previous: v3.9.52
|
|
292
297
|
|
|
293
|
-
v3.9.52 combines operator-controlled client update notices with signed, action-bound permit verification in
|
|
298
|
+
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:
|
|
294
299
|
|
|
295
300
|
- update availability or unrecognized version metadata appears during normal authenticated runtime/status activity;
|
|
296
301
|
- messaging clearly states that hosted Marrow services are already current and that no local change was applied;
|
|
@@ -298,7 +303,7 @@ v3.9.52 combines operator-controlled client update notices with signed, action-b
|
|
|
298
303
|
- unknown versions do not imply a vulnerability, while server-designated security requirements remain distinct;
|
|
299
304
|
- existing MCP tools and older server responses remain compatible when no advisory is returned.
|
|
300
305
|
|
|
301
|
-
The
|
|
306
|
+
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:
|
|
302
307
|
|
|
303
308
|
- protected deploy, publish, merge, migration, credential, and production actions fail closed on timeout or permit failure;
|
|
304
309
|
- the permit is bound to the authenticated account, key, agent, session, action, target, canonical action surfaces, decision, and runtime gate;
|
|
@@ -307,13 +312,13 @@ The native `PreToolUse` hook verifies the permit before protected work can execu
|
|
|
307
312
|
- the bounded hook timeout prevents a control-plane wait from hanging the agent indefinitely;
|
|
308
313
|
- low-risk work retains passive/advisory behavior unless account policy requires stronger enforcement.
|
|
309
314
|
|
|
310
|
-
It preserves
|
|
315
|
+
It preserves native-hook activity diagnostics introduced in v3.9.50, with the current trust boundary applied:
|
|
311
316
|
|
|
312
|
-
- agents and owners can distinguish “MCP configured” from
|
|
317
|
+
- agents and owners can distinguish “MCP configured” from client-reported pre-action, result, and session activity without treating either as certification;
|
|
313
318
|
- `PreToolUse` requests the Marrow runtime gate before matched actions and maps `block` to deny and `review_required` to operator review;
|
|
314
319
|
- matching `PreToolUse` and result hooks share Claude Code's tool-use correlation while the session shares one workflow identity;
|
|
315
|
-
- generic integration events cannot claim native-hook coverage
|
|
316
|
-
- retries preserve correlation and
|
|
320
|
+
- generic integration events and public hook entrypoints cannot claim certified native-hook coverage;
|
|
321
|
+
- retries preserve correlation and explicitly `client_self_reported` activity in the owner-only durable spool;
|
|
317
322
|
- configuration drift can be diagnosed without sending configuration contents;
|
|
318
323
|
- missing outcome closure remains visible rather than treating tool or session exit as business success;
|
|
319
324
|
- existing MCP tools and lifecycle inputs remain compatible.
|
|
@@ -334,16 +339,16 @@ It preserves `marrow_arbitrate` from v3.9.49, the session-orientation hardening
|
|
|
334
339
|
|
|
335
340
|
Existing MCP tools and stable context API names remain compatible. Authentication, policy, proof, and validation failures are surfaced rather than retried as network failures.
|
|
336
341
|
|
|
337
|
-
|
|
342
|
+
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.
|
|
338
343
|
|
|
339
344
|
## Governed Action Flow
|
|
340
345
|
|
|
341
|
-
|
|
346
|
+
Configured hooks can provide cooperative telemetry and context, but they are not a certified execution boundary. Before deploys, merges, publishes, migrations, credential changes, financial operations, or customer-impacting work:
|
|
342
347
|
|
|
343
348
|
1. Call `marrow_agent_runtime` or `marrow_decision_brief`.
|
|
344
349
|
2. Stop when the returned decision is `block` or `review_required`; otherwise follow its prior lesson and proof contract.
|
|
345
350
|
3. Call `marrow_think` or `marrow_auto` to record intent and obtain the `decision_id` that will be closed. Keep `marrow_agent_runtime.runtime_authorization.id` separate as the gate receipt for consequential work.
|
|
346
|
-
4. Perform the action only when its gate allows it.
|
|
351
|
+
4. Perform the action only when its gate allows it. Codex, Grok, and Gemini use configured native hooks only after restart and host hook review. The governed wrapper remains an explicit bounded fallback: `npx @getmarrow/install run --agent <agent-id> -- -- <command>`.
|
|
347
352
|
5. Call `marrow_commit` with that `decision_id`, the outcome, gate receipt, and required proof.
|
|
348
353
|
|
|
349
354
|
`marrow_agent_runtime` returns `runtime_authorization` with the authoritative gate receipt. Ordinary runtime checks do not create a decision, so they omit `decision_id`; call `marrow_think` (or use `marrow_auto`) when a decision must be created and closed. An arbitration runtime that actually creates a decision returns that server-created `decision_id`. This contract is identical across MCP-compatible hosts and SDK-owned runtimes.
|
|
@@ -444,22 +449,26 @@ it does not run models, retain prompts, or infer a winner from labels.
|
|
|
444
449
|
|
|
445
450
|
## Passive Use
|
|
446
451
|
|
|
447
|
-
`npx -y --package=@getmarrow/mcp@latest marrow-mcp setup` configures supported prompt, pre-action, tool-result, and session-stop hooks. Configuration
|
|
452
|
+
`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.
|
|
448
453
|
|
|
449
454
|
### Capability and coverage contract
|
|
450
455
|
|
|
451
456
|
| Integration mode | Coverage Marrow can claim |
|
|
452
457
|
| --- | --- |
|
|
453
458
|
| MCP tools-only | On demand; covers only explicit MCP tool calls |
|
|
454
|
-
|
|
|
459
|
+
| Configured native hooks | Cooperative telemetry/context only; activity is client-self-reported and coverage remains unverified |
|
|
455
460
|
| `createPassiveRuntime().install()` | Only the owned Node process, and only while that runtime is installed and running |
|
|
456
461
|
| Governed runner | Only the command launched through the wrapper |
|
|
457
462
|
| Custom host | Requires a bounded event adapter; covers only the lifecycle events whose receipts Marrow observes |
|
|
458
463
|
|
|
459
|
-
This contract is model-neutral. A model name, host header, config file, installed hook entry,
|
|
464
|
+
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.
|
|
460
465
|
|
|
461
466
|
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.
|
|
462
467
|
|
|
468
|
+
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.
|
|
469
|
+
|
|
470
|
+
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.
|
|
471
|
+
|
|
463
472
|
Transient lifecycle receipts use a bounded owner-only spool and are retried with stable event IDs. Operators can inspect and drain it without exposing event content:
|
|
464
473
|
|
|
465
474
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
const index_1 = require("./index");
|
|
14
|
+
const control_state_1 = require("./control-state");
|
|
14
15
|
const hook_1 = require("./hook");
|
|
15
16
|
const hook_contract_1 = require("./hook-contract");
|
|
16
17
|
const hook_context_1 = require("./hook-context");
|
|
@@ -40,16 +41,16 @@ function parseArgs() {
|
|
|
40
41
|
if (args[i] === 'setup' || args[i] === '--setup') {
|
|
41
42
|
result.setup = true;
|
|
42
43
|
}
|
|
43
|
-
if (
|
|
44
|
+
if (['hook', '--hook', 'claude-hook', 'cline-hook', 'codex-hook', 'cursor-hook', 'gemini-hook', 'grok-hook', 'windsurf-hook'].includes(args[i])) {
|
|
44
45
|
result.hook = true;
|
|
45
46
|
}
|
|
46
|
-
if (
|
|
47
|
+
if (['context-hook', '--context-hook', 'claude-context-hook', 'codex-context-hook', 'grok-context-hook'].includes(args[i])) {
|
|
47
48
|
result.contextHook = true;
|
|
48
49
|
}
|
|
49
|
-
if (
|
|
50
|
+
if (['pre-action-hook', '--pre-action-hook', 'claude-pre-action-hook', 'cline-pre-action-hook', 'codex-pre-action-hook', 'cursor-pre-action-hook', 'gemini-pre-action-hook', 'grok-pre-action-hook', 'windsurf-pre-action-hook'].includes(args[i])) {
|
|
50
51
|
result.preActionHook = true;
|
|
51
52
|
}
|
|
52
|
-
if (
|
|
53
|
+
if (['session-hook', '--session-hook', 'claude-session-hook', 'cline-session-hook', 'codex-session-hook', 'cursor-session-hook', 'gemini-session-hook', 'grok-session-hook', 'windsurf-session-hook'].includes(args[i])) {
|
|
53
54
|
result.sessionHook = true;
|
|
54
55
|
}
|
|
55
56
|
if (args[i] === 'spool-status' || args[i] === '--spool-status') {
|
|
@@ -162,7 +163,7 @@ function runSetup() {
|
|
|
162
163
|
|
|
163
164
|
Use Marrow according to the capability evidence returned by the MCP server:
|
|
164
165
|
|
|
165
|
-
1. **MCP baseline is on demand:** MCP transport exposes tools; it does not provide passive hooks.
|
|
166
|
+
1. **MCP baseline is on demand:** MCP transport exposes tools; it does not provide passive hooks. Public hook callbacks and local configuration are client-self-reported activity, not certified coverage.
|
|
166
167
|
2. **Before risky actions:** Respect the returned \`allow\`, \`warn\`, \`review_required\`, or \`block\` decision and its proof contract. Call \`marrow_agent_runtime\` explicitly when verified passive coverage cannot cover the action.
|
|
167
168
|
3. **After meaningful work:** Record the real success or failure with \`marrow_commit\` or \`marrow_auto\`. A tool exit or session end is not proof that the business outcome succeeded.
|
|
168
169
|
4. **Unfinished work:** Leave pending outcomes visible. Do not invent success to clear a closure item.
|
|
@@ -172,9 +173,9 @@ Use Marrow according to the capability evidence returned by the MCP server:
|
|
|
172
173
|
|
|
173
174
|
Do not skip the gate or outcome. Marrow's value comes from controlling the action before execution and preserving evidence afterward.
|
|
174
175
|
|
|
175
|
-
Capability boundaries:
|
|
176
|
+
Capability boundaries: configured native hooks provide cooperative client-reported control and lifecycle evidence only; \`createPassiveRuntime().install()\` covers only its owned Node process while installed; a governed wrapper covers only its wrapped command; and a custom host needs a bounded event adapter. A model name, host label, API key, public hook entrypoint, installed configuration, or client-self-reported callback is not proof of coverage or enforcement. Codex, Grok, and Gemini use configured native hooks only after restart and the host's hook review; the governed wrapper remains an explicit bounded fallback.
|
|
176
177
|
|
|
177
|
-
For
|
|
178
|
+
For bounded outcome capture: \`marrow_auto({ action: "did X", outcome: "result Y", success: true })\`. One outer invocation normally completes think and commit in-band within its bounded client budget. If the host or network deadline is reached, retry with the returned \`operation_id\`; Marrow continues the same operation and never opens a second decision.
|
|
178
179
|
${MARROW_BLOCK_END}`;
|
|
179
180
|
let dir = process.cwd();
|
|
180
181
|
let claudeMdPath = null;
|
|
@@ -217,44 +218,44 @@ ${MARROW_BLOCK_END}`;
|
|
|
217
218
|
}
|
|
218
219
|
const hookInstall = (0, hook_1.installPostToolUseHook)(process.cwd());
|
|
219
220
|
if (hookInstall.installed) {
|
|
220
|
-
process.stdout.write('Configured PostToolUse hook.
|
|
221
|
+
process.stdout.write('Configured PostToolUse hook. Activity is client-self-reported and does not certify action-result coverage.\n');
|
|
221
222
|
}
|
|
222
223
|
else {
|
|
223
|
-
process.stdout.write('PostToolUse hook configuration is present.
|
|
224
|
+
process.stdout.write('PostToolUse hook configuration is present. Activity is client-self-reported and does not certify action-result coverage.\n');
|
|
224
225
|
}
|
|
225
226
|
const contextHookInstall = (0, hook_context_1.installUserPromptSubmitHook)(process.cwd());
|
|
226
227
|
if (contextHookInstall.installed) {
|
|
227
|
-
process.stdout.write('Configured UserPromptSubmit hook.
|
|
228
|
+
process.stdout.write('Configured UserPromptSubmit hook. Activity is client-self-reported and does not certify passive prompt coverage.\n');
|
|
228
229
|
}
|
|
229
230
|
else {
|
|
230
|
-
process.stdout.write('UserPromptSubmit hook configuration is present.
|
|
231
|
+
process.stdout.write('UserPromptSubmit hook configuration is present. Activity is client-self-reported and does not certify passive prompt coverage.\n');
|
|
231
232
|
}
|
|
232
233
|
const preActionHookInstall = (0, hook_pre_action_1.installPreActionHook)(process.cwd());
|
|
233
234
|
if (preActionHookInstall.installed) {
|
|
234
|
-
process.stdout.write('Configured PreToolUse hook.
|
|
235
|
+
process.stdout.write('Configured PreToolUse hook. Activity is client-self-reported and does not certify pre-action control.\n');
|
|
235
236
|
}
|
|
236
237
|
else {
|
|
237
|
-
process.stdout.write('PreToolUse hook configuration is present.
|
|
238
|
+
process.stdout.write('PreToolUse hook configuration is present. Activity is client-self-reported and does not certify pre-action control.\n');
|
|
238
239
|
}
|
|
239
240
|
const sessionHookInstall = (0, hook_session_1.installSessionEndHook)(process.cwd());
|
|
240
241
|
if (sessionHookInstall.installed) {
|
|
241
|
-
process.stdout.write('Configured Stop hook.
|
|
242
|
+
process.stdout.write('Configured Stop hook. Activity is client-self-reported and does not certify session-end coverage.\n');
|
|
242
243
|
}
|
|
243
244
|
else {
|
|
244
|
-
process.stdout.write('Stop hook configuration is present.
|
|
245
|
+
process.stdout.write('Stop hook configuration is present. Activity is client-self-reported and does not certify session-end coverage.\n');
|
|
245
246
|
}
|
|
246
247
|
const grokHookInstall = (0, hook_contract_1.installGrokNativeHooks)();
|
|
247
248
|
if (grokHookInstall.installed) {
|
|
248
|
-
process.stdout.write(`Configured Grok native hooks at ${grokHookInstall.settingsPath}.
|
|
249
|
+
process.stdout.write(`Configured Grok native pre-action, result, and nonblocking turn-closeout hooks at ${grokHookInstall.settingsPath}. Restart Grok and inspect /hooks before relying on them. Activity remains client-self-reported and does not certify observed coverage.\n`);
|
|
249
250
|
}
|
|
250
251
|
else {
|
|
251
|
-
process.stdout.write(`Grok native hook configuration is present at ${grokHookInstall.settingsPath}.
|
|
252
|
+
process.stdout.write(`Grok native hook configuration is present at ${grokHookInstall.settingsPath}. Restart Grok and inspect /hooks before relying on it. Activity remains client-self-reported and does not certify observed coverage.\n`);
|
|
252
253
|
}
|
|
253
254
|
process.stdout.write(`Hook settings: ${hookInstall.settingsPath}\n`);
|
|
254
255
|
process.stdout.write('Set MARROW_AUTO_HOOK=false to disable passive hooks.\n');
|
|
255
256
|
process.stdout.write('Set MARROW_PASSIVE_BRIEF=false to disable automatic decision briefs, or MARROW_PASSIVE_BRIEF=always to brief every prompt.\n');
|
|
256
257
|
process.stdout.write('Set MARROW_HOOK_DEBUG=true for write-side hook diagnostics, or MARROW_CONTEXT_HOOK_DEBUG=true for prompt-context diagnostics.\n');
|
|
257
|
-
process.stdout.write('Setup completed. MCP tools remain on demand;
|
|
258
|
+
process.stdout.write('Setup completed. MCP tools remain on demand; configured hook activity is client-self-reported and does not certify passive coverage or enforcement.\n');
|
|
258
259
|
process.exit(0);
|
|
259
260
|
}
|
|
260
261
|
const cliArgs = parseArgs();
|
|
@@ -534,6 +535,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
534
535
|
: null)
|
|
535
536
|
|| (0, request_reliability_1.localClientUpdate)(),
|
|
536
537
|
control_path: (0, control_path_state_1.controlPathStats)(toolName),
|
|
538
|
+
local_control: (0, control_state_1.localControlEvidence)(Boolean(API_KEY)),
|
|
537
539
|
lifecycle_spool: {
|
|
538
540
|
state: spool.failed > 0 || spool.pending > 0 ? spool.state : 'clear',
|
|
539
541
|
pending: spool.pending,
|
|
@@ -902,7 +904,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
902
904
|
},
|
|
903
905
|
{
|
|
904
906
|
name: 'marrow_run',
|
|
905
|
-
description: '
|
|
907
|
+
description: 'Governed outcome capture. Records intent, obtains a gate for risky work, and closes only with an explicit measured result.',
|
|
906
908
|
inputSchema: {
|
|
907
909
|
type: 'object',
|
|
908
910
|
properties: {
|
|
@@ -922,7 +924,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
922
924
|
},
|
|
923
925
|
{
|
|
924
926
|
name: 'marrow_auto',
|
|
925
|
-
description: 'Durably capture low-risk activity
|
|
927
|
+
description: 'Durably capture low-risk activity. One outer invocation normally completes in-band within the bounded client budget; a deadline continuation reuses the same operation_id and never opens a second decision. Outcomes remain pending unless success is explicit; risky completion still requires a fresh gate and measured proof.',
|
|
926
928
|
inputSchema: {
|
|
927
929
|
type: 'object',
|
|
928
930
|
properties: {
|
|
@@ -1771,7 +1773,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
1771
1773
|
prompts: [
|
|
1772
1774
|
{
|
|
1773
1775
|
name: 'marrow-always-on',
|
|
1774
|
-
description: 'Marrow control and proof contract
|
|
1776
|
+
description: 'Marrow control and proof contract. MCP tools are on demand; host activity is client-self-reported and coverage remains unverified without independent authority.',
|
|
1775
1777
|
arguments: [],
|
|
1776
1778
|
_meta: { host_capability: mcpHostCapability() },
|
|
1777
1779
|
},
|
|
@@ -1791,7 +1793,7 @@ if (process.argv[2] !== 'keys') {
|
|
|
1791
1793
|
}
|
|
1792
1794
|
const hostCapability = mcpHostCapability();
|
|
1793
1795
|
success(id, {
|
|
1794
|
-
description: 'Marrow control and proof contract —
|
|
1796
|
+
description: 'Marrow control and proof contract — MCP tools are on demand, host activity is client-self-reported, and coverage is unverified without independent authority',
|
|
1795
1797
|
_meta: { host_capability: hostCapability },
|
|
1796
1798
|
messages: [
|
|
1797
1799
|
{
|
|
@@ -1804,12 +1806,12 @@ if (process.argv[2] !== 'keys') {
|
|
|
1804
1806
|
|
|
1805
1807
|
${(0, host_capability_1.hostCapabilityInstructions)(hostCapability)}
|
|
1806
1808
|
|
|
1807
|
-
|
|
1809
|
+
Configured native hooks can cooperatively report or inject context for these bounded lifecycle stages, but their callbacks are client-self-reported activity and do not certify control:
|
|
1808
1810
|
- UserPromptSubmit can request relevant policy, warnings, lessons, and a decision brief before risky work.
|
|
1809
1811
|
- PostToolUse can record compact tool success or failure receipts.
|
|
1810
1812
|
- Stop can keep unfinished outcomes visible instead of silently treating session exit as success.
|
|
1811
1813
|
|
|
1812
|
-
Hooks never make a blocked action safe. Before a consequential action, respect the returned allow, warn, review_required, or block decision and its required proof.
|
|
1814
|
+
Hooks never make a blocked action safe and are not an external execution choke point. Before a consequential action, respect the returned allow, warn, review_required, or block decision and its required proof. Codex, Grok, and Gemini use configured native hooks only after restart and host hook review; the governed wrapper remains an explicit bounded fallback.
|
|
1813
1815
|
|
|
1814
1816
|
When runtime/status returns a client_update notice, tell the operator and use its exact update and verification commands only when local change policy permits. Never silently change packages or configuration.
|
|
1815
1817
|
|
|
@@ -2044,6 +2046,9 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2044
2046
|
baseUrl: BASE_URL,
|
|
2045
2047
|
deferDelivery: false,
|
|
2046
2048
|
event: {
|
|
2049
|
+
...(delivered?.operation_id ? {
|
|
2050
|
+
event_id: `auto_${delivered.committed ? 'closed' : 'pending'}_${delivered.operation_id}`,
|
|
2051
|
+
} : {}),
|
|
2047
2052
|
event_type: delivered?.committed
|
|
2048
2053
|
? 'outcome_committed'
|
|
2049
2054
|
: !highRisk && outcomeSuccess === false
|
|
@@ -2058,8 +2063,7 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2058
2063
|
action,
|
|
2059
2064
|
outcome_state: delivered?.committed ? 'closed' : 'pending',
|
|
2060
2065
|
success: delivered?.committed ? outcomeSuccess : highRisk ? undefined : outcomeSuccess,
|
|
2061
|
-
|
|
2062
|
-
capability_level: 'mcp',
|
|
2066
|
+
source: 'client_self_reported',
|
|
2063
2067
|
},
|
|
2064
2068
|
});
|
|
2065
2069
|
const response = {
|
|
@@ -2283,7 +2287,7 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2283
2287
|
}
|
|
2284
2288
|
if (toolName === 'marrow_agent_status') {
|
|
2285
2289
|
const result = await (0, index_1.marrowAgentStatus)(API_KEY, BASE_URL, args.period || '7d', args.agentId || FLEET_AGENT_ID, SESSION_ID, FLEET_AGENT_ID);
|
|
2286
|
-
success(id, { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] });
|
|
2290
|
+
success(id, { content: [{ type: 'text', text: JSON.stringify({ ...result, local_control: (0, control_state_1.localControlEvidence)(Boolean(API_KEY)) }, null, 2) }] });
|
|
2287
2291
|
return;
|
|
2288
2292
|
}
|
|
2289
2293
|
if (toolName === 'marrow_runtime_status') {
|