tamperward 2.39.0 → 2.39.2
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/dist/cli/index.js +50 -33
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -19896,6 +19896,17 @@ var init_runtimes = __esm({
|
|
|
19896
19896
|
});
|
|
19897
19897
|
|
|
19898
19898
|
// src/adapters/contract.ts
|
|
19899
|
+
function immutableRuntimeCapabilities(caps) {
|
|
19900
|
+
return Object.freeze({
|
|
19901
|
+
preDeny: Object.freeze([...caps.preDeny]),
|
|
19902
|
+
postObserve: Object.freeze([...caps.postObserve]),
|
|
19903
|
+
endOfTurn: caps.endOfTurn,
|
|
19904
|
+
unsupported: Object.freeze([...caps.unsupported])
|
|
19905
|
+
});
|
|
19906
|
+
}
|
|
19907
|
+
function immutableRuntimeAdapter(adapter) {
|
|
19908
|
+
return Object.freeze(adapter);
|
|
19909
|
+
}
|
|
19899
19910
|
function unknownToolFinding(toolName) {
|
|
19900
19911
|
const name = toolName.length > 80 ? toolName.slice(0, 77) + "..." : toolName;
|
|
19901
19912
|
const detail = 'Copilot tool "' + name + `" is not in TamperWard's explicit operation vocabulary`;
|
|
@@ -19963,23 +19974,18 @@ var init_adapter = __esm({
|
|
|
19963
19974
|
init_contract();
|
|
19964
19975
|
ClaudeRuntimeAdapter = class {
|
|
19965
19976
|
name = "claude-code";
|
|
19966
|
-
|
|
19967
|
-
|
|
19968
|
-
* shell, file edit, file read, MCP, and anything else — even under
|
|
19969
|
-
* `--dangerously-skip-permissions`. The end-of-turn Stop sweep is live too. There is no
|
|
19970
|
-
* live per-tool PostToolUse veto (Stop is the post-turn reconciliation), so `postObserve`
|
|
19971
|
-
* is empty and `unsupported` names that gap explicitly rather than implying it.
|
|
19972
|
-
*/
|
|
19973
|
-
capabilities = {
|
|
19974
|
-
preDeny: OPERATION_KINDS,
|
|
19977
|
+
capabilities = immutableRuntimeCapabilities({
|
|
19978
|
+
preDeny: OPERATION_KINDS.filter((kind) => kind !== "mcp" && kind !== "other"),
|
|
19975
19979
|
postObserve: [],
|
|
19976
19980
|
endOfTurn: true,
|
|
19977
19981
|
unsupported: [
|
|
19982
|
+
"MCP pre-deny is not declared because Claude MCP calls are not reconstructed into Change[] before evaluation",
|
|
19983
|
+
"catch-all other-tool pre-deny is not declared because unmodelled Claude tools are not reconstructed into Change[] before evaluation",
|
|
19978
19984
|
"per-operation post-action veto (end-of-turn Stop sweep is the post-turn reconciliation)",
|
|
19979
19985
|
"network-egress control",
|
|
19980
19986
|
"identity / authentication"
|
|
19981
19987
|
]
|
|
19982
|
-
};
|
|
19988
|
+
});
|
|
19983
19989
|
parseEvent(raw, phase) {
|
|
19984
19990
|
try {
|
|
19985
19991
|
return eventFrom(parseInput(raw), phase);
|
|
@@ -20041,26 +20047,28 @@ var init_adapter = __esm({
|
|
|
20041
20047
|
const parsed = this.parseEvent(raw, phase);
|
|
20042
20048
|
if ("failure" in parsed) {
|
|
20043
20049
|
const live2 = phase === "end-of-turn" ? stopFromRaw(raw, defaultCwd) : preToolUseFromRaw(raw, defaultCwd);
|
|
20050
|
+
const findings2 = live2.findings ? [...live2.findings] : [];
|
|
20044
20051
|
return {
|
|
20045
20052
|
outcome: "parse-failure",
|
|
20046
20053
|
detail: parsed.detail,
|
|
20047
20054
|
wire: live2.stdout,
|
|
20048
|
-
decision: { verdict: "deny", findings:
|
|
20055
|
+
decision: { verdict: "deny", findings: findings2, reason: live2.stdout }
|
|
20049
20056
|
};
|
|
20050
20057
|
}
|
|
20051
20058
|
const idv = this.validateIdentity(parsed.identity, defaultCwd);
|
|
20052
20059
|
if (!idv.ok) {
|
|
20053
|
-
const
|
|
20054
|
-
const wire2 = this.denyPayload(
|
|
20055
|
-
return { outcome: "ok", wire: wire2, detail: idv.rejected, decision: { verdict: "deny", findings, reason: wire2 } };
|
|
20060
|
+
const findings2 = [steeringUnavailableFinding(`repository identity claim rejected: ${idv.rejected}`)];
|
|
20061
|
+
const wire2 = this.denyPayload(findings2, phase);
|
|
20062
|
+
return { outcome: "ok", wire: wire2, detail: idv.rejected, decision: { verdict: "deny", findings: findings2, reason: wire2 } };
|
|
20056
20063
|
}
|
|
20057
20064
|
const live = phase === "end-of-turn" ? stopFromRaw(raw, defaultCwd, idv.trustedRoot) : preToolUseFromRaw(raw, defaultCwd, idv.trustedRoot);
|
|
20058
20065
|
const wire = live.stdout;
|
|
20059
20066
|
const denied = wire.length > 0;
|
|
20067
|
+
const findings = live.findings ? [...live.findings] : [];
|
|
20060
20068
|
return {
|
|
20061
20069
|
outcome: "ok",
|
|
20062
20070
|
wire,
|
|
20063
|
-
decision: { verdict: denied ? "deny" : "allow", findings
|
|
20071
|
+
decision: { verdict: denied ? "deny" : "allow", findings, reason: denied ? wire : void 0 }
|
|
20064
20072
|
};
|
|
20065
20073
|
}
|
|
20066
20074
|
/**
|
|
@@ -20074,7 +20082,7 @@ var init_adapter = __esm({
|
|
|
20074
20082
|
return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
|
|
20075
20083
|
}
|
|
20076
20084
|
};
|
|
20077
|
-
claudeAdapter = new ClaudeRuntimeAdapter();
|
|
20085
|
+
claudeAdapter = immutableRuntimeAdapter(new ClaudeRuntimeAdapter());
|
|
20078
20086
|
}
|
|
20079
20087
|
});
|
|
20080
20088
|
|
|
@@ -20376,7 +20384,7 @@ var init_adapter2 = __esm({
|
|
|
20376
20384
|
* stop, so those are declared; every real gap is named in `unsupported`. The
|
|
20377
20385
|
* `probe:codex-runtime` harness is what may later justify moving a kind into `preDeny`.
|
|
20378
20386
|
*/
|
|
20379
|
-
capabilities = {
|
|
20387
|
+
capabilities = immutableRuntimeCapabilities({
|
|
20380
20388
|
preDeny: [],
|
|
20381
20389
|
postObserve: POST_OBSERVE,
|
|
20382
20390
|
endOfTurn: true,
|
|
@@ -20386,7 +20394,7 @@ var init_adapter2 = __esm({
|
|
|
20386
20394
|
"network-egress control",
|
|
20387
20395
|
"identity / authentication"
|
|
20388
20396
|
]
|
|
20389
|
-
};
|
|
20397
|
+
});
|
|
20390
20398
|
parseEvent(raw, phase) {
|
|
20391
20399
|
return normalizeCodexEvent(raw, phase);
|
|
20392
20400
|
}
|
|
@@ -20439,8 +20447,9 @@ var init_adapter2 = __esm({
|
|
|
20439
20447
|
return { outcome: "ok", wire, detail: idv.rejected, decision: { verdict: "deny", findings, reason: wire } };
|
|
20440
20448
|
}
|
|
20441
20449
|
if (phase === "end-of-turn") {
|
|
20442
|
-
const
|
|
20443
|
-
|
|
20450
|
+
const swept = stopFromRaw(raw, defaultCwd, idv.trustedRoot);
|
|
20451
|
+
const findings = swept.findings ? [...swept.findings] : [];
|
|
20452
|
+
return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
|
|
20444
20453
|
}
|
|
20445
20454
|
try {
|
|
20446
20455
|
const root = idv.trustedRoot ?? repoRoot(defaultCwd ?? process.cwd());
|
|
@@ -20464,7 +20473,7 @@ var init_adapter2 = __esm({
|
|
|
20464
20473
|
return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
|
|
20465
20474
|
}
|
|
20466
20475
|
};
|
|
20467
|
-
codexAdapter = new CodexRuntimeAdapter();
|
|
20476
|
+
codexAdapter = immutableRuntimeAdapter(new CodexRuntimeAdapter());
|
|
20468
20477
|
}
|
|
20469
20478
|
});
|
|
20470
20479
|
|
|
@@ -20705,7 +20714,7 @@ var init_adapter3 = __esm({
|
|
|
20705
20714
|
* does not report. Every real gap is named in `unsupported`. The `probe:copilot-runtime`
|
|
20706
20715
|
* harness is what may later justify moving a kind into `preDeny` or populating `postObserve`.
|
|
20707
20716
|
*/
|
|
20708
|
-
capabilities = {
|
|
20717
|
+
capabilities = immutableRuntimeCapabilities({
|
|
20709
20718
|
preDeny: [],
|
|
20710
20719
|
postObserve: [],
|
|
20711
20720
|
endOfTurn: true,
|
|
@@ -20719,7 +20728,7 @@ var init_adapter3 = __esm({
|
|
|
20719
20728
|
"network-egress control",
|
|
20720
20729
|
"identity / authentication"
|
|
20721
20730
|
]
|
|
20722
|
-
};
|
|
20731
|
+
});
|
|
20723
20732
|
parseEvent(raw, phase) {
|
|
20724
20733
|
return normalizeCopilotEvent(raw, phase);
|
|
20725
20734
|
}
|
|
@@ -20778,12 +20787,13 @@ var init_adapter3 = __esm({
|
|
|
20778
20787
|
if (phase === "end-of-turn") {
|
|
20779
20788
|
const stopInput = copilotStopInput(raw);
|
|
20780
20789
|
if (typeof stopInput !== "string") {
|
|
20781
|
-
const
|
|
20782
|
-
const
|
|
20783
|
-
return { outcome: "parse-failure", detail: stopInput.detail, wire
|
|
20790
|
+
const findings2 = [steeringUnavailableFinding(`unparseable Copilot event: ${stopInput.detail}`)];
|
|
20791
|
+
const wire = this.denyPayload(findings2, "end-of-turn");
|
|
20792
|
+
return { outcome: "parse-failure", detail: stopInput.detail, wire, decision: { verdict: "deny", findings: findings2, reason: wire } };
|
|
20784
20793
|
}
|
|
20785
|
-
const
|
|
20786
|
-
|
|
20794
|
+
const swept = stopFromRaw(stopInput, defaultCwd, idv.trustedRoot);
|
|
20795
|
+
const findings = swept.findings ? [...swept.findings] : [];
|
|
20796
|
+
return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
|
|
20787
20797
|
}
|
|
20788
20798
|
if (parsed.operation.kind === "unknown") {
|
|
20789
20799
|
const detail = `unrecognized Copilot tool ${parsed.operation.name}; refusing to evaluate it as a no-op`;
|
|
@@ -20813,7 +20823,7 @@ var init_adapter3 = __esm({
|
|
|
20813
20823
|
return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
|
|
20814
20824
|
}
|
|
20815
20825
|
};
|
|
20816
|
-
copilotAdapter = new CopilotRuntimeAdapter();
|
|
20826
|
+
copilotAdapter = immutableRuntimeAdapter(new CopilotRuntimeAdapter());
|
|
20817
20827
|
}
|
|
20818
20828
|
});
|
|
20819
20829
|
|
|
@@ -21151,7 +21161,7 @@ var init_adapter4 = __esm({
|
|
|
21151
21161
|
* no post-execution veto). `endOfTurn` is true via `onAgentStop`. Every real gap is named in
|
|
21152
21162
|
* `unsupported`, at the granularity #611 asks for.
|
|
21153
21163
|
*/
|
|
21154
|
-
capabilities = {
|
|
21164
|
+
capabilities = immutableRuntimeCapabilities({
|
|
21155
21165
|
preDeny: [],
|
|
21156
21166
|
postObserve: [],
|
|
21157
21167
|
endOfTurn: true,
|
|
@@ -21163,7 +21173,7 @@ var init_adapter4 = __esm({
|
|
|
21163
21173
|
"network-egress control",
|
|
21164
21174
|
"identity / authentication"
|
|
21165
21175
|
]
|
|
21166
|
-
};
|
|
21176
|
+
});
|
|
21167
21177
|
parseEvent(raw, phase) {
|
|
21168
21178
|
return normalizeCopilotSdkEvent(raw, phase);
|
|
21169
21179
|
}
|
|
@@ -21258,7 +21268,7 @@ var init_adapter4 = __esm({
|
|
|
21258
21268
|
return failClosedResult(outcome, detail, phase, (f, p) => this.denyPayload(f, p));
|
|
21259
21269
|
}
|
|
21260
21270
|
};
|
|
21261
|
-
copilotSdkAdapter = new CopilotSdkHostedAdapter();
|
|
21271
|
+
copilotSdkAdapter = immutableRuntimeAdapter(new CopilotSdkHostedAdapter());
|
|
21262
21272
|
}
|
|
21263
21273
|
});
|
|
21264
21274
|
|
|
@@ -21985,7 +21995,8 @@ function storedQualification(adapter, cwd, opts = {}) {
|
|
|
21985
21995
|
const validated = validateStoredReport(raw);
|
|
21986
21996
|
if ("reason" in validated) return { state: "rejected", reason: validated.reason };
|
|
21987
21997
|
const stored = validated.report;
|
|
21988
|
-
const
|
|
21998
|
+
const currentQualification = buildQualification(adapter, opts, cwd);
|
|
21999
|
+
const current = currentQualification.binding;
|
|
21989
22000
|
const storedBinding = {
|
|
21990
22001
|
runtime: stored.runtime,
|
|
21991
22002
|
tamperward: stored.tamperward,
|
|
@@ -21999,6 +22010,12 @@ function storedQualification(adapter, cwd, opts = {}) {
|
|
|
21999
22010
|
evidence_id: stored.evidence_id
|
|
22000
22011
|
};
|
|
22001
22012
|
const staleness = qualificationStaleness(storedBinding, current);
|
|
22013
|
+
if (!staleness.stale && (stored.evidence_id !== current.evidence_id || JSON.stringify(stored.capabilities) !== JSON.stringify(currentQualification.assessments))) {
|
|
22014
|
+
return {
|
|
22015
|
+
state: "rejected",
|
|
22016
|
+
reason: "stored qualification posture does not match retained evidence for the current binding"
|
|
22017
|
+
};
|
|
22018
|
+
}
|
|
22002
22019
|
return { state: "recorded", report: stored, stale: staleness.stale, changed_inputs: staleness.changed };
|
|
22003
22020
|
}
|
|
22004
22021
|
function runRuntime(sub, opts) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.39.
|
|
3
|
+
"version": "2.39.2",
|
|
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",
|