@getmarrow/mcp 3.9.102 → 3.9.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +49 -23
  2. package/dist/cli.js +41 -10
  3. package/dist/cli.js.map +1 -1
  4. package/dist/codex-plugin-pins.d.ts +19 -0
  5. package/dist/codex-plugin-pins.d.ts.map +1 -0
  6. package/dist/codex-plugin-pins.js +43 -0
  7. package/dist/codex-plugin-pins.js.map +1 -0
  8. package/dist/codex-plugins.d.ts +34 -0
  9. package/dist/codex-plugins.d.ts.map +1 -0
  10. package/dist/codex-plugins.js +240 -0
  11. package/dist/codex-plugins.js.map +1 -0
  12. package/dist/hook-contract.d.ts +2 -2
  13. package/dist/hook-contract.d.ts.map +1 -1
  14. package/dist/hook-contract.js +8 -3
  15. package/dist/hook-contract.js.map +1 -1
  16. package/dist/hook-pre-action.d.ts +48 -2
  17. package/dist/hook-pre-action.d.ts.map +1 -1
  18. package/dist/hook-pre-action.js +195 -22
  19. package/dist/hook-pre-action.js.map +1 -1
  20. package/dist/hook.d.ts +1 -1
  21. package/dist/hook.d.ts.map +1 -1
  22. package/dist/hook.js +12 -6
  23. package/dist/hook.js.map +1 -1
  24. package/dist/host-session.d.ts +11 -0
  25. package/dist/host-session.d.ts.map +1 -1
  26. package/dist/host-session.js +49 -0
  27. package/dist/host-session.js.map +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +15 -10
  30. package/dist/index.js.map +1 -1
  31. package/dist/normalized-action.d.ts +29 -6
  32. package/dist/normalized-action.d.ts.map +1 -1
  33. package/dist/normalized-action.js +492 -102
  34. package/dist/normalized-action.js.map +1 -1
  35. package/dist/own-server-identity.d.ts +123 -0
  36. package/dist/own-server-identity.d.ts.map +1 -0
  37. package/dist/own-server-identity.js +1052 -0
  38. package/dist/own-server-identity.js.map +1 -0
  39. package/dist/own-tool.d.ts +7 -3
  40. package/dist/own-tool.d.ts.map +1 -1
  41. package/dist/own-tool.js +7 -3
  42. package/dist/own-tool.js.map +1 -1
  43. package/dist/redact.d.ts +23 -0
  44. package/dist/redact.d.ts.map +1 -1
  45. package/dist/redact.js +181 -8
  46. package/dist/redact.js.map +1 -1
  47. package/dist/seatbelt/classifier-pin.d.ts +15 -0
  48. package/dist/seatbelt/classifier-pin.d.ts.map +1 -0
  49. package/dist/seatbelt/classifier-pin.js +26 -0
  50. package/dist/seatbelt/classifier-pin.js.map +1 -0
  51. package/dist/seatbelt/guards.d.ts +10 -0
  52. package/dist/seatbelt/guards.d.ts.map +1 -0
  53. package/dist/seatbelt/guards.js +509 -0
  54. package/dist/seatbelt/guards.js.map +1 -0
  55. package/dist/seatbelt/hook.d.ts +72 -0
  56. package/dist/seatbelt/hook.d.ts.map +1 -0
  57. package/dist/seatbelt/hook.js +362 -0
  58. package/dist/seatbelt/hook.js.map +1 -0
  59. package/dist/seatbelt/longopts.d.ts +68 -0
  60. package/dist/seatbelt/longopts.d.ts.map +1 -0
  61. package/dist/seatbelt/longopts.js +377 -0
  62. package/dist/seatbelt/longopts.js.map +1 -0
  63. package/dist/seatbelt/mapper.d.ts +83 -0
  64. package/dist/seatbelt/mapper.d.ts.map +1 -0
  65. package/dist/seatbelt/mapper.js +10248 -0
  66. package/dist/seatbelt/mapper.js.map +1 -0
  67. package/dist/seatbelt/record.d.ts +94 -0
  68. package/dist/seatbelt/record.d.ts.map +1 -0
  69. package/dist/seatbelt/record.js +776 -0
  70. package/dist/seatbelt/record.js.map +1 -0
  71. package/dist/seatbelt/tables.d.ts +82 -0
  72. package/dist/seatbelt/tables.d.ts.map +1 -0
  73. package/dist/seatbelt/tables.js +359 -0
  74. package/dist/seatbelt/tables.js.map +1 -0
  75. package/dist/seatbelt-deploy.d.ts +100 -0
  76. package/dist/seatbelt-deploy.d.ts.map +1 -0
  77. package/dist/seatbelt-deploy.js +393 -0
  78. package/dist/seatbelt-deploy.js.map +1 -0
  79. package/dist/seatbelt-fs.d.ts +30 -0
  80. package/dist/seatbelt-fs.d.ts.map +1 -0
  81. package/dist/seatbelt-fs.js +94 -0
  82. package/dist/seatbelt-fs.js.map +1 -0
  83. package/dist/seatbelt-git.d.ts +212 -0
  84. package/dist/seatbelt-git.d.ts.map +1 -0
  85. package/dist/seatbelt-git.js +844 -0
  86. package/dist/seatbelt-git.js.map +1 -0
  87. package/dist/seatbelt-mode.d.ts +77 -0
  88. package/dist/seatbelt-mode.d.ts.map +1 -0
  89. package/dist/seatbelt-mode.js +496 -0
  90. package/dist/seatbelt-mode.js.map +1 -0
  91. package/dist/seatbelt-path.d.ts +123 -0
  92. package/dist/seatbelt-path.d.ts.map +1 -0
  93. package/dist/seatbelt-path.js +482 -0
  94. package/dist/seatbelt-path.js.map +1 -0
  95. package/dist/seatbelt-scripts.d.ts +109 -0
  96. package/dist/seatbelt-scripts.d.ts.map +1 -0
  97. package/dist/seatbelt-scripts.js +1060 -0
  98. package/dist/seatbelt-scripts.js.map +1 -0
  99. package/dist/tool-catalog.js +2 -2
  100. package/dist/tool-catalog.js.map +1 -1
  101. package/dist/types.d.ts +2 -1
  102. package/dist/types.d.ts.map +1 -1
  103. package/package.json +2 -1
  104. package/server.json +3 -3
  105. package/vendor/classifier/MANIFEST.json +25 -0
  106. package/vendor/classifier/classifier.js +1356 -0
  107. package/vendor/classifier/policy-baseline.js +187 -0
  108. package/vendor/classifier/redact.js +59 -0
  109. package/vendor/classifier/shell-parse.js +455 -0
@@ -1 +1 @@
1
- {"version":3,"file":"hook-pre-action.d.ts","sourceRoot":"","sources":["../src/hook-pre-action.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-pre-action.d.ts","sourceRoot":"","sources":["../src/hook-pre-action.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DENIED_DECISION_CLOSE_TIMEOUT_MS = exports.GROK_FIXED_DENIAL = exports.HELD_SLOW_TEXT = exports.HOLD_OWNER_DENIAL = exports.PreActionControlTimeoutError = exports.PRE_ACTION_CONTROL_TIMEOUT_MS = exports.MAX_PRE_ACTION_INPUT_BYTES = exports.MARROW_OUTAGE_WARNING = exports.NO_KEY_TEXT = void 0;
3
+ exports.DENIED_DECISION_CLOSE_TIMEOUT_MS = exports.SEATBELT_CURSOR_ASK_AGENT_TEXT = exports.SEATBELT_CURSOR_ASK_USER_TEXT = exports.SEATBELT_HELD_TEXT = exports.GROK_FIXED_DENIAL = exports.HELD_OFFLINE_TEXT = exports.HELD_SLOW_TEXT = exports.HOLD_OWNER_DENIAL = exports.PreActionControlTimeoutError = exports.PRE_ACTION_CONTROL_TIMEOUT_MS = exports.MAX_PRE_ACTION_INPUT_BYTES = exports.MARROW_OUTAGE_WARNING = exports.SETUP_UNCONFIRMED_TEXT = exports.CLAIMED_NO_KEY_TEXT = exports.NO_KEY_TEXT = void 0;
4
4
  exports.isMarrowControlTimeout = isMarrowControlTimeout;
5
5
  exports.isMarrowControlOutage = isMarrowControlOutage;
6
6
  exports.heldActionHookOutput = heldActionHookOutput;
@@ -16,6 +16,7 @@ exports.advisoryGateNotice = advisoryGateNotice;
16
16
  exports.runtimeGateVerdict = runtimeGateVerdict;
17
17
  exports.gateDecisionMessage = gateDecisionMessage;
18
18
  exports.localControlAllowOutput = localControlAllowOutput;
19
+ exports.seatbeltPassOutput = seatbeltPassOutput;
19
20
  exports.localLoopGuardDenyOutput = localLoopGuardDenyOutput;
20
21
  exports.classifyTool = classifyTool;
21
22
  exports.cursorPreActionHookOutput = cursorPreActionHookOutput;
@@ -27,6 +28,7 @@ exports.preActionHookOutput = preActionHookOutput;
27
28
  exports.closeDeniedDecision = closeDeniedDecision;
28
29
  exports.localApprovalCategories = localApprovalCategories;
29
30
  exports.installPreActionHook = installPreActionHook;
31
+ exports.outageHolds = outageHolds;
30
32
  exports.runPreActionHookCommand = runPreActionHookCommand;
31
33
  const node_crypto_1 = require("node:crypto");
32
34
  const index_1 = require("./index");
@@ -36,6 +38,7 @@ const control_state_1 = require("./control-state");
36
38
  const runtime_contract_1 = require("./runtime-contract");
37
39
  const host_approval_1 = require("./host-approval");
38
40
  const host_session_1 = require("./host-session");
41
+ const own_server_identity_1 = require("./own-server-identity");
39
42
  const normalized_action_1 = require("./normalized-action");
40
43
  const session_loop_guard_1 = require("./session-loop-guard");
41
44
  const hook_tool_policy_1 = require("./hook-tool-policy");
@@ -43,6 +46,12 @@ const hook_contract_1 = require("./hook-contract");
43
46
  Object.defineProperty(exports, "MARROW_OUTAGE_WARNING", { enumerable: true, get: function () { return hook_contract_1.MARROW_OUTAGE_WARNING; } });
44
47
  /** A protected action with no Marrow key anywhere this machine keeps one (MARROW_API_KEY, ~/.marrow/env.local or ~/.marrow/env, owner-only). */
45
48
  exports.NO_KEY_TEXT = 'Marrow has no API key on this machine. Owner: create one at getmarrow.ai/signup, then run the installer activate command in a terminal. Do not retry this action.';
49
+ /** Seatbelt mode `claimed_no_key` (spec §1.1): account evidence on the machine but no usable key. Same text as src/seatbelt/hook.ts. */
50
+ exports.CLAIMED_NO_KEY_TEXT = 'Marrow is linked to an account but has no working key; owner: run `npx -y @getmarrow/install@latest doctor`.';
51
+ /** `claimed_no_key` without account evidence (a mode fallback): the same holds, never an account claim. Same text as src/seatbelt/hook.ts. */
52
+ exports.SETUP_UNCONFIRMED_TEXT = 'Marrow has no working key on this machine and its keyless mode is off here (strict mode, or a home folder it cannot trust); owner: run `npx -y @getmarrow/install@latest doctor`.';
53
+ /** The seatbelt path itself could not run (its modules did not load): a stop (spec §2.1.4). */
54
+ const SEATBELT_FAILED_TEXT = 'MARROW SEATBELT stopped this action: a safety check that could not finish (U5.fail_closed, hook_error). This needs the machine owner. Do not retry it another way or edit Marrow settings.';
46
55
  // Claude Code sends the whole tool input, and a Write of a long document grows
47
56
  // further once JSON-escaped, so tens of kilobytes of markdown must still parse.
48
57
  exports.MAX_PRE_ACTION_INPUT_BYTES = 4 * 1024 * 1024;
@@ -107,6 +116,8 @@ function isMarrowControlOutage(error) {
107
116
  exports.HOLD_OWNER_DENIAL = 'Marrow is holding this action for approval. Retry it after approval.';
108
117
  /** Marrow did not answer within the hook's time limit: an action that can be held stays held. */
109
118
  exports.HELD_SLOW_TEXT = 'Marrow did not answer in time, so this action is held. Retry it in a moment.';
119
+ /** Marrow cannot be reached (a real outage): a high-risk action fails closed; routine actions keep the outage allow. */
120
+ exports.HELD_OFFLINE_TEXT = 'Marrow cannot be reached right now, so this high-risk action is held; routine actions keep running. Retry it when Marrow is back.';
110
121
  /** The only denial @getmarrow/install's Grok guard passes through (any other output blocks with a launch failure). */
111
122
  exports.GROK_FIXED_DENIAL = 'Marrow blocked this protected action.';
112
123
  /**
@@ -231,7 +242,7 @@ function plainControlFix(error) {
231
242
  }
232
243
  // Names a reached control failure by HTTP status and stable failure code, with a plain
233
244
  // fix (see plainControlFix); private service text is never echoed into the agent transcript.
234
- function controlRejectionMessage(error, agentId) {
245
+ function controlRejectionMessage(error, agentId, kind = controlFailureKind(error)) {
235
246
  const detail = [];
236
247
  if (error instanceof request_reliability_1.MarrowRequestError) {
237
248
  if (typeof error.status === 'number' && Number.isInteger(error.status))
@@ -241,7 +252,6 @@ function controlRejectionMessage(error, agentId) {
241
252
  detail.push(code);
242
253
  }
243
254
  const suffix = detail.length ? ` (${detail.join(' ')})` : '';
244
- const kind = controlFailureKind(error);
245
255
  if (kind === 'credential_scope') {
246
256
  const agent = agentId && SAFE_AGENT_ID.test(agentId)
247
257
  ? `agent "${agentId}"`
@@ -410,6 +420,46 @@ function localControlAllowOutput(harness) {
410
420
  return { decision: 'allow' };
411
421
  return {};
412
422
  }
423
+ /** The Cursor events where Cursor enforces "ask" with its own approval prompt (the installer's execution hooks). */
424
+ const CURSOR_ASK_EVENTS = new Set(['beforeShellExecution', 'beforeMCPExecution']);
425
+ /** Keyless seatbelt: a host that cannot hand this action to its own approval prompt holds it (no account to approve it). */
426
+ exports.SEATBELT_HELD_TEXT = 'MARROW SEATBELT held this action: this host cannot hand it to its own approval prompt here, and no Marrow account is linked to approve it. This needs the machine owner. Do not retry it another way or edit Marrow settings. Tell the owner: run it yourself in your own terminal, or link a Marrow account with "npx -y @getmarrow/install@latest activate" (it needs MARROW_API_KEY set first) so these become approval prompts.';
427
+ exports.SEATBELT_CURSOR_ASK_USER_TEXT = 'Marrow seatbelt (no account linked): approve this action here only if you expected it.';
428
+ exports.SEATBELT_CURSOR_ASK_AGENT_TEXT = 'Cursor is asking the user to approve this action (Marrow seatbelt, no account linked). Wait for the answer; do not retry it another way.';
429
+ /**
430
+ * The keyless seatbelt's answer for an action it does not stop (spec §1.3 "pass": Marrow adds no
431
+ * decision and the host's own permission flow runs). `heldBefore`: the 3.9.103 keyless hook held this
432
+ * action (protected, or not read-only on Windsurf, Gemini or Grok). `null` means exit 0, no output.
433
+ * - Not held before: exactly the answer 3.9.103 gave (its read-only and unprotected passes).
434
+ * - Held before: never an explicit allow that could skip the host's own approval step.
435
+ * Claude Code and Codex `{}` (no permissionDecision), Cline `{cancel:false}`, Windsurf no output:
436
+ * the hosts' neutral answers (see PASS_THROUGH_HOSTS), so their own approval step runs.
437
+ * Gemini CLI `{"decision":"allow"}`: the installed guard passes only that or a fixed denial (no
438
+ * output is a launch failure that blocks), and Gemini applies its own policy and confirmation
439
+ * after the BeforeTool hook whatever an "allow" says, so it is Gemini's neutral answer.
440
+ * Cursor beforeShellExecution / beforeMCPExecution: "ask", so Cursor's own approval prompt decides.
441
+ * Cursor preToolUse (no neutral answer, "ask" not enforced) and Grok (its guard passes only an
442
+ * explicit allow or the fixed denial, and nothing shows an allow keeps Grok's own approval): held,
443
+ * as 3.9.103 did. Any other or missing Cursor event name is treated as preToolUse.
444
+ */
445
+ function seatbeltPassOutput(harness, hookEventName, heldBefore) {
446
+ if (!heldBefore)
447
+ return localControlAllowOutput(harness);
448
+ if (harness === 'windsurf')
449
+ return null;
450
+ if (harness === 'cline')
451
+ return { cancel: false };
452
+ if (harness === 'gemini')
453
+ return { decision: 'allow' };
454
+ if (harness === 'grok')
455
+ return { decision: 'deny', reason: exports.GROK_FIXED_DENIAL };
456
+ if (harness === 'cursor') {
457
+ return typeof hookEventName === 'string' && CURSOR_ASK_EVENTS.has(hookEventName)
458
+ ? { permission: 'ask', user_message: exports.SEATBELT_CURSOR_ASK_USER_TEXT, agent_message: exports.SEATBELT_CURSOR_ASK_AGENT_TEXT }
459
+ : { permission: 'deny', user_message: exports.SEATBELT_HELD_TEXT, agent_message: exports.SEATBELT_HELD_TEXT };
460
+ }
461
+ return {};
462
+ }
413
463
  function localLoopGuardDenyOutput(harness, reason) {
414
464
  const bounded = reason.replace(/[\u0000-\u001f\u007f]/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 500);
415
465
  if (harness === 'windsurf')
@@ -418,7 +468,10 @@ function localLoopGuardDenyOutput(harness, reason) {
418
468
  return { permission: 'deny', user_message: bounded, agent_message: bounded };
419
469
  if (harness === 'cline')
420
470
  return { cancel: true, errorMessage: bounded };
421
- if (harness === 'gemini' || harness === 'grok')
471
+ // The installed Grok guard passes only an allow or this fixed denial; any other text is its launch failure (audit M1).
472
+ if (harness === 'grok')
473
+ return { decision: 'deny', reason: exports.GROK_FIXED_DENIAL };
474
+ if (harness === 'gemini')
422
475
  return { decision: 'deny', reason: bounded };
423
476
  return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: bounded } };
424
477
  }
@@ -456,7 +509,13 @@ function localControlDisabled() {
456
509
  return false;
457
510
  }
458
511
  }
459
- function classifyTool(event) {
512
+ /**
513
+ * `ownUnproven`: the label is one of Marrow's own, but the host's server
514
+ * identity check did not prove the official server (Codex, Cursor). Such a
515
+ * call is classified as a protected MCP tool of another server, never
516
+ * read-only (it imitates Marrow's names, so a read verb proves nothing).
517
+ */
518
+ function classifyTool(event, options = {}) {
460
519
  const tool = String(event.tool_name || 'tool').slice(0, 64);
461
520
  const normalizedTool = (0, hook_tool_policy_1.normalizeHookToolName)(tool);
462
521
  // Editing and task tools are judged by their target; shell-like words in the
@@ -464,7 +523,8 @@ function classifyTool(event) {
464
523
  const shellGoverned = (0, hook_tool_policy_1.isShellGovernedTool)(event);
465
524
  const command = shellGoverned ? (0, hook_tool_policy_1.hookToolCommand)(event) : '';
466
525
  const input = (0, hook_tool_policy_1.toolClassificationText)(event).toLowerCase();
467
- const readOnly = (0, hook_tool_policy_1.isReadOnlyToolEvent)(event);
526
+ // A look-alike of Marrow's own tool is never read-only, whatever its verb.
527
+ const readOnly = options.ownUnproven !== true && (0, hook_tool_policy_1.isReadOnlyToolEvent)(event);
468
528
  const secretAccess = (0, hook_tool_policy_1.isSecretMaterialAccess)(event);
469
529
  const protectedShellCommand = shellGoverned && (0, hook_tool_policy_1.isProtectedShellMutation)(command);
470
530
  const infrastructureDeployment = /\b(?:kubectl|terraform|pulumi|helm)\b/.test(command.toLowerCase())
@@ -493,7 +553,7 @@ function classifyTool(event) {
493
553
  const protectedAction = !readOnly && (secretAccess
494
554
  || (shellGoverned && /\b(?:deploy|release|publish|git\s+push|git\s+merge|gh\s+pr\s+merge|migration|migrate|secret|credential|rotate|revoke|payment|refund|charge|invoice|production|prod)\b/.test(input))
495
555
  || protectedShellCommand
496
- || ((0, hook_tool_policy_1.isMcpHookTool)(event.tool_name) && !(0, hook_tool_policy_1.isOfficialMarrowMcpTool)(event.tool_name))
556
+ || ((0, hook_tool_policy_1.isMcpHookTool)(event.tool_name) && (options.ownUnproven === true || !(0, hook_tool_policy_1.isOfficialMarrowMcpTool)(event.tool_name)))
497
557
  || (['use_mcp_tool', 'use_tool'].includes(normalizedTool) && !(0, hook_tool_policy_1.isOfficialMarrowMcpEvent)(event)));
498
558
  const risk = readOnly ? 'low' : protectedAction ? 'high' : 'medium';
499
559
  const target = surfaces.includes('npm') ? `npm:${type}`
@@ -548,11 +608,12 @@ function clinePreActionHookOutput(result) {
548
608
  };
549
609
  }
550
610
  if (result.protectedRisk && (!result.runtime || !result.permit?.verified)) {
551
- const credentialsUnavailable = result.enforcementError === exports.NO_KEY_TEXT;
611
+ const credentialsUnavailable = result.enforcementError === exports.NO_KEY_TEXT || result.enforcementError === exports.CLAIMED_NO_KEY_TEXT
612
+ || result.enforcementError === exports.SETUP_UNCONFIRMED_TEXT;
552
613
  return {
553
614
  cancel: true,
554
615
  errorMessage: credentialsUnavailable
555
- ? exports.NO_KEY_TEXT
616
+ ? result.enforcementError
556
617
  : result.failure === 'credential_scope'
557
618
  ? 'This Marrow API key is not authorized to obtain action permits for this agent. Use the API key issued to this agent and retry.'
558
619
  : result.failure === 'unavailable'
@@ -828,11 +889,54 @@ function installPreActionHook(startDir = process.cwd()) {
828
889
  fs.writeFileSync(path, JSON.stringify(settings, null, 2) + '\n');
829
890
  return { settingsPath: path, installed: reconciled.changed };
830
891
  }
892
+ /**
893
+ * I3: whether a real outage (the gate never answered) holds this action. Never looser than master,
894
+ * which allowed every action in an outage. A shell command is read by the seatbelt mapper: held for an
895
+ * S0-S5/S-x hit or a program on the outage list (git push, publish, deploy, remote delete), allowed
896
+ * when the mapper read all of it and found neither (words in a message, a path or a comment never hold
897
+ * it). Anything else, or a mapper that could not finish, keeps `classifiedHighRisk` (F2).
898
+ */
899
+ function outageHolds(classifiedHighRisk, read) {
900
+ let reading = { shell: false, risk: 'unknown' };
901
+ try {
902
+ reading = read();
903
+ }
904
+ catch { /* unknown: the classifier's answer */ }
905
+ if (reading.risk === 'high')
906
+ return true;
907
+ if (reading.shell && reading.risk === 'not_high')
908
+ return false;
909
+ return classifiedHighRisk;
910
+ }
911
+ function seatbeltEvent(source, rawEvent) {
912
+ const raw = asRecord(rawEvent) || {};
913
+ const event = source;
914
+ return {
915
+ tool_name: source.tool_name, tool_input: source.tool_input, cwd: event.cwd ?? raw.cwd, truncated: event.input_truncated === true,
916
+ session: source.session_id || source.conversation_id || source.task_id || undefined,
917
+ };
918
+ }
831
919
  async function runPreActionHookCommand(input) {
920
+ // Account mode: the S0-S5 floor in watch runs after the answer is written, for the record only.
921
+ const watch = {};
922
+ try {
923
+ await runPreActionHook(input, watch);
924
+ }
925
+ finally {
926
+ if (watch.harness && watch.event) {
927
+ try {
928
+ require('./seatbelt/hook').accountFloor(watch.harness, watch.event, (0, host_approval_1.preToolDeadline)((0, host_approval_1.approvalHostFor)(watch.harness)));
929
+ }
930
+ catch { /* watch never changes the answer */ }
931
+ }
932
+ }
933
+ }
934
+ async function runPreActionHook(input, watch) {
832
935
  if (process.env.MARROW_AUTO_HOOK === 'false')
833
936
  return;
834
937
  const identity = (0, hook_contract_1.resolveNativeHookIdentity)(process.argv[2]);
835
938
  let event = input;
939
+ let rawEvent = input;
836
940
  let inputFailure = null;
837
941
  if (event === undefined) {
838
942
  try {
@@ -842,7 +946,8 @@ async function runPreActionHookCommand(input) {
842
946
  }
843
947
  else {
844
948
  const raw = stdin.raw.trim();
845
- event = raw ? (0, hook_contract_1.normalizeHookEventPayload)(JSON.parse(raw)) : {};
949
+ rawEvent = raw ? JSON.parse(raw) : {};
950
+ event = (0, hook_contract_1.normalizeHookEventPayload)(rawEvent);
846
951
  }
847
952
  }
848
953
  catch {
@@ -865,7 +970,7 @@ async function runPreActionHookCommand(input) {
865
970
  emitDecision({ runtime: null, permit: null, protectedRisk: true, enforcementError: inputFailure || 'Marrow could not classify this mutation-capable tool request.' }, identity.harness);
866
971
  return;
867
972
  }
868
- if ((0, hook_tool_policy_1.isOfficialMarrowMcpEvent)(source)) {
973
+ if ((0, own_server_identity_1.isOfficialMarrowMcpEventOnHost)(identity.harness, source, rawEvent)) {
869
974
  if (identity.harness === 'windsurf') {
870
975
  process.exitCode = 0;
871
976
  return;
@@ -876,7 +981,7 @@ async function runPreActionHookCommand(input) {
876
981
  : {}));
877
982
  return;
878
983
  }
879
- const classified = classifyTool(source);
984
+ const classified = classifyTool(source, { ownUnproven: (0, hook_tool_policy_1.isOfficialMarrowMcpEvent)(source) });
880
985
  let localControl;
881
986
  try {
882
987
  localControl = (0, control_state_1.readLocalControlState)();
@@ -962,6 +1067,55 @@ async function runPreActionHookCommand(input) {
962
1067
  emitLoopGuardDenial(identity.harness, loopDecision.reason || `Marrow local loop guard blocked this unchanged repeat. Receipt: ${loopDecision.receipt}.`);
963
1068
  return;
964
1069
  }
1070
+ // No usable key: the seatbelt decides first (spec §1.1), before the read-only pass so S4 reads stop.
1071
+ // `seatbelt` answers here with no network call; `claimed_no_key` stops S0-S5 here and keeps the holds below.
1072
+ // Whether a keyless hold may say "linked to an account" (only with account evidence, never for a mode fallback).
1073
+ let keylessAccountLinked = false;
1074
+ // The keyless hold text when the seatbelt does not answer: master's no-key text in seatbelt mode (a
1075
+ // tool the mapper does not recognise, audit H1), the claimed_no_key texts otherwise.
1076
+ let keylessSeatbeltMode = false;
1077
+ if (!resolved.apiKey) {
1078
+ let keyless;
1079
+ try {
1080
+ keyless = require('./seatbelt/hook').keylessSeatbelt(identity.harness, seatbeltEvent(source, rawEvent));
1081
+ }
1082
+ catch {
1083
+ keyless = { mode: 'claimed_no_key', stopText: SEATBELT_FAILED_TEXT };
1084
+ }
1085
+ keylessAccountLinked = keyless.accountLinked === true;
1086
+ keylessSeatbeltMode = keyless.mode === 'seatbelt';
1087
+ if (keyless.stopText) {
1088
+ emitLoopGuardDenial(identity.harness, keyless.stopText);
1089
+ return;
1090
+ }
1091
+ // A tool the mapper does not recognise never gets the seatbelt pass: master's answer below.
1092
+ if (keyless.mode === 'seatbelt' && keyless.recognized === true) {
1093
+ // Never an explicit allow for an action 3.9.103 held: the host's own approval step decides.
1094
+ const answer = seatbeltPassOutput(identity.harness, source.hook_event_name, !classified.readOnly && enforcementRequired);
1095
+ if (answer === null)
1096
+ process.exitCode = 0;
1097
+ else
1098
+ process.stdout.write(JSON.stringify(answer));
1099
+ return;
1100
+ }
1101
+ }
1102
+ else {
1103
+ watch.harness = identity.harness;
1104
+ watch.event = seatbeltEvent(source, rawEvent);
1105
+ let floor = null;
1106
+ try {
1107
+ floor = require('./seatbelt/hook');
1108
+ }
1109
+ catch { /* watch only: a missing module never changes the account flow */ }
1110
+ if (floor && floor.SEATBELT_ROLLOUT.account_floor === 'on') {
1111
+ watch.harness = undefined;
1112
+ const stopText = floor.accountFloor(identity.harness, watch.event, (0, host_approval_1.preToolDeadline)((0, host_approval_1.approvalHostFor)(identity.harness)));
1113
+ if (stopText) {
1114
+ emitLoopGuardDenial(identity.harness, stopText);
1115
+ return;
1116
+ }
1117
+ }
1118
+ }
965
1119
  if (classified.readOnly) {
966
1120
  const allow = localControlAllowOutput(identity.harness);
967
1121
  if (allow === null)
@@ -988,7 +1142,7 @@ async function runPreActionHookCommand(input) {
988
1142
  runtime: null,
989
1143
  permit: null,
990
1144
  protectedRisk: enforcementRequired,
991
- enforcementError: exports.NO_KEY_TEXT,
1145
+ enforcementError: keylessSeatbeltMode ? exports.NO_KEY_TEXT : keylessAccountLinked ? exports.CLAIMED_NO_KEY_TEXT : exports.SETUP_UNCONFIRMED_TEXT,
992
1146
  }, identity.harness);
993
1147
  return;
994
1148
  }
@@ -1058,6 +1212,11 @@ async function runPreActionHookCommand(input) {
1058
1212
  });
1059
1213
  // The decision and gate receipt this control path holds, so a denial can close them.
1060
1214
  const held = { decisionId: null, gateReceiptId: null };
1215
+ // Set once the runtime gate has answered. A later network or 5xx failure (decision, permit issue
1216
+ // or verify) on a high-risk action is a reached answer that no permit can be had: a denial, never
1217
+ // "offline, allowed". Routine actions keep the outage policy (failure_mode low_risk_behavior).
1218
+ const reach = { gateAnswered: false };
1219
+ const highRisk = classified.protected || classified.risk === 'high';
1061
1220
  const control = async (signal) => {
1062
1221
  const runtime = await (0, index_1.marrowAgentRuntime)(resolved.apiKey, baseUrl, {
1063
1222
  action: classified.action,
@@ -1072,6 +1231,7 @@ async function runPreActionHookCommand(input) {
1072
1231
  // non-durable fast_gate receipt can never back an action permit.
1073
1232
  ...(enforcementRequired ? { risk_level: classified.risk } : {}),
1074
1233
  }, sessionId, agentId, signal);
1234
+ reach.gateAnswered = true;
1075
1235
  const heldIds = [...new Set([runtime.decision_id, runtime.completion_contract?.decision_id, runtime.runtime_authorization?.decision_id]
1076
1236
  .filter((value) => typeof value === 'string' && SAFE_DECISION_ID.test(value)))];
1077
1237
  held.decisionId = heldIds.length === 1 ? heldIds[0] : null;
@@ -1173,7 +1333,7 @@ async function runPreActionHookCommand(input) {
1173
1333
  timedOut: true,
1174
1334
  enforcementError: hook_contract_1.MARROW_OUTAGE_WARNING,
1175
1335
  }
1176
- : isMarrowControlOutage(error)
1336
+ : isMarrowControlOutage(error) && !(reach.gateAnswered && highRisk)
1177
1337
  ? {
1178
1338
  runtime: null,
1179
1339
  permit: null,
@@ -1181,13 +1341,21 @@ async function runPreActionHookCommand(input) {
1181
1341
  outage: true,
1182
1342
  enforcementError: hook_contract_1.MARROW_OUTAGE_WARNING,
1183
1343
  }
1184
- : {
1185
- runtime: null,
1186
- permit: null,
1187
- protectedRisk: enforcementRequired,
1188
- enforcementError: controlRejectionMessage(error, agentId),
1189
- ...(controlFailureKind(error) ? { failure: controlFailureKind(error) } : {}),
1190
- })),
1344
+ : isMarrowControlOutage(error)
1345
+ ? {
1346
+ runtime: null,
1347
+ permit: null,
1348
+ protectedRisk: enforcementRequired,
1349
+ enforcementError: controlRejectionMessage(error, agentId, 'unavailable'),
1350
+ failure: 'unavailable',
1351
+ }
1352
+ : {
1353
+ runtime: null,
1354
+ permit: null,
1355
+ protectedRisk: enforcementRequired,
1356
+ enforcementError: controlRejectionMessage(error, agentId),
1357
+ ...(controlFailureKind(error) ? { failure: controlFailureKind(error) } : {}),
1358
+ })),
1191
1359
  lifecycle,
1192
1360
  ]);
1193
1361
  const claudePrompt = ownerApprovalPrompt(identity.harness, source);
@@ -1205,12 +1373,17 @@ async function runPreActionHookCommand(input) {
1205
1373
  }
1206
1374
  if (result.outage) {
1207
1375
  // Marrow cannot be reached. An action in a category the account owner
1208
- // protects stays held on every host; everything else keeps the outage policy.
1376
+ // protects stays held on every host; a high-risk action fails closed (high-risk
1377
+ // work needs a fresh gate); routine actions keep the outage policy.
1209
1378
  const protectedNow = (0, host_approval_1.protectedAmong)(holdContext, localApprovalCategories(classified));
1210
1379
  if (protectedNow.length) {
1211
1380
  emitHeldPlan(identity.harness, { kind: 'deny', agentText: host_approval_1.HELD_UNREACHABLE_TEXT, userText: host_approval_1.HELD_UNREACHABLE_TEXT, code: false });
1212
1381
  return;
1213
1382
  }
1383
+ if (outageHolds(highRisk, () => require('./seatbelt/hook').outageRisk(seatbeltEvent(source, rawEvent), holdContext.deadlineAt ?? Number.POSITIVE_INFINITY))) {
1384
+ emitHeldPlan(identity.harness, { kind: 'deny', agentText: exports.HELD_OFFLINE_TEXT, userText: exports.HELD_OFFLINE_TEXT, code: false });
1385
+ return;
1386
+ }
1214
1387
  }
1215
1388
  const verdict = result.outage ? null : runtimeGateVerdict(result.runtime);
1216
1389
  const guidance = verdict?.kind === 'review' ? (0, runtime_contract_1.ordinaryApprovalGuidance)(result.runtime) : null;