tamperward 1.10.0 → 1.10.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 +24 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2932,6 +2932,21 @@ function runEnvelope(opts) {
|
|
|
2932
2932
|
err(`tamperward run: cannot resolve trusted base ${opts.base ?? "HEAD"} \u2014 failing closed.`);
|
|
2933
2933
|
return 2;
|
|
2934
2934
|
}
|
|
2935
|
+
let frozenCmd;
|
|
2936
|
+
let frozenBudget;
|
|
2937
|
+
try {
|
|
2938
|
+
const entryPolicy = loadPolicy(cwd);
|
|
2939
|
+
frozenCmd = opts.cmd ?? entryPolicy.verify?.command;
|
|
2940
|
+
frozenBudget = opts.budget ?? entryPolicy.verify?.budget;
|
|
2941
|
+
} catch (e) {
|
|
2942
|
+
err(`tamperward run: cannot load the entry-time policy (${e instanceof Error ? e.message : String(e)}) \u2014 failing closed.`);
|
|
2943
|
+
return 2;
|
|
2944
|
+
}
|
|
2945
|
+
if (!frozenCmd) {
|
|
2946
|
+
err("tamperward run: no suite command at entry (policy `verify: { command: ... }` or --cmd) \u2014");
|
|
2947
|
+
err("refusing to start: a verifier that appears after the agent runs would be agent-authored.");
|
|
2948
|
+
return 2;
|
|
2949
|
+
}
|
|
2935
2950
|
if (!opts.allowDirty) {
|
|
2936
2951
|
const dirty = git3(["status", "--porcelain"], cwd).trim();
|
|
2937
2952
|
if (dirty) {
|
|
@@ -2944,6 +2959,14 @@ function runEnvelope(opts) {
|
|
|
2944
2959
|
const agent = spawnSync2(opts.argv[0], opts.argv.slice(1), { cwd, stdio: "inherit" });
|
|
2945
2960
|
const agentExit = agent.status ?? 1;
|
|
2946
2961
|
const head = git3(["rev-parse", "HEAD"], cwd).trim();
|
|
2962
|
+
const isAncestor = spawnSync2("git", ["merge-base", "--is-ancestor", base, head], { cwd });
|
|
2963
|
+
if (isAncestor.status !== 0) {
|
|
2964
|
+
err(`tamperward run: HEAD ${head.slice(0, 10)} is not a descendant of the trusted base ${base.slice(0, 10)} \u2014`);
|
|
2965
|
+
err("the agent rewrote history out from under the anchor. That is the finding.");
|
|
2966
|
+
out(`
|
|
2967
|
+
tamperward run \u2014 agent exit ${agentExit}; HISTORY_REWRITE \u2192 ENFORCEMENT_FAILED`);
|
|
2968
|
+
return 1;
|
|
2969
|
+
}
|
|
2947
2970
|
let diffCode = 0;
|
|
2948
2971
|
if (head !== base) {
|
|
2949
2972
|
out(`
|
|
@@ -2953,7 +2976,7 @@ function runEnvelope(opts) {
|
|
|
2953
2976
|
out("\n[envelope] policy check over the working tree:");
|
|
2954
2977
|
const workCode = runCheck({ worktree: true, cwd });
|
|
2955
2978
|
out("\n[envelope] pristine verification against the trusted base:");
|
|
2956
|
-
const verifyCode = runVerify({ cwd, base, cmd:
|
|
2979
|
+
const verifyCode = runVerify({ cwd, base, cmd: frozenCmd, budget: frozenBudget });
|
|
2957
2980
|
const cannot = diffCode === 2 || workCode === 2 || verifyCode === 2;
|
|
2958
2981
|
const blocked = diffCode === 1 || workCode === 1 || verifyCode === 1;
|
|
2959
2982
|
const enforcement = cannot ? 2 : blocked ? 1 : 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.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",
|