@getmarrow/mcp 3.9.72 → 3.9.73
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 +9 -3
- package/dist/cli.js +37 -32
- package/dist/cli.js.map +1 -1
- package/dist/hook-context.d.ts +1 -1
- package/dist/hook-contract.d.ts +6 -6
- package/dist/hook-contract.js +1 -1
- package/dist/hook-session.d.ts +1 -1
- package/dist/hook.d.ts +1 -1
- package/dist/index.d.ts +23 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +294 -44
- package/dist/index.js.map +1 -1
- package/dist/runtime-contract.d.ts +6 -0
- package/dist/runtime-contract.d.ts.map +1 -1
- package/dist/runtime-contract.js +14 -2
- package/dist/runtime-contract.js.map +1 -1
- package/package.json +1 -1
- package/scripts/control-path-canary.cjs +39 -4
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -104,7 +104,11 @@ 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.73
|
|
108
|
+
|
|
109
|
+
v3.9.73 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.
|
|
110
|
+
|
|
111
|
+
## Previous: v3.9.72
|
|
108
112
|
|
|
109
113
|
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.
|
|
110
114
|
|
|
@@ -117,7 +121,7 @@ v3.9.71 makes the advertised Grok control loop true:
|
|
|
117
121
|
- Grok native hooks are installed under `~/.grok/hooks/marrow.json` and hook parsers accept Grok camelCase envelopes;
|
|
118
122
|
- idle spool nudge drains up to 40 current-namespace events so the queue does not sit as a nag;
|
|
119
123
|
- if `risk_gate.enforced` is false, the gate is advisory — do not describe it as a live block;
|
|
120
|
-
- `marrow_commit.decision_id`
|
|
124
|
+
- `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.
|
|
121
125
|
|
|
122
126
|
## Previous: v3.9.69
|
|
123
127
|
|
|
@@ -338,12 +342,14 @@ With installed native hooks, protected tool calls follow this automatically. For
|
|
|
338
342
|
|
|
339
343
|
1. Call `marrow_agent_runtime` or `marrow_decision_brief`.
|
|
340
344
|
2. Stop when the returned decision is `block` or `review_required`; otherwise follow its prior lesson and proof contract.
|
|
341
|
-
3. Call `marrow_think` or `marrow_auto` to record intent and obtain the `decision_id` that will be closed. `marrow_agent_runtime.runtime_authorization.id`
|
|
345
|
+
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.
|
|
342
346
|
4. Perform the action only when its gate allows it. For a hard external choke point, run the command through `npx @getmarrow/install run`; it verifies the signed action permit immediately before execution.
|
|
343
347
|
5. Call `marrow_commit` with that `decision_id`, the outcome, gate receipt, and required proof.
|
|
344
348
|
|
|
345
349
|
`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.
|
|
346
350
|
|
|
351
|
+
`marrow_auto` returns an `operation_id`, phase, and resumable state. If a client deadline is reached before closure, retry with the same `operation_id`; Marrow reuses the same tenant-scoped runtime authorization, think decision, and commit idempotency keys instead of opening another decision. When the phase is `proof_required`, add the requested proof and retry with that same operation ID and unchanged action/context/surfaces. Proof is validated and bound at commit; changing the tenant or action scope is rejected. A closed response reports `phase: "closed"`, `committed: true`, and `resumable: false`.
|
|
352
|
+
|
|
347
353
|
Example pre-action request:
|
|
348
354
|
|
|
349
355
|
```json
|
package/dist/cli.js
CHANGED
|
@@ -25,7 +25,6 @@ const hook_contract_2 = require("./hook-contract");
|
|
|
25
25
|
const ping_state_1 = require("./ping-state");
|
|
26
26
|
const control_path_state_1 = require("./control-path-state");
|
|
27
27
|
const redact_1 = require("./redact");
|
|
28
|
-
const runtime_contract_1 = require("./runtime-contract");
|
|
29
28
|
const status_cache_1 = require("./status-cache");
|
|
30
29
|
const habit_loop_copy_1 = require("./habit-loop-copy");
|
|
31
30
|
const host_capability_1 = require("./host-capability");
|
|
@@ -848,13 +847,13 @@ if (process.argv[2] !== 'keys') {
|
|
|
848
847
|
{
|
|
849
848
|
name: 'marrow_commit',
|
|
850
849
|
description: 'Close a recorded action with success/failure, a specific outcome, and required proof. ' +
|
|
851
|
-
'decision_id
|
|
850
|
+
'decision_id comes from marrow_think, marrow_auto, or an arbitration runtime that actually created a decision. ' +
|
|
852
851
|
'Use the gate receipt from marrow_agent_runtime for consequential work. ' +
|
|
853
852
|
'Outcome closure is required for accountable fleet learning.',
|
|
854
853
|
inputSchema: {
|
|
855
854
|
type: 'object',
|
|
856
855
|
properties: {
|
|
857
|
-
decision_id: { type: 'string', description: 'decision_id from marrow_think, marrow_auto, or
|
|
856
|
+
decision_id: { type: 'string', description: 'decision_id from marrow_think, marrow_auto, or an arbitration runtime that created a decision' },
|
|
858
857
|
success: { type: 'boolean', description: 'Did the action succeed?' },
|
|
859
858
|
outcome: { type: 'string', description: 'What happened — be specific, this trains the hive' },
|
|
860
859
|
caused_by: { type: 'string', description: 'Optional: what caused this action' },
|
|
@@ -937,6 +936,10 @@ if (process.argv[2] !== 'keys') {
|
|
|
937
936
|
},
|
|
938
937
|
proof: { type: 'object', description: 'Measured completion evidence for gated work.' },
|
|
939
938
|
gate_receipt_id: { type: 'string', description: 'Fresh receipt returned by marrow_agent_runtime.' },
|
|
939
|
+
operation_id: {
|
|
940
|
+
type: 'string',
|
|
941
|
+
description: 'Opaque 8-80 character resume token. Reuse it only with the original tenant, action, context, and surfaces; proof may be added after proof_required.',
|
|
942
|
+
},
|
|
940
943
|
},
|
|
941
944
|
required: ['action'],
|
|
942
945
|
},
|
|
@@ -2010,35 +2013,20 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2010
2013
|
const suppliedProof = args.proof && typeof args.proof === 'object' && !Array.isArray(args.proof)
|
|
2011
2014
|
? (0, redact_1.redactSensitiveValue)(args.proof)
|
|
2012
2015
|
: undefined;
|
|
2013
|
-
let runtimeGate = null;
|
|
2014
|
-
if (highRisk) {
|
|
2015
|
-
runtimeGate = await withControlDeadline((signal) => (0, index_1.marrowAgentRuntime)(API_KEY, BASE_URL, {
|
|
2016
|
-
action: (0, redact_1.redactSensitiveText)(action),
|
|
2017
|
-
type,
|
|
2018
|
-
agent_id: FLEET_AGENT_ID,
|
|
2019
|
-
session_id: SESSION_ID,
|
|
2020
|
-
proof: suppliedProof,
|
|
2021
|
-
context: { source: 'mcp_auto_risk_upgrade' },
|
|
2022
|
-
}, SESSION_ID, FLEET_AGENT_ID, signal), { highRisk: true, toolName: 'marrow_auto.runtime' });
|
|
2023
|
-
storeRuntimeGuidance(runtimeGate);
|
|
2024
|
-
}
|
|
2025
|
-
const canonicalRuntimeReceiptId = (0, runtime_contract_1.runtimeAuthorizationReceiptId)(runtimeGate);
|
|
2026
2016
|
const suppliedRuntimeReceiptId = typeof args.gate_receipt_id === 'string'
|
|
2027
2017
|
? args.gate_receipt_id
|
|
2028
|
-
:
|
|
2029
|
-
const proofCanClose = !highRisk
|
|
2030
|
-
|| (0, runtime_contract_1.highRiskRuntimeCanClose)(runtimeGate, suppliedProof, suppliedRuntimeReceiptId);
|
|
2031
|
-
const acceptedSuccess = proofCanClose ? outcomeSuccess : undefined;
|
|
2018
|
+
: undefined;
|
|
2032
2019
|
const delivery = () => (0, index_1.marrowAuto)(API_KEY, BASE_URL, {
|
|
2033
2020
|
action,
|
|
2034
2021
|
outcome,
|
|
2035
|
-
success:
|
|
2022
|
+
success: outcomeSuccess,
|
|
2036
2023
|
type,
|
|
2037
2024
|
proof: suppliedProof,
|
|
2038
2025
|
gate_receipt_id: suppliedRuntimeReceiptId || undefined,
|
|
2039
2026
|
// Low-risk one-shot capture does not need a policy gate. Consequential
|
|
2040
|
-
// work
|
|
2027
|
+
// work obtains exactly one canonical runtime authorization inside auto.
|
|
2041
2028
|
auto_gate: highRisk,
|
|
2029
|
+
operation_id: typeof args.operation_id === 'string' ? args.operation_id : undefined,
|
|
2042
2030
|
}, SESSION_ID, FLEET_AGENT_ID, 8_000);
|
|
2043
2031
|
let delivered = null;
|
|
2044
2032
|
let deliveryFailure = null;
|
|
@@ -2048,6 +2036,9 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2048
2036
|
catch (err) {
|
|
2049
2037
|
deliveryFailure = (0, request_reliability_1.structuredRequestFailure)(err);
|
|
2050
2038
|
}
|
|
2039
|
+
const runtimeGate = delivered?.runtime_gate || null;
|
|
2040
|
+
if (runtimeGate)
|
|
2041
|
+
storeRuntimeGuidance(runtimeGate);
|
|
2051
2042
|
const receipt = await (0, lifecycle_spool_1.recordLifecycleEvent)({
|
|
2052
2043
|
apiKey: API_KEY,
|
|
2053
2044
|
baseUrl: BASE_URL,
|
|
@@ -2055,18 +2046,18 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2055
2046
|
event: {
|
|
2056
2047
|
event_type: delivered?.committed
|
|
2057
2048
|
? 'outcome_committed'
|
|
2058
|
-
: !highRisk &&
|
|
2049
|
+
: !highRisk && outcomeSuccess === false
|
|
2059
2050
|
? 'tool_failed'
|
|
2060
|
-
: !highRisk &&
|
|
2051
|
+
: !highRisk && outcomeSuccess === true
|
|
2061
2052
|
? 'tool_completed'
|
|
2062
2053
|
: 'goal_started',
|
|
2063
2054
|
harness: process.env.MARROW_CLIENT || process.env.MARROW_HARNESS || 'mcp',
|
|
2064
2055
|
agent_id: FLEET_AGENT_ID,
|
|
2065
2056
|
session_id: SESSION_ID,
|
|
2066
|
-
decision_id: delivered?.decision_id,
|
|
2057
|
+
decision_id: delivered?.decision_id || undefined,
|
|
2067
2058
|
action,
|
|
2068
2059
|
outcome_state: delivered?.committed ? 'closed' : 'pending',
|
|
2069
|
-
success: delivered?.committed ?
|
|
2060
|
+
success: delivered?.committed ? outcomeSuccess : highRisk ? undefined : outcomeSuccess,
|
|
2070
2061
|
adapter_version: hook_contract_2.MCP_ADAPTER_VERSION,
|
|
2071
2062
|
capability_level: 'mcp',
|
|
2072
2063
|
},
|
|
@@ -2077,20 +2068,34 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
|
|
|
2077
2068
|
warnings: cachedOrientWarnings.map(formatWarningActionably),
|
|
2078
2069
|
logging: delivered?.committed
|
|
2079
2070
|
? 'governed_commit_confirmed'
|
|
2080
|
-
: delivered
|
|
2081
|
-
? '
|
|
2082
|
-
:
|
|
2071
|
+
: delivered?.resumable
|
|
2072
|
+
? 'resume_required'
|
|
2073
|
+
: delivered
|
|
2074
|
+
? 'intent_confirmed'
|
|
2075
|
+
: 'durably_queued',
|
|
2083
2076
|
receipt,
|
|
2084
2077
|
completion_state: delivered?.committed
|
|
2085
2078
|
? 'closed_with_proof'
|
|
2086
|
-
:
|
|
2079
|
+
: delivered?.phase === 'proof_required'
|
|
2087
2080
|
? 'pending_required_proof'
|
|
2088
|
-
: outcomeSuccess === undefined
|
|
2081
|
+
: delivered?.phase === 'decision_created' || outcomeSuccess === undefined
|
|
2089
2082
|
? 'pending_evidence'
|
|
2090
2083
|
: 'delivery_pending',
|
|
2091
2084
|
decision_id: delivered?.decision_id || null,
|
|
2085
|
+
operation_id: delivered?.operation_id || (typeof args.operation_id === 'string' ? args.operation_id : null),
|
|
2086
|
+
phase: delivered?.phase || null,
|
|
2087
|
+
resumable: delivered?.resumable || false,
|
|
2088
|
+
retry_after_ms: delivered?.retry_after_ms ?? null,
|
|
2089
|
+
phase_timings_ms: delivered?.phase_timings_ms || null,
|
|
2090
|
+
exact_next_action: delivered?.committed
|
|
2091
|
+
? 'The governed outcome is closed. Reuse this decision_id only for read-only trace inspection.'
|
|
2092
|
+
: delivered?.phase === 'proof_required'
|
|
2093
|
+
? 'Attach the required measured proof and retry marrow_auto with this same operation_id and unchanged action, context, and surfaces.'
|
|
2094
|
+
: delivered?.resumable
|
|
2095
|
+
? 'Retry marrow_auto with this same operation_id. Do not start a new auto operation.'
|
|
2096
|
+
: 'Close this decision after the real outcome is known.',
|
|
2092
2097
|
live_delivery: {
|
|
2093
|
-
accepted: Boolean(delivered),
|
|
2098
|
+
accepted: Boolean(delivered?.decision_id),
|
|
2094
2099
|
committed: Boolean(delivered?.committed),
|
|
2095
2100
|
...(deliveryFailure ? { failure: deliveryFailure } : {}),
|
|
2096
2101
|
},
|