tamperward 2.39.0 → 2.39.1
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 +27 -21
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -19963,18 +19963,13 @@ var init_adapter = __esm({
|
|
|
19963
19963
|
init_contract();
|
|
19964
19964
|
ClaudeRuntimeAdapter = class {
|
|
19965
19965
|
name = "claude-code";
|
|
19966
|
-
/**
|
|
19967
|
-
* Claude Code's live PreToolUse fires for EVERY tool and can synchronously deny it —
|
|
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
19966
|
capabilities = {
|
|
19974
|
-
preDeny: OPERATION_KINDS,
|
|
19967
|
+
preDeny: OPERATION_KINDS.filter((kind) => kind !== "mcp" && kind !== "other"),
|
|
19975
19968
|
postObserve: [],
|
|
19976
19969
|
endOfTurn: true,
|
|
19977
19970
|
unsupported: [
|
|
19971
|
+
"MCP pre-deny is not declared because Claude MCP calls are not reconstructed into Change[] before evaluation",
|
|
19972
|
+
"catch-all other-tool pre-deny is not declared because unmodelled Claude tools are not reconstructed into Change[] before evaluation",
|
|
19978
19973
|
"per-operation post-action veto (end-of-turn Stop sweep is the post-turn reconciliation)",
|
|
19979
19974
|
"network-egress control",
|
|
19980
19975
|
"identity / authentication"
|
|
@@ -20041,26 +20036,28 @@ var init_adapter = __esm({
|
|
|
20041
20036
|
const parsed = this.parseEvent(raw, phase);
|
|
20042
20037
|
if ("failure" in parsed) {
|
|
20043
20038
|
const live2 = phase === "end-of-turn" ? stopFromRaw(raw, defaultCwd) : preToolUseFromRaw(raw, defaultCwd);
|
|
20039
|
+
const findings2 = live2.findings ? [...live2.findings] : [];
|
|
20044
20040
|
return {
|
|
20045
20041
|
outcome: "parse-failure",
|
|
20046
20042
|
detail: parsed.detail,
|
|
20047
20043
|
wire: live2.stdout,
|
|
20048
|
-
decision: { verdict: "deny", findings:
|
|
20044
|
+
decision: { verdict: "deny", findings: findings2, reason: live2.stdout }
|
|
20049
20045
|
};
|
|
20050
20046
|
}
|
|
20051
20047
|
const idv = this.validateIdentity(parsed.identity, defaultCwd);
|
|
20052
20048
|
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 } };
|
|
20049
|
+
const findings2 = [steeringUnavailableFinding(`repository identity claim rejected: ${idv.rejected}`)];
|
|
20050
|
+
const wire2 = this.denyPayload(findings2, phase);
|
|
20051
|
+
return { outcome: "ok", wire: wire2, detail: idv.rejected, decision: { verdict: "deny", findings: findings2, reason: wire2 } };
|
|
20056
20052
|
}
|
|
20057
20053
|
const live = phase === "end-of-turn" ? stopFromRaw(raw, defaultCwd, idv.trustedRoot) : preToolUseFromRaw(raw, defaultCwd, idv.trustedRoot);
|
|
20058
20054
|
const wire = live.stdout;
|
|
20059
20055
|
const denied = wire.length > 0;
|
|
20056
|
+
const findings = live.findings ? [...live.findings] : [];
|
|
20060
20057
|
return {
|
|
20061
20058
|
outcome: "ok",
|
|
20062
20059
|
wire,
|
|
20063
|
-
decision: { verdict: denied ? "deny" : "allow", findings
|
|
20060
|
+
decision: { verdict: denied ? "deny" : "allow", findings, reason: denied ? wire : void 0 }
|
|
20064
20061
|
};
|
|
20065
20062
|
}
|
|
20066
20063
|
/**
|
|
@@ -20439,8 +20436,9 @@ var init_adapter2 = __esm({
|
|
|
20439
20436
|
return { outcome: "ok", wire, detail: idv.rejected, decision: { verdict: "deny", findings, reason: wire } };
|
|
20440
20437
|
}
|
|
20441
20438
|
if (phase === "end-of-turn") {
|
|
20442
|
-
const
|
|
20443
|
-
|
|
20439
|
+
const swept = stopFromRaw(raw, defaultCwd, idv.trustedRoot);
|
|
20440
|
+
const findings = swept.findings ? [...swept.findings] : [];
|
|
20441
|
+
return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
|
|
20444
20442
|
}
|
|
20445
20443
|
try {
|
|
20446
20444
|
const root = idv.trustedRoot ?? repoRoot(defaultCwd ?? process.cwd());
|
|
@@ -20778,12 +20776,13 @@ var init_adapter3 = __esm({
|
|
|
20778
20776
|
if (phase === "end-of-turn") {
|
|
20779
20777
|
const stopInput = copilotStopInput(raw);
|
|
20780
20778
|
if (typeof stopInput !== "string") {
|
|
20781
|
-
const
|
|
20782
|
-
const
|
|
20783
|
-
return { outcome: "parse-failure", detail: stopInput.detail, wire
|
|
20779
|
+
const findings2 = [steeringUnavailableFinding(`unparseable Copilot event: ${stopInput.detail}`)];
|
|
20780
|
+
const wire = this.denyPayload(findings2, "end-of-turn");
|
|
20781
|
+
return { outcome: "parse-failure", detail: stopInput.detail, wire, decision: { verdict: "deny", findings: findings2, reason: wire } };
|
|
20784
20782
|
}
|
|
20785
|
-
const
|
|
20786
|
-
|
|
20783
|
+
const swept = stopFromRaw(stopInput, defaultCwd, idv.trustedRoot);
|
|
20784
|
+
const findings = swept.findings ? [...swept.findings] : [];
|
|
20785
|
+
return { outcome: "ok", wire: swept.stdout, decision: { verdict: swept.stdout ? "deny" : "allow", findings, reason: swept.stdout || void 0 } };
|
|
20787
20786
|
}
|
|
20788
20787
|
if (parsed.operation.kind === "unknown") {
|
|
20789
20788
|
const detail = `unrecognized Copilot tool ${parsed.operation.name}; refusing to evaluate it as a no-op`;
|
|
@@ -21985,7 +21984,8 @@ function storedQualification(adapter, cwd, opts = {}) {
|
|
|
21985
21984
|
const validated = validateStoredReport(raw);
|
|
21986
21985
|
if ("reason" in validated) return { state: "rejected", reason: validated.reason };
|
|
21987
21986
|
const stored = validated.report;
|
|
21988
|
-
const
|
|
21987
|
+
const currentQualification = buildQualification(adapter, opts, cwd);
|
|
21988
|
+
const current = currentQualification.binding;
|
|
21989
21989
|
const storedBinding = {
|
|
21990
21990
|
runtime: stored.runtime,
|
|
21991
21991
|
tamperward: stored.tamperward,
|
|
@@ -21999,6 +21999,12 @@ function storedQualification(adapter, cwd, opts = {}) {
|
|
|
21999
21999
|
evidence_id: stored.evidence_id
|
|
22000
22000
|
};
|
|
22001
22001
|
const staleness = qualificationStaleness(storedBinding, current);
|
|
22002
|
+
if (!staleness.stale && (stored.evidence_id !== current.evidence_id || JSON.stringify(stored.capabilities) !== JSON.stringify(currentQualification.assessments))) {
|
|
22003
|
+
return {
|
|
22004
|
+
state: "rejected",
|
|
22005
|
+
reason: "stored qualification posture does not match retained evidence for the current binding"
|
|
22006
|
+
};
|
|
22007
|
+
}
|
|
22002
22008
|
return { state: "recorded", report: stored, stale: staleness.stale, changed_inputs: staleness.changed };
|
|
22003
22009
|
}
|
|
22004
22010
|
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.1",
|
|
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",
|