tamperward 2.39.1 → 2.39.3

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 +79 -31
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -19758,6 +19758,29 @@ var init_trace_verify = __esm({
19758
19758
  }
19759
19759
  });
19760
19760
 
19761
+ // src/immutable.ts
19762
+ function isPlainData(value) {
19763
+ if (value === null || typeof value !== "object") return false;
19764
+ const proto = Object.getPrototypeOf(value);
19765
+ return proto === Object.prototype || proto === Array.prototype || proto === null;
19766
+ }
19767
+ function deepFreeze(value) {
19768
+ const seen = /* @__PURE__ */ new WeakSet();
19769
+ const walk2 = (node) => {
19770
+ if (!isPlainData(node) || seen.has(node)) return;
19771
+ seen.add(node);
19772
+ Object.freeze(node);
19773
+ for (const key2 of Reflect.ownKeys(node)) walk2(Reflect.get(node, key2));
19774
+ };
19775
+ walk2(value);
19776
+ return value;
19777
+ }
19778
+ var init_immutable = __esm({
19779
+ "src/immutable.ts"() {
19780
+ "use strict";
19781
+ }
19782
+ });
19783
+
19761
19784
  // src/runtimes.ts
19762
19785
  import { existsSync as existsSync17, readFileSync as readFileSync20 } from "node:fs";
19763
19786
  import { join as join25 } from "node:path";
@@ -19854,7 +19877,8 @@ var KNOWN_RUNTIMES;
19854
19877
  var init_runtimes = __esm({
19855
19878
  "src/runtimes.ts"() {
19856
19879
  "use strict";
19857
- KNOWN_RUNTIMES = [
19880
+ init_immutable();
19881
+ KNOWN_RUNTIMES = deepFreeze([
19858
19882
  {
19859
19883
  id: "claude-code",
19860
19884
  // Markers are Claude Code files `init` never writes, so detection never mistakes
@@ -19891,11 +19915,22 @@ var init_runtimes = __esm({
19891
19915
  adapterTracking: "#482",
19892
19916
  note: "agent-neutral layers (pre-commit + CI) today; a native in-loop adapter is tracked in #482."
19893
19917
  }
19894
- ];
19918
+ ]);
19895
19919
  }
19896
19920
  });
19897
19921
 
19898
19922
  // src/adapters/contract.ts
19923
+ function immutableRuntimeCapabilities(caps) {
19924
+ return Object.freeze({
19925
+ preDeny: Object.freeze([...caps.preDeny]),
19926
+ postObserve: Object.freeze([...caps.postObserve]),
19927
+ endOfTurn: caps.endOfTurn,
19928
+ unsupported: Object.freeze([...caps.unsupported])
19929
+ });
19930
+ }
19931
+ function immutableRuntimeAdapter(adapter) {
19932
+ return Object.freeze(adapter);
19933
+ }
19899
19934
  function unknownToolFinding(toolName) {
19900
19935
  const name = toolName.length > 80 ? toolName.slice(0, 77) + "..." : toolName;
19901
19936
  const detail = 'Copilot tool "' + name + `" is not in TamperWard's explicit operation vocabulary`;
@@ -19923,11 +19958,22 @@ function failClosedResult(outcome, detail, phase, denyPayload) {
19923
19958
  const wire = denyPayload(findings, phase);
19924
19959
  return { outcome, detail, wire, decision: { verdict: "deny", findings, reason: wire } };
19925
19960
  }
19926
- var OPERATION_KINDS;
19961
+ var STEERING_PHASES, CONTRACT_TO_RESEARCH_LAYER, OPERATION_KINDS;
19927
19962
  var init_contract = __esm({
19928
19963
  "src/adapters/contract.ts"() {
19929
19964
  "use strict";
19930
- OPERATION_KINDS = ["shell", "file-edit", "file-read", "mcp", "other"];
19965
+ init_immutable();
19966
+ STEERING_PHASES = Object.freeze(["pre-action", "post-action", "end-of-turn"]);
19967
+ CONTRACT_TO_RESEARCH_LAYER = deepFreeze([
19968
+ { source: "pre-action", layer: "pre-tool-use", note: "synchronous pre-execution deny (Claude PreToolUse)" },
19969
+ { source: "end-of-turn", layer: "stop-sweep", note: "mandatory end-of-turn reconciliation (Claude Stop)" },
19970
+ {
19971
+ source: "post-exit-envelope",
19972
+ layer: "envelope",
19973
+ note: "the run envelope around the whole agent process; post-action outcome observation lives here, not in a per-tool veto"
19974
+ }
19975
+ ]);
19976
+ OPERATION_KINDS = Object.freeze(["shell", "file-edit", "file-read", "mcp", "other"]);
19931
19977
  }
19932
19978
  });
19933
19979
 
@@ -19963,7 +20009,7 @@ var init_adapter = __esm({
19963
20009
  init_contract();
19964
20010
  ClaudeRuntimeAdapter = class {
19965
20011
  name = "claude-code";
19966
- capabilities = {
20012
+ capabilities = immutableRuntimeCapabilities({
19967
20013
  preDeny: OPERATION_KINDS.filter((kind) => kind !== "mcp" && kind !== "other"),
19968
20014
  postObserve: [],
19969
20015
  endOfTurn: true,
@@ -19974,7 +20020,7 @@ var init_adapter = __esm({
19974
20020
  "network-egress control",
19975
20021
  "identity / authentication"
19976
20022
  ]
19977
- };
20023
+ });
19978
20024
  parseEvent(raw, phase) {
19979
20025
  try {
19980
20026
  return eventFrom(parseInput(raw), phase);
@@ -20071,7 +20117,7 @@ var init_adapter = __esm({
20071
20117
  return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
20072
20118
  }
20073
20119
  };
20074
- claudeAdapter = new ClaudeRuntimeAdapter();
20120
+ claudeAdapter = immutableRuntimeAdapter(new ClaudeRuntimeAdapter());
20075
20121
  }
20076
20122
  });
20077
20123
 
@@ -20373,7 +20419,7 @@ var init_adapter2 = __esm({
20373
20419
  * stop, so those are declared; every real gap is named in `unsupported`. The
20374
20420
  * `probe:codex-runtime` harness is what may later justify moving a kind into `preDeny`.
20375
20421
  */
20376
- capabilities = {
20422
+ capabilities = immutableRuntimeCapabilities({
20377
20423
  preDeny: [],
20378
20424
  postObserve: POST_OBSERVE,
20379
20425
  endOfTurn: true,
@@ -20383,7 +20429,7 @@ var init_adapter2 = __esm({
20383
20429
  "network-egress control",
20384
20430
  "identity / authentication"
20385
20431
  ]
20386
- };
20432
+ });
20387
20433
  parseEvent(raw, phase) {
20388
20434
  return normalizeCodexEvent(raw, phase);
20389
20435
  }
@@ -20462,7 +20508,7 @@ var init_adapter2 = __esm({
20462
20508
  return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
20463
20509
  }
20464
20510
  };
20465
- codexAdapter = new CodexRuntimeAdapter();
20511
+ codexAdapter = immutableRuntimeAdapter(new CodexRuntimeAdapter());
20466
20512
  }
20467
20513
  });
20468
20514
 
@@ -20703,7 +20749,7 @@ var init_adapter3 = __esm({
20703
20749
  * does not report. Every real gap is named in `unsupported`. The `probe:copilot-runtime`
20704
20750
  * harness is what may later justify moving a kind into `preDeny` or populating `postObserve`.
20705
20751
  */
20706
- capabilities = {
20752
+ capabilities = immutableRuntimeCapabilities({
20707
20753
  preDeny: [],
20708
20754
  postObserve: [],
20709
20755
  endOfTurn: true,
@@ -20717,7 +20763,7 @@ var init_adapter3 = __esm({
20717
20763
  "network-egress control",
20718
20764
  "identity / authentication"
20719
20765
  ]
20720
- };
20766
+ });
20721
20767
  parseEvent(raw, phase) {
20722
20768
  return normalizeCopilotEvent(raw, phase);
20723
20769
  }
@@ -20812,7 +20858,7 @@ var init_adapter3 = __esm({
20812
20858
  return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
20813
20859
  }
20814
20860
  };
20815
- copilotAdapter = new CopilotRuntimeAdapter();
20861
+ copilotAdapter = immutableRuntimeAdapter(new CopilotRuntimeAdapter());
20816
20862
  }
20817
20863
  });
20818
20864
 
@@ -21150,7 +21196,7 @@ var init_adapter4 = __esm({
21150
21196
  * no post-execution veto). `endOfTurn` is true via `onAgentStop`. Every real gap is named in
21151
21197
  * `unsupported`, at the granularity #611 asks for.
21152
21198
  */
21153
- capabilities = {
21199
+ capabilities = immutableRuntimeCapabilities({
21154
21200
  preDeny: [],
21155
21201
  postObserve: [],
21156
21202
  endOfTurn: true,
@@ -21162,7 +21208,7 @@ var init_adapter4 = __esm({
21162
21208
  "network-egress control",
21163
21209
  "identity / authentication"
21164
21210
  ]
21165
- };
21211
+ });
21166
21212
  parseEvent(raw, phase) {
21167
21213
  return normalizeCopilotSdkEvent(raw, phase);
21168
21214
  }
@@ -21257,7 +21303,7 @@ var init_adapter4 = __esm({
21257
21303
  return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
21258
21304
  }
21259
21305
  };
21260
- copilotSdkAdapter = new CopilotSdkHostedAdapter();
21306
+ copilotSdkAdapter = immutableRuntimeAdapter(new CopilotSdkHostedAdapter());
21261
21307
  }
21262
21308
  });
21263
21309
 
@@ -21277,24 +21323,24 @@ var init_registry = __esm({
21277
21323
  init_adapter2();
21278
21324
  init_adapter3();
21279
21325
  init_adapter4();
21280
- RUNTIME_ADAPTERS = [
21326
+ RUNTIME_ADAPTERS = Object.freeze([
21281
21327
  claudeAdapter,
21282
21328
  codexAdapter,
21283
21329
  copilotAdapter,
21284
21330
  copilotSdkAdapter
21285
- ];
21286
- ADAPTER_LABELS = {
21331
+ ]);
21332
+ ADAPTER_LABELS = Object.freeze({
21287
21333
  "claude-code": "Claude Code",
21288
21334
  codex: "Codex",
21289
21335
  "github-copilot-cli": "GitHub Copilot CLI",
21290
21336
  "github-copilot-sdk-hosted": "GitHub Copilot SDK (hosted)"
21291
- };
21292
- ADAPTER_ALIASES = {
21337
+ });
21338
+ ADAPTER_ALIASES = Object.freeze({
21293
21339
  claude: "claude-code",
21294
21340
  copilot: "github-copilot-cli",
21295
21341
  "copilot-cli": "github-copilot-cli",
21296
21342
  "copilot-sdk": "github-copilot-sdk-hosted"
21297
- };
21343
+ });
21298
21344
  }
21299
21345
  });
21300
21346
 
@@ -21319,7 +21365,8 @@ var RETAINED_EVIDENCE;
21319
21365
  var init_evidence = __esm({
21320
21366
  "src/adapters/evidence.ts"() {
21321
21367
  "use strict";
21322
- RETAINED_EVIDENCE = [
21368
+ init_immutable();
21369
+ RETAINED_EVIDENCE = deepFreeze([
21323
21370
  {
21324
21371
  ref: "copilot-sdk-capture-2026-09-20",
21325
21372
  source: "harness/adapters/copilot-sdk/evidence/capture-2026-09-20.json",
@@ -21360,7 +21407,7 @@ var init_evidence = __esm({
21360
21407
  }
21361
21408
  ]
21362
21409
  }
21363
- ];
21410
+ ]);
21364
21411
  }
21365
21412
  });
21366
21413
 
@@ -21579,19 +21626,19 @@ function evidenceId(binding, assessments) {
21579
21626
  };
21580
21627
  return sha16(JSON.stringify(projection));
21581
21628
  }
21582
- var CAPABILITY_STATES, RUNTIME_CAPABILITY_IDS, EVIDENCE_SOURCES, FINAL_AUTHORITY, FAIL_OPEN_RE, PRE_DENY_UNPROVEN_RE, TRANSPORT_UNPROVEN_RE, LIFECYCLE_ONLY_RE, POST_ACTION_RE, TRANSPORT_KEYWORDS, PRE_DENY_IDS, REQUIRED_IN_LOOP_IDS;
21629
+ var CAPABILITY_STATES, RUNTIME_CAPABILITY_IDS, EVIDENCE_SOURCES, IN_LOOP_AGGREGATES, FINAL_AUTHORITY, FAIL_OPEN_RE, PRE_DENY_UNPROVEN_RE, TRANSPORT_UNPROVEN_RE, LIFECYCLE_ONLY_RE, POST_ACTION_RE, TRANSPORT_KEYWORDS, PRE_DENY_IDS, REQUIRED_IN_LOOP_IDS;
21583
21630
  var init_runtime_qualification = __esm({
21584
21631
  "src/runtime-qualification.ts"() {
21585
21632
  "use strict";
21586
- CAPABILITY_STATES = [
21633
+ CAPABILITY_STATES = Object.freeze([
21587
21634
  "PROVEN",
21588
21635
  "PARTIAL",
21589
21636
  "UNPROVEN",
21590
21637
  "UNSUPPORTED",
21591
21638
  "FAIL-OPEN",
21592
21639
  "INCONCLUSIVE"
21593
- ];
21594
- RUNTIME_CAPABILITY_IDS = [
21640
+ ]);
21641
+ RUNTIME_CAPABILITY_IDS = Object.freeze([
21595
21642
  "pre-deny:shell",
21596
21643
  "pre-deny:native-edit",
21597
21644
  "pre-deny:delete",
@@ -21609,8 +21656,8 @@ var init_runtime_qualification = __esm({
21609
21656
  "transport:empty",
21610
21657
  "hook-not-invoked",
21611
21658
  "detached/quiescence"
21612
- ];
21613
- EVIDENCE_SOURCES = [
21659
+ ]);
21660
+ EVIDENCE_SOURCES = Object.freeze([
21614
21661
  "adapter-declaration",
21615
21662
  // structural preDeny / postObserve / endOfTurn membership
21616
21663
  "adapter-unsupported",
@@ -21621,7 +21668,8 @@ var init_runtime_qualification = __esm({
21621
21668
  // a committed real-runtime evidence record proved it
21622
21669
  "not-declared"
21623
21670
  // absent from every declaration — no proof either way
21624
- ];
21671
+ ]);
21672
+ IN_LOOP_AGGREGATES = Object.freeze(["FULL", "PARTIAL", "NONE"]);
21625
21673
  FINAL_AUTHORITY = "AVAILABLE";
21626
21674
  FAIL_OPEN_RE = /fails?\s+open/i;
21627
21675
  PRE_DENY_UNPROVEN_RE = /pre-action deny|pre-deny|shell pre-deny/i;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.39.1",
3
+ "version": "2.39.3",
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",