protect-mcp 0.7.2 → 0.7.4

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.
@@ -12,6 +12,9 @@
12
12
  * - delete_file (destructive, blocked by default policy)
13
13
  * - web_search (rate-limited)
14
14
  * - deploy (high-privilege)
15
+ * - github_create_pr (source-control mutation)
16
+ * - send_email (external communication)
17
+ * - pms_book_fill (mock portfolio-management booking)
15
18
  */
16
19
  /**
17
20
  * Smithery sandbox server — returns a McpServer instance
@@ -12,6 +12,9 @@
12
12
  * - delete_file (destructive, blocked by default policy)
13
13
  * - web_search (rate-limited)
14
14
  * - deploy (high-privilege)
15
+ * - github_create_pr (source-control mutation)
16
+ * - send_email (external communication)
17
+ * - pms_book_fill (mock portfolio-management booking)
15
18
  */
16
19
  /**
17
20
  * Smithery sandbox server — returns a McpServer instance
@@ -35064,6 +35064,48 @@ var TOOLS = [
35064
35064
  },
35065
35065
  required: ["environment"]
35066
35066
  }
35067
+ },
35068
+ {
35069
+ name: "github_create_pr",
35070
+ description: "Create a GitHub pull request",
35071
+ inputSchema: {
35072
+ type: "object",
35073
+ properties: {
35074
+ repo: { type: "string", description: "Repository name" },
35075
+ branch: { type: "string", description: "Source branch" },
35076
+ title: { type: "string", description: "Pull request title" }
35077
+ },
35078
+ required: ["repo", "branch", "title"]
35079
+ }
35080
+ },
35081
+ {
35082
+ name: "send_email",
35083
+ description: "Send an email",
35084
+ inputSchema: {
35085
+ type: "object",
35086
+ properties: {
35087
+ to: { type: "string", description: "Recipient email address" },
35088
+ subject: { type: "string", description: "Subject line" },
35089
+ body: { type: "string", description: "Message body" }
35090
+ },
35091
+ required: ["to", "subject"]
35092
+ }
35093
+ },
35094
+ {
35095
+ name: "pms_book_fill",
35096
+ description: "Book a fill into the mock portfolio management system",
35097
+ inputSchema: {
35098
+ type: "object",
35099
+ properties: {
35100
+ account: { type: "string", description: "Portfolio or fund account" },
35101
+ symbol: { type: "string", description: "Instrument symbol" },
35102
+ side: { type: "string", enum: ["BUY", "SELL"] },
35103
+ quantity: { type: "number" },
35104
+ price: { type: "number" },
35105
+ strategy: { type: "string" }
35106
+ },
35107
+ required: ["account", "symbol", "side", "quantity", "price"]
35108
+ }
35067
35109
  }
35068
35110
  ];
35069
35111
  function handleRequest(request) {
@@ -35111,6 +35153,15 @@ Contents: Hello from protect-mcp demo server!`;
35111
35153
  case "deploy":
35112
35154
  resultText = `[demo] Deployed to ${args.environment || "staging"}${args.reason ? ` (reason: ${args.reason})` : ""}`;
35113
35155
  break;
35156
+ case "github_create_pr":
35157
+ resultText = `[demo] Created PR in ${args.repo || "scopeblind/demo"} from ${args.branch || "agent/demo"}: ${args.title || "Agent change"}`;
35158
+ break;
35159
+ case "send_email":
35160
+ resultText = `[demo] Drafted email to ${args.to || "pm@example.com"}: ${args.subject || "Agent update"}`;
35161
+ break;
35162
+ case "pms_book_fill":
35163
+ resultText = `[demo] Booked ${args.side || "BUY"} ${args.quantity || 0} ${args.symbol || "AAPL"} @ ${args.price || 0} into ${args.account || "Demo Fund"} (${args.strategy || "Unassigned"})`;
35164
+ break;
35114
35165
  default:
35115
35166
  resultText = `[demo] Unknown tool: ${toolName}`;
35116
35167
  }
@@ -35183,6 +35234,30 @@ function createSandboxServer() {
35183
35234
  { environment: z.enum(["staging", "production"]).describe("Target environment"), reason: z.string().optional().describe("Deployment reason") },
35184
35235
  async (args) => ({ content: [{ type: "text", text: `[demo] Deployed to ${args.environment}` }] })
35185
35236
  );
35237
+ server.tool("github_create_pr", "Create a GitHub pull request", {
35238
+ repo: z.string(),
35239
+ branch: z.string(),
35240
+ title: z.string()
35241
+ }, async (args) => ({
35242
+ content: [{ type: "text", text: `[demo] PR created in ${args.repo} from ${args.branch}: ${args.title}` }]
35243
+ }));
35244
+ server.tool("send_email", "Send an email", {
35245
+ to: z.string(),
35246
+ subject: z.string(),
35247
+ body: z.string().optional()
35248
+ }, async (args) => ({
35249
+ content: [{ type: "text", text: `[demo] Email prepared for ${args.to}: ${args.subject}` }]
35250
+ }));
35251
+ server.tool("pms_book_fill", "Book a fill into a mock PMS", {
35252
+ account: z.string(),
35253
+ symbol: z.string(),
35254
+ side: z.enum(["BUY", "SELL"]),
35255
+ quantity: z.number(),
35256
+ price: z.number(),
35257
+ strategy: z.string().optional()
35258
+ }, async (args) => ({
35259
+ content: [{ type: "text", text: `[demo] Booked ${args.side} ${args.quantity} ${args.symbol} @ ${args.price} into ${args.account}` }]
35260
+ }));
35186
35261
  return server;
35187
35262
  }
35188
35263
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createSandboxServer
4
- } from "./chunk-J6L4XCTE.mjs";
4
+ } from "./chunk-KPSICBAJ.mjs";
5
5
  import "./chunk-PQJP2ZCI.mjs";
6
6
  export {
7
7
  createSandboxServer
@@ -24,7 +24,7 @@ __export(hook_server_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(hook_server_exports);
26
26
  var import_node_http2 = require("http");
27
- var import_node_crypto3 = require("crypto");
27
+ var import_node_crypto4 = require("crypto");
28
28
  var import_node_fs5 = require("fs");
29
29
  var import_node_path3 = require("path");
30
30
 
@@ -320,6 +320,7 @@ function signDecision(entry) {
320
320
  if (entry.timing) payload.timing = entry.timing;
321
321
  if (entry.swarm) payload.swarm = entry.swarm;
322
322
  if (entry.payload_digest) payload.payload_digest = entry.payload_digest;
323
+ if (entry.action_readback) payload.action_readback = entry.action_readback;
323
324
  if (entry.deny_iteration) payload.deny_iteration = entry.deny_iteration;
324
325
  const result = artifactsModule.createSignedArtifact(
325
326
  artifactType,
@@ -613,6 +614,95 @@ function getScopeBlindBridge() {
613
614
  return singleton;
614
615
  }
615
616
 
617
+ // src/action-readback.ts
618
+ var import_node_crypto3 = require("crypto");
619
+ var SECRET_KEY_RE = /(api[_-]?key|authorization|bearer|credential|password|secret|session|token|private[_-]?key)/i;
620
+ var DESTINATION_KEYS = [
621
+ "path",
622
+ "file_path",
623
+ "filePath",
624
+ "url",
625
+ "uri",
626
+ "endpoint",
627
+ "host",
628
+ "hostname",
629
+ "repo",
630
+ "repository",
631
+ "branch",
632
+ "channel",
633
+ "to",
634
+ "recipient",
635
+ "symbol",
636
+ "account",
637
+ "bucket",
638
+ "database",
639
+ "table",
640
+ "service"
641
+ ];
642
+ function stableStringify(value) {
643
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
644
+ if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
645
+ const obj = value;
646
+ return `{${Object.keys(obj).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`).join(",")}}`;
647
+ }
648
+ function redact(value, path = [], redacted = [], disclosed = [], depth = 0) {
649
+ if (depth > 4) return "[truncated-depth]";
650
+ if (value === null || value === void 0) return value;
651
+ if (typeof value !== "object") {
652
+ if (path.length > 0) disclosed.push(path.join("."));
653
+ if (typeof value === "string" && value.length > 240) return `${value.slice(0, 240)}...`;
654
+ return value;
655
+ }
656
+ if (Array.isArray(value)) {
657
+ return value.slice(0, 20).map((item, idx) => redact(item, [...path, String(idx)], redacted, disclosed, depth + 1));
658
+ }
659
+ const out = {};
660
+ for (const [key, child] of Object.entries(value)) {
661
+ const childPath = [...path, key];
662
+ if (SECRET_KEY_RE.test(key)) {
663
+ redacted.push(childPath.join("."));
664
+ out[key] = "[redacted]";
665
+ continue;
666
+ }
667
+ out[key] = redact(child, childPath, redacted, disclosed, depth + 1);
668
+ }
669
+ return out;
670
+ }
671
+ function firstStringValue(input, keys) {
672
+ for (const key of keys) {
673
+ const value = input[key];
674
+ if (typeof value === "string" && value.trim()) return value.trim();
675
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
676
+ }
677
+ return void 0;
678
+ }
679
+ function actionFor(tool, input) {
680
+ const explicit = firstStringValue(input, ["action", "operation", "method", "verb", "command"]);
681
+ if (explicit) return explicit.length > 90 ? `${explicit.slice(0, 90)}...` : explicit;
682
+ return tool;
683
+ }
684
+ function buildActionReadback(tool, input) {
685
+ const normalized = input && typeof input === "object" && !Array.isArray(input) ? input : { value: input };
686
+ const canonical = stableStringify(normalized);
687
+ const redactedFields = [];
688
+ const disclosedFields = [];
689
+ const payloadPreview = redact(normalized, [], redactedFields, disclosedFields);
690
+ const action = actionFor(tool, normalized);
691
+ const destination = firstStringValue(normalized, DESTINATION_KEYS);
692
+ const summary = destination ? `${tool} -> ${destination}` : `${tool} request`;
693
+ return {
694
+ tool,
695
+ action,
696
+ destination,
697
+ payload_preview: payloadPreview,
698
+ payload_hash: (0, import_node_crypto3.createHash)("sha256").update(canonical).digest("hex"),
699
+ payload_bytes: Buffer.byteLength(canonical, "utf-8"),
700
+ disclosed_fields: [...new Set(disclosedFields)].slice(0, 80),
701
+ redacted_fields: [...new Set(redactedFields)].slice(0, 80),
702
+ summary
703
+ };
704
+ }
705
+
616
706
  // src/hook-server.ts
617
707
  var DEFAULT_PORT = 9377;
618
708
  var LOG_FILE = ".protect-mcp-log.jsonl";
@@ -641,7 +731,7 @@ function computePayloadDigest(input) {
641
731
  return void 0;
642
732
  }
643
733
  return {
644
- input_hash: (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex"),
734
+ input_hash: (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex"),
645
735
  input_size: size,
646
736
  truncated: true,
647
737
  preview: content.slice(0, 256)
@@ -654,7 +744,7 @@ function computeOutputDigest(output) {
654
744
  return void 0;
655
745
  }
656
746
  return {
657
- output_hash: (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex"),
747
+ output_hash: (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex"),
658
748
  output_size: size
659
749
  };
660
750
  }
@@ -677,13 +767,14 @@ function detectSandboxState() {
677
767
  async function handlePreToolUse(input, state) {
678
768
  const hookStart = Date.now();
679
769
  const toolName = input.toolName || "unknown";
680
- const requestId = input.toolUseId || (0, import_node_crypto3.randomUUID)().slice(0, 12);
770
+ const requestId = input.toolUseId || (0, import_node_crypto4.randomUUID)().slice(0, 12);
681
771
  state.inflightTools.set(requestId, {
682
772
  tool: toolName,
683
773
  startedAt: hookStart,
684
774
  requestId
685
775
  });
686
776
  const payloadDigest = computePayloadDigest(input.toolInput);
777
+ const actionReadback = buildActionReadback(toolName, input.toolInput || {});
687
778
  const swarm = {
688
779
  ...state.swarmContext,
689
780
  ...input.agentId && { agent_id: input.agentId },
@@ -701,7 +792,10 @@ async function handlePreToolUse(input, state) {
701
792
  context: {
702
793
  hook_event: "PreToolUse",
703
794
  ...input.toolInput || {}
704
- }
795
+ },
796
+ // Also expose the raw tool input under context.input so policies written
797
+ // against the documented nested shape match on the hook path too.
798
+ toolInput: input.toolInput || {}
705
799
  });
706
800
  if (!cedarDecision.allowed) {
707
801
  const reason = cedarDecision.reason || "cedar_deny";
@@ -720,6 +814,7 @@ async function handlePreToolUse(input, state) {
720
814
  swarm: swarm.team_name ? swarm : void 0,
721
815
  timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
722
816
  payload_digest: payloadDigest,
817
+ action_readback: actionReadback,
723
818
  deny_iteration: denyCount,
724
819
  sandbox_state: detectSandboxState(),
725
820
  plan_receipt_id: state.activePlanReceiptId || void 0
@@ -740,10 +835,30 @@ async function handlePreToolUse(input, state) {
740
835
  };
741
836
  }
742
837
  } catch (err) {
743
- if (state.verbose) {
744
- process.stderr.write(`[PROTECT_MCP] Cedar eval error: ${err instanceof Error ? err.message : err}
745
- `);
746
- }
838
+ const hookLatency2 = Date.now() - hookStart;
839
+ process.stderr.write(
840
+ `[PROTECT_MCP] Cedar eval threw for "${toolName}", failing closed: ${err instanceof Error ? err.message : err}
841
+ `
842
+ );
843
+ emitDecisionLog(state, {
844
+ tool: toolName,
845
+ decision: "deny",
846
+ reason_code: "cedar_eval_error",
847
+ request_id: requestId,
848
+ hook_event: "PreToolUse",
849
+ swarm: swarm.team_name ? swarm : void 0,
850
+ timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
851
+ payload_digest: payloadDigest,
852
+ action_readback: actionReadback,
853
+ sandbox_state: detectSandboxState()
854
+ });
855
+ return {
856
+ hookSpecificOutput: {
857
+ hookEventName: "PreToolUse",
858
+ permissionDecision: "deny",
859
+ permissionDecisionReason: `[ScopeBlind] Denied: the policy engine errored while evaluating "${toolName}", so the gate fails closed rather than allow an unverified call. Check the policy set and server logs.`
860
+ }
861
+ };
747
862
  }
748
863
  }
749
864
  if (state.jsonPolicy?.policy) {
@@ -759,6 +874,7 @@ async function handlePreToolUse(input, state) {
759
874
  swarm: swarm.team_name ? swarm : void 0,
760
875
  timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
761
876
  payload_digest: payloadDigest,
877
+ action_readback: actionReadback,
762
878
  sandbox_state: detectSandboxState()
763
879
  });
764
880
  return {
@@ -779,13 +895,15 @@ async function handlePreToolUse(input, state) {
779
895
  hook_event: "PreToolUse",
780
896
  swarm: swarm.team_name ? swarm : void 0,
781
897
  timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
898
+ payload_digest: payloadDigest,
899
+ action_readback: actionReadback,
782
900
  sandbox_state: detectSandboxState()
783
901
  });
784
902
  return {
785
903
  hookSpecificOutput: {
786
904
  hookEventName: "PreToolUse",
787
905
  permissionDecision: "ask",
788
- permissionDecisionReason: `[ScopeBlind] "${toolName}" requires human approval. Policy: ${state.policyDigest}`
906
+ permissionDecisionReason: `[ScopeBlind] Approval required for exactly this action: ${actionReadback.summary}. Payload hash: ${actionReadback.payload_hash.slice(0, 16)}\u2026 Policy: ${state.policyDigest}`
789
907
  }
790
908
  };
791
909
  }
@@ -830,6 +948,7 @@ async function handlePreToolUse(input, state) {
830
948
  swarm: swarm.team_name ? swarm : void 0,
831
949
  timing: { hook_latency_ms: hookLatency, started_at: hookStart },
832
950
  payload_digest: payloadDigest,
951
+ action_readback: actionReadback,
833
952
  sandbox_state: detectSandboxState(),
834
953
  plan_receipt_id: state.activePlanReceiptId || void 0
835
954
  });
@@ -846,7 +965,7 @@ async function handlePreToolUse(input, state) {
846
965
  }
847
966
  async function handlePostToolUse(input, state) {
848
967
  const toolName = input.toolName || "unknown";
849
- const requestId = input.toolUseId || (0, import_node_crypto3.randomUUID)().slice(0, 12);
968
+ const requestId = input.toolUseId || (0, import_node_crypto4.randomUUID)().slice(0, 12);
850
969
  const now = Date.now();
851
970
  const inflight = state.inflightTools.get(requestId);
852
971
  const timing = {
@@ -858,7 +977,7 @@ async function handlePostToolUse(input, state) {
858
977
  state.inflightTools.delete(requestId);
859
978
  }
860
979
  const outputDigest = computeOutputDigest(input.toolResult);
861
- const receiptId = (0, import_node_crypto3.randomUUID)().slice(0, 8);
980
+ const receiptId = (0, import_node_crypto4.randomUUID)().slice(0, 8);
862
981
  const policyName = state.cedarPolicies ? `cedar:${state.policyDigest}` : state.policyDigest;
863
982
  const additionalContext = `[ScopeBlind] Tool call receipted. Policy: ${policyName}. Decision: allow. Receipt: #${receiptId}.` + (timing.tool_duration_ms !== void 0 ? ` Duration: ${timing.tool_duration_ms}ms.` : "") + (timing.hook_latency_ms !== void 0 ? ` Overhead: ${timing.hook_latency_ms}ms.` : "");
864
983
  emitDecisionLog(state, {
@@ -890,7 +1009,7 @@ function handleSubagentStart(input, state) {
890
1009
  tool: `subagent:${agentId}`,
891
1010
  decision: "allow",
892
1011
  reason_code: "subagent_started",
893
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1012
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
894
1013
  hook_event: "SubagentStart",
895
1014
  swarm: {
896
1015
  ...state.swarmContext,
@@ -911,7 +1030,7 @@ function handleSubagentStop(input, state) {
911
1030
  tool: `subagent:${agentId}`,
912
1031
  decision: "allow",
913
1032
  reason_code: "subagent_stopped",
914
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1033
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
915
1034
  hook_event: "SubagentStop",
916
1035
  swarm: {
917
1036
  ...state.swarmContext,
@@ -926,7 +1045,7 @@ function handleTaskCreated(input, state) {
926
1045
  tool: `task:${input.taskId || "unknown"}`,
927
1046
  decision: "allow",
928
1047
  reason_code: "task_created",
929
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1048
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
930
1049
  hook_event: "TaskCreated",
931
1050
  swarm: {
932
1051
  ...state.swarmContext,
@@ -940,7 +1059,7 @@ function handleTaskCompleted(input, state) {
940
1059
  tool: `task:${input.taskId || "unknown"}`,
941
1060
  decision: "allow",
942
1061
  reason_code: "task_completed",
943
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1062
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
944
1063
  hook_event: "TaskCompleted",
945
1064
  swarm: state.swarmContext
946
1065
  });
@@ -951,7 +1070,7 @@ function handleSessionStart(input, state) {
951
1070
  tool: "session",
952
1071
  decision: "allow",
953
1072
  reason_code: "session_started",
954
- request_id: input.sessionId || (0, import_node_crypto3.randomUUID)().slice(0, 12),
1073
+ request_id: input.sessionId || (0, import_node_crypto4.randomUUID)().slice(0, 12),
955
1074
  hook_event: "SessionStart",
956
1075
  swarm: state.swarmContext,
957
1076
  sandbox_state: detectSandboxState()
@@ -974,7 +1093,7 @@ function handleSessionEnd(input, state) {
974
1093
  tool: "session",
975
1094
  decision: "allow",
976
1095
  reason_code: "session_ended",
977
- request_id: input.sessionId || (0, import_node_crypto3.randomUUID)().slice(0, 12),
1096
+ request_id: input.sessionId || (0, import_node_crypto4.randomUUID)().slice(0, 12),
978
1097
  hook_event: "SessionEnd",
979
1098
  swarm: state.swarmContext
980
1099
  });
@@ -985,7 +1104,7 @@ function handleTeammateIdle(input, state) {
985
1104
  tool: `teammate:${input.agentId || "unknown"}`,
986
1105
  decision: "allow",
987
1106
  reason_code: "teammate_idle",
988
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1107
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
989
1108
  hook_event: "TeammateIdle",
990
1109
  swarm: {
991
1110
  ...state.swarmContext,
@@ -1013,7 +1132,7 @@ function handleConfigChange(input, state) {
1013
1132
  tool: "config",
1014
1133
  decision: "deny",
1015
1134
  reason_code: "config_tamper_detected",
1016
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1135
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
1017
1136
  hook_event: "ConfigChange",
1018
1137
  swarm: state.swarmContext
1019
1138
  });
@@ -1022,7 +1141,7 @@ function handleConfigChange(input, state) {
1022
1141
  tool: "config",
1023
1142
  decision: "allow",
1024
1143
  reason_code: "config_changed",
1025
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1144
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
1026
1145
  hook_event: "ConfigChange"
1027
1146
  });
1028
1147
  }
@@ -1044,7 +1163,7 @@ function handleStop(input, state) {
1044
1163
  tool: "session",
1045
1164
  decision: "allow",
1046
1165
  reason_code: "agent_stopped",
1047
- request_id: (0, import_node_crypto3.randomUUID)().slice(0, 12),
1166
+ request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
1048
1167
  hook_event: "Stop",
1049
1168
  swarm: state.swarmContext
1050
1169
  });
@@ -1052,8 +1171,8 @@ function handleStop(input, state) {
1052
1171
  }
1053
1172
  function emitDecisionLog(state, entry) {
1054
1173
  const mode = state.enforce ? "enforce" : "shadow";
1055
- const otelTraceId = (0, import_node_crypto3.randomBytes)(16).toString("hex");
1056
- const otelSpanId = (0, import_node_crypto3.randomBytes)(8).toString("hex");
1174
+ const otelTraceId = (0, import_node_crypto4.randomBytes)(16).toString("hex");
1175
+ const otelSpanId = (0, import_node_crypto4.randomBytes)(8).toString("hex");
1057
1176
  const log = {
1058
1177
  v: 2,
1059
1178
  tool: entry.tool || "unknown",
@@ -1061,7 +1180,7 @@ function emitDecisionLog(state, entry) {
1061
1180
  reason_code: entry.reason_code || "default_allow",
1062
1181
  policy_digest: state.policyDigest,
1063
1182
  policy_engine: state.cedarPolicies ? "cedar" : "built-in",
1064
- request_id: entry.request_id || (0, import_node_crypto3.randomUUID)().slice(0, 12),
1183
+ request_id: entry.request_id || (0, import_node_crypto4.randomUUID)().slice(0, 12),
1065
1184
  timestamp: Date.now(),
1066
1185
  mode,
1067
1186
  otel_trace_id: otelTraceId,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startHookServer
3
- } from "./chunk-X63ELMU4.mjs";
4
- import "./chunk-546U3A7R.mjs";
3
+ } from "./chunk-NVJHGXXG.mjs";
4
+ import "./chunk-D2RDY2JR.mjs";
5
5
  import "./chunk-PQJP2ZCI.mjs";
6
6
  export {
7
7
  startHookServer
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ProtectGateway
3
- } from "./chunk-OHUTUFTC.mjs";
4
- import "./chunk-546U3A7R.mjs";
3
+ } from "./chunk-UBZJ3VI2.mjs";
4
+ import "./chunk-D2RDY2JR.mjs";
5
5
  import "./chunk-PQJP2ZCI.mjs";
6
6
 
7
7
  // src/http-transport.ts
package/dist/index.d.mts CHANGED
@@ -190,6 +190,18 @@ interface DecisionLog {
190
190
  plan_receipt_id?: string;
191
191
  /** Hook event that triggered this log entry */
192
192
  hook_event?: HookEventName;
193
+ /** Redacted exact-action readback shown to humans before approving */
194
+ action_readback?: {
195
+ tool: string;
196
+ action: string;
197
+ destination?: string;
198
+ payload_preview: unknown;
199
+ payload_hash: string;
200
+ payload_bytes: number;
201
+ disclosed_fields: string[];
202
+ redacted_fields: string[];
203
+ summary: string;
204
+ };
193
205
  /** IETF specification version — ties every receipt to the standard */
194
206
  spec?: string;
195
207
  /** Issuer certification level:
@@ -977,6 +989,31 @@ interface MinimalDisclosure {
977
989
  /** Merkle inclusion proof. */
978
990
  proof: MerkleProof;
979
991
  }
992
+ interface SelectiveDisclosurePackageV0 {
993
+ type: 'scopeblind.selective_disclosure.v0';
994
+ version: 0;
995
+ parent_receipt_hash: string;
996
+ committed_fields_root: string;
997
+ disclosed_fields: string[];
998
+ hidden_fields: string[];
999
+ disclosures: MinimalDisclosure[];
1000
+ verifier_explanation: {
1001
+ summary: string;
1002
+ disclosed: string;
1003
+ hidden: string;
1004
+ limitation: string;
1005
+ };
1006
+ }
1007
+ interface SelectiveDisclosureVerification {
1008
+ valid: boolean;
1009
+ receipt_hash_valid: boolean;
1010
+ signature_valid: boolean | null;
1011
+ commitment_root_valid: boolean;
1012
+ disclosed_fields: string[];
1013
+ hidden_fields: string[];
1014
+ errors: string[];
1015
+ explanation: string[];
1016
+ }
980
1017
  /**
981
1018
  * Sign a DecisionLog in commitment mode.
982
1019
  *
@@ -1007,6 +1044,8 @@ declare function signCommittedDecision(entry: DecisionLog, committedFieldNames:
1007
1044
  * @standard draft-farley-acta-signed-receipts-01 §commitment-disclosure
1008
1045
  */
1009
1046
  declare function discloseField(receiptHash: string, fieldName: string, openings: Record<string, CommittedFieldOpening>): MinimalDisclosure;
1047
+ declare function createSelectiveDisclosurePackage(receipt: Record<string, unknown>, fieldNames: string[], openings: Record<string, CommittedFieldOpening>): SelectiveDisclosurePackageV0;
1048
+ declare function verifySelectiveDisclosurePackage(receipt: Record<string, unknown>, disclosure: SelectiveDisclosurePackageV0): SelectiveDisclosureVerification;
1010
1049
 
1011
1050
  /**
1012
1051
  * @scopeblind/protect-mcp — External PDP Adapter
@@ -1076,6 +1115,8 @@ interface AuditBundleOptions {
1076
1115
  receipts: Record<string, unknown>[];
1077
1116
  /** Optional audit anchors */
1078
1117
  anchors?: Record<string, unknown>[];
1118
+ /** Optional selective-disclosure packages opening selected committed fields */
1119
+ selectiveDisclosures?: SelectiveDisclosurePackageV0[];
1079
1120
  /** JWK signing keys used by the receipts */
1080
1121
  signingKeys: Array<{
1081
1122
  kty: string;
@@ -1096,6 +1137,14 @@ interface AuditBundle {
1096
1137
  } | null;
1097
1138
  receipts: Record<string, unknown>[];
1098
1139
  anchors: Record<string, unknown>[];
1140
+ selective_disclosures: SelectiveDisclosurePackageV0[];
1141
+ privacy: {
1142
+ selective_disclosure: {
1143
+ supported: true;
1144
+ model: 'salted_commitments_merkle_v0';
1145
+ statement: string;
1146
+ };
1147
+ };
1099
1148
  verification: {
1100
1149
  algorithm: 'ed25519';
1101
1150
  signing_keys: Array<{
@@ -1620,6 +1669,71 @@ declare function generateCedarSchema(tools: McpToolDescription[], config?: Schem
1620
1669
  */
1621
1670
  declare function generateSchemaStub(namespace?: string): string;
1622
1671
 
1672
+ interface PolicyPack {
1673
+ id: string;
1674
+ name: string;
1675
+ description: string;
1676
+ recommendedMode: 'shadow-first' | 'enforce-ready';
1677
+ files: Array<{
1678
+ path: string;
1679
+ contents: string;
1680
+ }>;
1681
+ }
1682
+ declare const POLICY_PACKS: PolicyPack[];
1683
+ declare function getPolicyPack(id: string): PolicyPack | undefined;
1684
+ declare function policyPackIds(): string[];
1685
+
1686
+ type ConnectorPilotId = 'github' | 'email-gmail' | 'filesystem-git' | 'slack-teams' | 'finance-pms';
1687
+ interface ConnectorEnvVar {
1688
+ name: string;
1689
+ required: boolean;
1690
+ description: string;
1691
+ }
1692
+ interface ConnectorAction {
1693
+ name: string;
1694
+ tool: string;
1695
+ risk: 'low' | 'medium' | 'high';
1696
+ mode: 'observe' | 'require_approval' | 'deny';
1697
+ description: string;
1698
+ }
1699
+ interface ConnectorPilot {
1700
+ id: ConnectorPilotId;
1701
+ category: string;
1702
+ name: string;
1703
+ status: 'usable-pilot';
1704
+ description: string;
1705
+ value: string;
1706
+ env: ConnectorEnvVar[];
1707
+ tools: string[];
1708
+ actions: ConnectorAction[];
1709
+ setup: string[];
1710
+ config: Record<string, unknown>;
1711
+ cedar: string;
1712
+ }
1713
+ interface InstalledConnectorPilot {
1714
+ id: string;
1715
+ name: string;
1716
+ category: string;
1717
+ status: string;
1718
+ config_path: string;
1719
+ policy_path: string;
1720
+ }
1721
+ declare const CONNECTOR_PILOTS: ConnectorPilot[];
1722
+ declare function connectorPilotIds(): ConnectorPilotId[];
1723
+ declare function getConnectorPilot(id: string): ConnectorPilot | undefined;
1724
+ declare function connectorDirectory(dir: string): string;
1725
+ declare function writeConnectorPilots(opts: {
1726
+ dir: string;
1727
+ ids?: string[];
1728
+ force?: boolean;
1729
+ }): {
1730
+ written: string[];
1731
+ pilots: ConnectorPilot[];
1732
+ directory: string;
1733
+ };
1734
+ declare function readInstalledConnectorPilots(dir: string): InstalledConnectorPilot[];
1735
+ declare function connectorDoctor(dir: string, env?: NodeJS.ProcessEnv): Array<Record<string, unknown>>;
1736
+
1623
1737
  /**
1624
1738
  * Sigstore Rekor Transparency Log Anchoring
1625
1739
  *
@@ -3015,4 +3129,4 @@ declare function getScopeBlindBridge(): ScopeBlindBridge;
3015
3129
  /** Convenience: forward a signed receipt without instantiating yourself. */
3016
3130
  declare function forwardReceipt(signedReceipt: any): void;
3017
3131
 
3018
- export { type ActionReceipt, type AdmissionResult, type AgentId, type AgentManifest, type ApprovalAssertion, type ApprovalChallenge, type ApprovalNotification, type ApprovalResult, type ArenaPayload, type ArenaReceipt, type AttestationDocument, type AttestationPayload, type AttestationProvider, type AttestationReceipt, type AttestationResult, type AuditBundle, type AuditBundleOptions, type BenchmarkPayload, type BenchmarkReceipt, type BuilderId, type C2PAAssertion, type C2PAIngredient, type C2PAManifest, type C2PAOptions, type CCRConnectorConfig, type CCRSessionContext, type CalibrationScore, type CedarEvalOptions, type CedarEvalRequest, type CedarPolicySet, type CedarSchema, type CedarSchemaResult, type CommittedFieldOpening, type CommittedSignResult, type ComplianceReport, ConfidentialGate, type ConfidentialGateConfig, type ConfidentialInferenceConfig, type CredentialConfig, type DecisionContext, type DecisionLog, type DelegationReceipt, type DisclosureMode, type Ed25519PublicKey, type EvidenceAttestation, type EvidenceAttestationInput, type EvidenceIssuer, type EvidenceReceipt, type EvidenceReceiptBase, type EvidenceSummary, type EvidenceSummaryEntry, type EvidenceType, type ExternalDecision, type ExternalPDPConfig, type HFDatasetMetadata, type HFReceiptRow, type HookEventName, type HookInput, type HookResponse, type IssuerType, type JsonRpcRequest, type JsonRpcResponse, type LeaseCompatibility, type ManifestBuilder, type ManifestCapabilities, type ManifestConfig, type ManifestIdentity, type ManifestPresentation, type ManifestSignature, type ManifestStatus, type McpToolDescription, type MinimalDisclosure, type NotificationConfig, type PassportTokenClaims, type PayloadDigest, type PlanReceipt, type PolicyEngineMode, type PredictionReceipt, type PredictionResolution, type PropagatorConfig, type ProtectConfig, ProtectGateway, type ProtectPolicy, type RateLimit, ReceiptPropagator, type RedactedResult, type RedactionSalt, type RekorAnchor, type RekorVerification, type RestraintPayload, type RestraintReceipt, type SHA256Hash, type SafetyTranscript, type Sandbox, type SandboxConfig, type SandboxReceipt, type SandboxResult, type SandboxToolCall, type SchemaGeneratorConfig, ScopeBlindBridge, type SelfTestCase, type SelfTestReport, type SigningConfig, type SimulationResult, type SimulationSummary, type SwarmContext, type TierOverrides, type TimingMetrics, type ToolPolicy, type TrustTier, type WorkPayload, type WorkReceipt, anchorToRekor, buildDecisionContext, checkRateLimit, collectSignedReceipts, computeCalibration, confidentialInference, createApprovalChallenge, createApprovalReceiptPayload, createAttestationField, createAuditBundle, createC2PAManifest, createDisclosurePackage, createEvidenceAttestation, createLogAnchorField, createReceiptChannel, createSandbox, destroySandbox, discloseField, ed25519ToDIDKey, evaluateCedar, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, forwardReceipt, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getScopeBlindBridge, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, policySetFromSource, queryExternalPDP, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runEvaluatorSelfTest, runInSandbox, sendApprovalNotification, signCommittedDecision, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor };
3132
+ export { type ActionReceipt, type AdmissionResult, type AgentId, type AgentManifest, type ApprovalAssertion, type ApprovalChallenge, type ApprovalNotification, type ApprovalResult, type ArenaPayload, type ArenaReceipt, type AttestationDocument, type AttestationPayload, type AttestationProvider, type AttestationReceipt, type AttestationResult, type AuditBundle, type AuditBundleOptions, type BenchmarkPayload, type BenchmarkReceipt, type BuilderId, type C2PAAssertion, type C2PAIngredient, type C2PAManifest, type C2PAOptions, type CCRConnectorConfig, type CCRSessionContext, CONNECTOR_PILOTS, type CalibrationScore, type CedarEvalOptions, type CedarEvalRequest, type CedarPolicySet, type CedarSchema, type CedarSchemaResult, type CommittedFieldOpening, type CommittedSignResult, type ComplianceReport, ConfidentialGate, type ConfidentialGateConfig, type ConfidentialInferenceConfig, type ConnectorAction, type ConnectorEnvVar, type ConnectorPilot, type ConnectorPilotId, type CredentialConfig, type DecisionContext, type DecisionLog, type DelegationReceipt, type DisclosureMode, type Ed25519PublicKey, type EvidenceAttestation, type EvidenceAttestationInput, type EvidenceIssuer, type EvidenceReceipt, type EvidenceReceiptBase, type EvidenceSummary, type EvidenceSummaryEntry, type EvidenceType, type ExternalDecision, type ExternalPDPConfig, type HFDatasetMetadata, type HFReceiptRow, type HookEventName, type HookInput, type HookResponse, type InstalledConnectorPilot, type IssuerType, type JsonRpcRequest, type JsonRpcResponse, type LeaseCompatibility, type ManifestBuilder, type ManifestCapabilities, type ManifestConfig, type ManifestIdentity, type ManifestPresentation, type ManifestSignature, type ManifestStatus, type McpToolDescription, type MinimalDisclosure, type NotificationConfig, POLICY_PACKS, type PassportTokenClaims, type PayloadDigest, type PlanReceipt, type PolicyEngineMode, type PolicyPack, type PredictionReceipt, type PredictionResolution, type PropagatorConfig, type ProtectConfig, ProtectGateway, type ProtectPolicy, type RateLimit, ReceiptPropagator, type RedactedResult, type RedactionSalt, type RekorAnchor, type RekorVerification, type RestraintPayload, type RestraintReceipt, type SHA256Hash, type SafetyTranscript, type Sandbox, type SandboxConfig, type SandboxReceipt, type SandboxResult, type SandboxToolCall, type SchemaGeneratorConfig, ScopeBlindBridge, type SelectiveDisclosurePackageV0, type SelectiveDisclosureVerification, type SelfTestCase, type SelfTestReport, type SigningConfig, type SimulationResult, type SimulationSummary, type SwarmContext, type TierOverrides, type TimingMetrics, type ToolPolicy, type TrustTier, type WorkPayload, type WorkReceipt, anchorToRekor, buildDecisionContext, checkRateLimit, collectSignedReceipts, computeCalibration, confidentialInference, connectorDirectory, connectorDoctor, connectorPilotIds, createApprovalChallenge, createApprovalReceiptPayload, createAttestationField, createAuditBundle, createC2PAManifest, createDisclosurePackage, createEvidenceAttestation, createLogAnchorField, createReceiptChannel, createSandbox, createSelectiveDisclosurePackage, destroySandbox, discloseField, ed25519ToDIDKey, evaluateCedar, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, forwardReceipt, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getConnectorPilot, getPolicyPack, getScopeBlindBridge, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, policyPackIds, policySetFromSource, queryExternalPDP, readInstalledConnectorPilots, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runEvaluatorSelfTest, runInSandbox, sendApprovalNotification, signCommittedDecision, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor, verifySelectiveDisclosurePackage, writeConnectorPilots };