tamperward 2.39.13 → 2.39.15

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 (2) hide show
  1. package/dist/cli/index.js +37 -12
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -20173,15 +20173,15 @@ function immutableRuntimeCapabilities(caps) {
20173
20173
  function immutableRuntimeAdapter(adapter) {
20174
20174
  return Object.freeze(adapter);
20175
20175
  }
20176
- function unknownToolFinding(toolName) {
20176
+ function unknownToolFinding(runtime, toolName) {
20177
20177
  const name = toolName.length > 80 ? toolName.slice(0, 77) + "..." : toolName;
20178
- const detail = 'Copilot tool "' + name + `" is not in TamperWard's explicit operation vocabulary`;
20178
+ const detail = runtime + ' tool "' + name + `" is not in TamperWard's explicit operation vocabulary`;
20179
20179
  return {
20180
20180
  rule: "unknown-tool",
20181
20181
  severity: "block",
20182
20182
  message: "TamperWard cannot safely classify " + detail + "; it is denied rather than treated as a no-op.",
20183
20183
  evidence: detail,
20184
- remediation: "Confirm the tool is non-mutating and add it to the Copilot adapter allowlist, or obtain an explicit sign-off before retrying.",
20184
+ remediation: "Confirm the tool is non-mutating and add it to the " + runtime + " adapter allowlist, or obtain an explicit sign-off before retrying.",
20185
20185
  signoff: { required: true, command: 'tamperward allow --reason "..."' }
20186
20186
  };
20187
20187
  }
@@ -20592,7 +20592,8 @@ function codexOperationKind(toolName) {
20592
20592
  if (FILE_EDIT_TOOLS.has(toolName)) return "file-edit";
20593
20593
  if (toolName.startsWith(MCP_PREFIX)) return "mcp";
20594
20594
  if (FILE_READ_TOOLS.has(toolName)) return "file-read";
20595
- return "other";
20595
+ if (NON_MUTATING_TOOLS.has(toolName)) return "other";
20596
+ return "unknown";
20596
20597
  }
20597
20598
  function inputFrom(parsed) {
20598
20599
  return {
@@ -20625,7 +20626,7 @@ function normalizeCodexEvent(raw, phase) {
20625
20626
  }
20626
20627
  return eventFrom2(inputFrom(parsed), phase);
20627
20628
  }
20628
- var SHELL_TOOLS, FILE_EDIT_TOOLS, FILE_READ_TOOLS, MCP_PREFIX;
20629
+ var SHELL_TOOLS, FILE_EDIT_TOOLS, FILE_READ_TOOLS, NON_MUTATING_TOOLS, MCP_PREFIX;
20629
20630
  var init_schema = __esm({
20630
20631
  "src/adapters/codex/schema.ts"() {
20631
20632
  "use strict";
@@ -20633,6 +20634,7 @@ var init_schema = __esm({
20633
20634
  SHELL_TOOLS = /* @__PURE__ */ new Set(["Bash"]);
20634
20635
  FILE_EDIT_TOOLS = /* @__PURE__ */ new Set(["apply_patch", "Write", "Edit"]);
20635
20636
  FILE_READ_TOOLS = /* @__PURE__ */ new Set(["view_image"]);
20637
+ NON_MUTATING_TOOLS = /* @__PURE__ */ new Set(["update_plan", "web_search"]);
20636
20638
  MCP_PREFIX = "mcp__";
20637
20639
  }
20638
20640
  });
@@ -20728,6 +20730,12 @@ var init_adapter2 = __esm({
20728
20730
  const findings = swept.findings ? [...swept.findings] : [];
20729
20731
  return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
20730
20732
  }
20733
+ if (parsed.operation.kind === "unknown") {
20734
+ const detail = `unrecognized Codex tool ${parsed.operation.name}; refusing to evaluate it as a no-op`;
20735
+ const findings = [unknownToolFinding("Codex", parsed.operation.name)];
20736
+ const wire = this.denyPayload(findings, "pre-action");
20737
+ return { outcome: "ok", wire, detail, decision: { verdict: "deny", findings, reason: wire } };
20738
+ }
20731
20739
  try {
20732
20740
  const root = idv.trustedRoot ?? repoRoot(defaultCwd ?? process.cwd());
20733
20741
  const sessionCwd = parsed.identity.claimedCwd ?? defaultCwd ?? process.cwd();
@@ -20865,7 +20873,7 @@ function copilotOperationKind(toolName) {
20865
20873
  if (FILE_EDIT_TOOLS2.has(name)) return "file-edit";
20866
20874
  if (name.startsWith(MCP_PREFIX2)) return "mcp";
20867
20875
  if (FILE_READ_TOOLS2.has(name)) return "file-read";
20868
- if (NON_MUTATING_TOOLS.has(name)) return "other";
20876
+ if (NON_MUTATING_TOOLS2.has(name)) return "other";
20869
20877
  return "unknown";
20870
20878
  }
20871
20879
  function argsFrom(parsed) {
@@ -20929,7 +20937,7 @@ function copilotStopInput(raw) {
20929
20937
  ...input.stop_hook_active !== void 0 ? { stop_hook_active: input.stop_hook_active } : {}
20930
20938
  });
20931
20939
  }
20932
- var SHELL_TOOLS2, FILE_EDIT_TOOLS2, FILE_READ_TOOLS2, NON_MUTATING_TOOLS, MCP_PREFIX2;
20940
+ var SHELL_TOOLS2, FILE_EDIT_TOOLS2, FILE_READ_TOOLS2, NON_MUTATING_TOOLS2, MCP_PREFIX2;
20933
20941
  var init_schema2 = __esm({
20934
20942
  "src/adapters/copilot/schema.ts"() {
20935
20943
  "use strict";
@@ -20937,7 +20945,7 @@ var init_schema2 = __esm({
20937
20945
  SHELL_TOOLS2 = /* @__PURE__ */ new Set(["bash", "powershell", "write_bash", "write_powershell"]);
20938
20946
  FILE_EDIT_TOOLS2 = /* @__PURE__ */ new Set(["create", "edit", "write", "multiedit", "apply_patch", "str_replace_editor"]);
20939
20947
  FILE_READ_TOOLS2 = /* @__PURE__ */ new Set(["view", "read", "grep", "rg", "glob"]);
20940
- NON_MUTATING_TOOLS = /* @__PURE__ */ new Set([
20948
+ NON_MUTATING_TOOLS2 = /* @__PURE__ */ new Set([
20941
20949
  "read_bash",
20942
20950
  "read_powershell",
20943
20951
  "stop_bash",
@@ -21074,7 +21082,7 @@ var init_adapter3 = __esm({
21074
21082
  }
21075
21083
  if (parsed.operation.kind === "unknown") {
21076
21084
  const detail = `unrecognized Copilot tool ${parsed.operation.name}; refusing to evaluate it as a no-op`;
21077
- const findings = [unknownToolFinding(parsed.operation.name)];
21085
+ const findings = [unknownToolFinding("Copilot", parsed.operation.name)];
21078
21086
  const wire = this.denyPayload(findings, "pre-action");
21079
21087
  return { outcome: "ok", wire, detail, decision: { verdict: "deny", findings, reason: wire } };
21080
21088
  }
@@ -21332,8 +21340,13 @@ function copilotSdkOperationKind(kind) {
21332
21340
  return "file-read";
21333
21341
  case "mcp":
21334
21342
  return "mcp";
21335
- default:
21343
+ case "":
21344
+ case "url":
21345
+ case "memory":
21346
+ case "hook":
21336
21347
  return "other";
21348
+ default:
21349
+ return "unknown";
21337
21350
  }
21338
21351
  }
21339
21352
  function str2(v) {
@@ -21371,8 +21384,13 @@ function argsFor(req2) {
21371
21384
  }
21372
21385
  return {};
21373
21386
  }
21387
+ function operationFrom(req2) {
21388
+ const kind = copilotSdkOperationKind(req2.kind);
21389
+ const name = kind === "unknown" ? req2.toolName || req2.kind || "" : req2.toolName ?? "";
21390
+ return { kind, name, args: argsFor(req2) };
21391
+ }
21374
21392
  function eventFrom4(req2, phase) {
21375
- const operation = phase === "end-of-turn" ? { kind: "other", name: "stop", args: {} } : { kind: copilotSdkOperationKind(req2.kind), name: req2.toolName ?? "", args: argsFor(req2) };
21393
+ const operation = phase === "end-of-turn" ? { kind: "other", name: "stop", args: {} } : operationFrom(req2);
21376
21394
  const identity2 = { claimedCwd: req2.cwd, sessionId: req2.sessionId };
21377
21395
  return { phase, operation, identity: identity2 };
21378
21396
  }
@@ -21480,7 +21498,8 @@ var init_adapter4 = __esm({
21480
21498
  * `onAgentStop` `{decision:"block",reason}` shape.
21481
21499
  * 5. `pre-action` + shell → the SAME `evaluate` engine over the reconstructed command.
21482
21500
  * 6. `pre-action` + file-edit → `unsupported` (content not surfaced; sweep is authority).
21483
- * 7. `pre-action` + read/mcp/other → no Change → allow.
21501
+ * 7. `pre-action` + an unmodelled permission kind → an `unknown-tool` deny.
21502
+ * 8. `pre-action` + read/mcp/other → no Change → allow.
21484
21503
  */
21485
21504
  decide(raw, phase, defaultCwd) {
21486
21505
  if (phase === "post-action") {
@@ -21509,6 +21528,12 @@ var init_adapter4 = __esm({
21509
21528
  const findings = swept.findings ? [...swept.findings] : [];
21510
21529
  return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
21511
21530
  }
21531
+ if (parsed.operation.kind === "unknown") {
21532
+ const detail = `unrecognized Copilot SDK permission request ${parsed.operation.name}; refusing to evaluate it as a no-op`;
21533
+ const findings = [unknownToolFinding("Copilot SDK", parsed.operation.name)];
21534
+ const wire = this.denyPayload(findings, "pre-action");
21535
+ return { outcome: "ok", wire, detail, decision: { verdict: "deny", findings, reason: wire } };
21536
+ }
21512
21537
  let stage = "repo-context";
21513
21538
  try {
21514
21539
  const root = idv.trustedRoot ?? repoRoot(defaultCwd ?? process.cwd());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.39.13",
3
+ "version": "2.39.15",
4
4
  "description": "The deterministic agent-integrity gate. One ruleset, evaluated on the actual diff/commands as a verdict, enforced everywhere a change can be made.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "hexrift",