@getmarrow/mcp 3.9.69 → 3.9.71

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 CHANGED
@@ -104,7 +104,18 @@ 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.69
107
+ ## What's New in v3.9.71
108
+
109
+ v3.9.71 makes the advertised Grok control loop true:
110
+
111
+ - default tools include `marrow_think` so the official loop can create a `decision_id` without `MARROW_TOOL_PROFILE=full`;
112
+ - process identity prefers `MARROW_KEY_<ROLE>` when it matches `MARROW_AGENT_ID`, so a leaked fleet env cannot 403 every status call;
113
+ - Grok native hooks are installed under `~/.grok/hooks/marrow.json` and hook parsers accept Grok camelCase envelopes;
114
+ - idle spool nudge drains up to 40 current-namespace events so the queue does not sit as a nag;
115
+ - if `risk_gate.enforced` is false, the gate is advisory — do not describe it as a live block;
116
+ - `marrow_commit.decision_id` may come from `marrow_think`, `marrow_auto`, or `marrow_agent_runtime.runtime_authorization.id`.
117
+
118
+ ## Previous: v3.9.69
108
119
 
109
120
  v3.9.69 keeps the always-on spool from growing into a nag queue:
110
121
 
@@ -169,7 +180,7 @@ v3.9.62 integrates four model-neutral reliability and capability contracts:
169
180
  - `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;
170
181
  - initialize, prompt, setup, and tool responses qualify coverage by `host_capability`: MCP tools are on demand, while native hooks, an owned SDK process, a governed runner, or a custom event adapter cover only the scope proved by observed Marrow receipts.
171
182
 
172
- The default surface remains six tools 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.
183
+ 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 always-on coverage is native hooks plus MCP; it is verified only from observed receipts.
173
184
 
174
185
  ## Previous: v3.9.61
175
186
 
@@ -223,7 +234,7 @@ The compact agent control path introduced in v3.9.57 remains the default:
223
234
  - `marrow_status`, `marrow_ask`, and `marrow_agent_runtime` use authenticated routes with bounded retries and typed failures;
224
235
  - transient read failures return an owner-only last-known brief when available, while cached guidance can never authorize high-risk work;
225
236
  - normal tool errors return structured `ok`, `error_code`, `exact_fix`, `stale_brief`, and `client_update` data instead of raw MCP `fetch failed` errors;
226
- - the default agent surface is six tools: runtime, commit, ask, status, auto, and handoff status; set `MARROW_TOOL_PROFILE=full` only for legacy or advanced integrations;
237
+ - the default agent surface is seven tools: runtime, think, commit, ask, status, auto, and handoff status; set `MARROW_TOOL_PROFILE=full` only for legacy or advanced integrations;
227
238
  - risky `marrow_auto` calls obtain a fresh runtime gate automatically and cannot self-close as successful without required proof;
228
239
  - `marrow_run` requires an explicit outcome and never invents proof or a successful result;
229
240
  - the package includes an exact-version control-path canary covering every route reported in the production incident.
@@ -323,7 +334,7 @@ With installed native hooks, protected tool calls follow this automatically. For
323
334
 
324
335
  1. Call `marrow_agent_runtime` or `marrow_decision_brief`.
325
336
  2. Stop when the returned decision is `block` or `review_required`; otherwise follow its prior lesson and proof contract.
326
- 3. Call `marrow_think` to record intent and obtain the `decision_id` that will be closed.
337
+ 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` is also accepted.
327
338
  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.
328
339
  5. Call `marrow_commit` with that `decision_id`, the outcome, gate receipt, and required proof.
329
340
 
package/dist/cli.js CHANGED
@@ -12,6 +12,7 @@
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  const index_1 = require("./index");
14
14
  const hook_1 = require("./hook");
15
+ const hook_contract_1 = require("./hook-contract");
15
16
  const hook_context_1 = require("./hook-context");
16
17
  const hook_session_1 = require("./hook-session");
17
18
  const hook_pre_action_1 = require("./hook-pre-action");
@@ -20,7 +21,7 @@ const lifecycle_spool_1 = require("./lifecycle-spool");
20
21
  const spool_command_1 = require("./spool-command");
21
22
  const guidance_cache_1 = require("./guidance-cache");
22
23
  const request_reliability_1 = require("./request-reliability");
23
- const hook_contract_1 = require("./hook-contract");
24
+ const hook_contract_2 = require("./hook-contract");
24
25
  const ping_state_1 = require("./ping-state");
25
26
  const control_path_state_1 = require("./control-path-state");
26
27
  const redact_1 = require("./redact");
@@ -243,6 +244,13 @@ ${MARROW_BLOCK_END}`;
243
244
  else {
244
245
  process.stdout.write('Stop hook configuration is present. Session-end coverage remains unverified until Marrow observes session-end receipts.\n');
245
246
  }
247
+ const grokHookInstall = (0, hook_contract_1.installGrokNativeHooks)();
248
+ if (grokHookInstall.installed) {
249
+ process.stdout.write(`Configured Grok native hooks at ${grokHookInstall.settingsPath}. Coverage remains unverified until Marrow observes Grok lifecycle receipts.\n`);
250
+ }
251
+ else {
252
+ process.stdout.write(`Grok native hook configuration is present at ${grokHookInstall.settingsPath}. Coverage remains unverified until Marrow observes Grok lifecycle receipts.\n`);
253
+ }
246
254
  process.stdout.write(`Hook settings: ${hookInstall.settingsPath}\n`);
247
255
  process.stdout.write('Set MARROW_AUTO_HOOK=false to disable passive hooks.\n');
248
256
  process.stdout.write('Set MARROW_PASSIVE_BRIEF=false to disable automatic decision briefs, or MARROW_PASSIVE_BRIEF=always to brief every prompt.\n');
@@ -840,12 +848,13 @@ if (process.argv[2] !== 'keys') {
840
848
  {
841
849
  name: 'marrow_commit',
842
850
  description: 'Close a recorded action with success/failure, a specific outcome, and required proof. ' +
843
- 'Use the decision_id from marrow_think and the gate receipt from marrow_agent_runtime for consequential work. ' +
851
+ 'decision_id may come from marrow_think, marrow_auto, or marrow_agent_runtime.runtime_authorization.id. ' +
852
+ 'Use the gate receipt from marrow_agent_runtime for consequential work. ' +
844
853
  'Outcome closure is required for accountable fleet learning.',
845
854
  inputSchema: {
846
855
  type: 'object',
847
856
  properties: {
848
- decision_id: { type: 'string', description: 'decision_id from the marrow_think call' },
857
+ decision_id: { type: 'string', description: 'decision_id from marrow_think, marrow_auto, or marrow_agent_runtime.runtime_authorization.id' },
849
858
  success: { type: 'boolean', description: 'Did the action succeed?' },
850
859
  outcome: { type: 'string', description: 'What happened — be specific, this trains the hive' },
851
860
  caused_by: { type: 'string', description: 'Optional: what caused this action' },
@@ -1695,6 +1704,7 @@ if (process.argv[2] !== 'keys') {
1695
1704
  ];
1696
1705
  const CORE_TOOL_NAMES = new Set([
1697
1706
  'marrow_agent_runtime',
1707
+ 'marrow_think',
1698
1708
  'marrow_commit',
1699
1709
  'marrow_ask',
1700
1710
  'marrow_status',
@@ -1726,9 +1736,9 @@ if (process.argv[2] !== 'keys') {
1726
1736
  success(id, {
1727
1737
  protocolVersion: '2024-11-05',
1728
1738
  capabilities: { tools: {}, prompts: {} },
1729
- serverInfo: { name: 'marrow', version: hook_contract_1.MCP_ADAPTER_VERSION },
1739
+ serverInfo: { name: 'marrow', version: hook_contract_2.MCP_ADAPTER_VERSION },
1730
1740
  ...(AUTO_ENROLL ? {
1731
- instructions: `Use marrow_agent_runtime before consequential actions, obey fresh allow/warn/review_required/block results, use marrow_ask for relevant prior lessons, and close meaningful outcomes with marrow_commit. Infrastructure failures are not policy denials; continue only low-risk reversible work from the returned outage-safe brief, and require a fresh gate for high-risk work. ${(0, host_capability_1.hostCapabilityInstructions)(hostCapability)}`,
1741
+ instructions: `Call marrow_think before meaningful work to create the decision_id. Use marrow_agent_runtime before consequential actions and obey fresh allow/warn/review_required/block only when risk_gate.enforced is true; if enforced is false the gate is advisory, not a live block. Use marrow_ask for relevant prior lessons, and close outcomes with marrow_commit using that decision_id. Infrastructure failures are not policy denials; continue only low-risk reversible work from the returned outage-safe brief, and require a fresh gate for high-risk work. ${(0, host_capability_1.hostCapabilityInstructions)(hostCapability)}`,
1732
1742
  } : {}),
1733
1743
  _meta: { host_capability: hostCapability },
1734
1744
  });
@@ -2057,7 +2067,7 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
2057
2067
  action,
2058
2068
  outcome_state: delivered?.committed ? 'closed' : 'pending',
2059
2069
  success: delivered?.committed ? acceptedSuccess : highRisk ? undefined : acceptedSuccess,
2060
- adapter_version: hook_contract_1.MCP_ADAPTER_VERSION,
2070
+ adapter_version: hook_contract_2.MCP_ADAPTER_VERSION,
2061
2071
  capability_level: 'mcp',
2062
2072
  },
2063
2073
  });
@@ -2114,16 +2124,27 @@ Marrow is not a replacement agent or a standalone memory app. Context and prior
2114
2124
  cached = (0, status_cache_1.readStatusCache)({ apiKey: API_KEY, baseUrl: BASE_URL, agentId: FLEET_AGENT_ID });
2115
2125
  }
2116
2126
  catch { /* owner-only cache is best effort */ }
2117
- if (cached) {
2127
+ if (cached?.freshness === 'fresh') {
2118
2128
  const startedAt = Date.now();
2119
2129
  refreshStatusInBackground();
2120
2130
  (0, control_path_state_1.recordControlPathSample)('marrow_status', Date.now() - startedAt, true);
2121
2131
  toolSuccess(id, clientOperationalPayload('marrow_status', (0, status_cache_1.cachedStatusPayload)(cached)));
2122
2132
  return;
2123
2133
  }
2124
- const result = await withControlDeadline((signal) => (0, index_1.marrowStatus)(API_KEY, BASE_URL, SESSION_ID, FLEET_AGENT_ID, signal), { cacheAware: false, toolName: 'marrow_status' });
2125
- storeLastKnownStatus(result, 'status');
2126
- toolSuccess(id, clientOperationalPayload('marrow_status', result));
2134
+ try {
2135
+ const result = await withControlDeadline((signal) => (0, index_1.marrowStatus)(API_KEY, BASE_URL, SESSION_ID, FLEET_AGENT_ID, signal), { cacheAware: false, toolName: 'marrow_status' });
2136
+ storeLastKnownStatus(result, 'status');
2137
+ toolSuccess(id, clientOperationalPayload('marrow_status', result));
2138
+ }
2139
+ catch (error) {
2140
+ if (cached) {
2141
+ const startedAt = Date.now();
2142
+ (0, control_path_state_1.recordControlPathSample)('marrow_status', Date.now() - startedAt, false);
2143
+ toolSuccess(id, clientOperationalPayload('marrow_status', (0, status_cache_1.cachedStatusPayload)(cached)));
2144
+ return;
2145
+ }
2146
+ throw error;
2147
+ }
2127
2148
  return;
2128
2149
  }
2129
2150
  if (toolName === 'marrow_create_key') {