tamperward 2.16.4 → 2.16.5
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/README.md +25 -3
- package/dist/cli/index.js +50 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,9 +223,31 @@ verifier's `--budget`). A clean timeout is `AGENT_TIMEOUT` / exit 124; enforceme
|
|
|
223
223
|
cannot-adjudicate still outranks it. **From 2.16.4, `tamperward run` is Linux-only
|
|
224
224
|
for authoritative lifecycle certification.** Windows, macOS and other non-Linux platforms
|
|
225
225
|
fail closed before the agent starts because this release has no OS primitive there that can
|
|
226
|
-
prove the detached execution domain is drained.
|
|
227
|
-
`tamperward verify`
|
|
228
|
-
|
|
226
|
+
prove the detached execution domain is drained. From **2.16.5**, checkpointed-local
|
|
227
|
+
`tamperward verify` also has an explicit host-shell contract: Linux, macOS and the
|
|
228
|
+
supported POSIX Node platforms use `/bin/sh -c`; Windows local verification fails closed
|
|
229
|
+
before candidate execution rather than depending on an incidental MSYS/Git-for-Windows
|
|
230
|
+
`sh` on PATH. A digest-pinned container verifier is a separate backend and must pass its
|
|
231
|
+
own Docker authority preflight. Dependency-attestation reuse remains disabled on all
|
|
232
|
+
platforms.
|
|
233
|
+
|
|
234
|
+
### Platform support
|
|
235
|
+
|
|
236
|
+
| Capability | Linux | macOS | Windows |
|
|
237
|
+
| --- | --- | --- | --- |
|
|
238
|
+
| `check` / policy evaluation | Supported | Supported | Supported |
|
|
239
|
+
| Claude hook / Stop adapter | Supported where Claude Code command hooks are available | Same | Same |
|
|
240
|
+
| `watch` / observer telemetry | Supported; backend health is reported | Supported/degraded according to `fs.watch` health | Supported/degraded according to `fs.watch` health |
|
|
241
|
+
| checkpointed-local `verify` | Supported via `/bin/sh` | Supported via `/bin/sh` | **Unsupported; fails before candidate execution** |
|
|
242
|
+
| isolated-container `verify` | Supported when Docker authority preflight passes | Not claimed beyond Docker preflight | Not claimed beyond Docker preflight |
|
|
243
|
+
| authoritative `run` | **Supported only with trusted non-root subreaper backend** | **Unsupported; fails before agent start** | **Unsupported; fails before agent start** |
|
|
244
|
+
| CI coverage for this contract | Full suite + platform contract | Platform-contract job | Platform-contract job |
|
|
245
|
+
|
|
246
|
+
The platform-contract CI job runs on real `ubuntu-latest`, `macos-latest` and
|
|
247
|
+
`windows-latest` hosts. It verifies the declared shell/lifecycle selection and proves
|
|
248
|
+
that Windows local verification refuses before a candidate command can produce a side
|
|
249
|
+
effect. This matrix is intentionally narrower than the Linux adversarial suite; it tests
|
|
250
|
+
the support boundary rather than implying feature parity where none is claimed.
|
|
229
251
|
|
|
230
252
|
`tamperward verify` materialises two temporary copies — they are **not
|
|
231
253
|
sandboxes**, and both execute agent-controlled code. The visible copy runs the
|
package/dist/cli/index.js
CHANGED
|
@@ -10218,15 +10218,37 @@ function suiteEnv(scratch) {
|
|
|
10218
10218
|
env.YARN_IGNORE_PATH = "1";
|
|
10219
10219
|
return env;
|
|
10220
10220
|
}
|
|
10221
|
+
function localVerifierShell(platform = process.platform, command) {
|
|
10222
|
+
switch (platform) {
|
|
10223
|
+
case "linux":
|
|
10224
|
+
case "darwin":
|
|
10225
|
+
case "freebsd":
|
|
10226
|
+
case "openbsd":
|
|
10227
|
+
case "aix":
|
|
10228
|
+
case "sunos":
|
|
10229
|
+
return { executable: "/bin/sh", args: ["-c", command] };
|
|
10230
|
+
default:
|
|
10231
|
+
return null;
|
|
10232
|
+
}
|
|
10233
|
+
}
|
|
10221
10234
|
function runLocalSuite(dir, cmd, budgetSecs) {
|
|
10222
10235
|
const t0 = Date.now();
|
|
10236
|
+
const shell = localVerifierShell(process.platform, cmd);
|
|
10237
|
+
if (!shell) {
|
|
10238
|
+
return {
|
|
10239
|
+
exit: null,
|
|
10240
|
+
secs: 0,
|
|
10241
|
+
failure: "backend",
|
|
10242
|
+
reason: `checkpointed-local verifier is unsupported on ${process.platform}; no trusted local shell contract is defined`
|
|
10243
|
+
};
|
|
10244
|
+
}
|
|
10223
10245
|
const scratch = mkdtempSync3(join16(tmpdir3(), "tw-verify-run-"));
|
|
10224
10246
|
try {
|
|
10225
|
-
const r = runCapturedProcessSync(
|
|
10247
|
+
const r = runCapturedProcessSync(shell.executable, shell.args, {
|
|
10226
10248
|
cwd: dir,
|
|
10227
10249
|
env: suiteEnv(scratch),
|
|
10228
10250
|
timeoutMs: budgetSecs * 1e3,
|
|
10229
|
-
detached:
|
|
10251
|
+
detached: true,
|
|
10230
10252
|
killGroupOnFinish: true,
|
|
10231
10253
|
backstopMs: 3e4
|
|
10232
10254
|
});
|
|
@@ -10339,6 +10361,22 @@ function runVerify(opts) {
|
|
|
10339
10361
|
return 2;
|
|
10340
10362
|
}
|
|
10341
10363
|
const isolated = verifierBackend.kind === "container";
|
|
10364
|
+
if (!isolated && !localVerifierShell(process.platform, cmd)) {
|
|
10365
|
+
if (opts.json) {
|
|
10366
|
+
out2(JSON.stringify({
|
|
10367
|
+
verdict: "CANNOT_VERIFY",
|
|
10368
|
+
reason: "LOCAL_VERIFIER_UNSUPPORTED_PLATFORM",
|
|
10369
|
+
platform: process.platform,
|
|
10370
|
+
verifier_backend: backendReport(),
|
|
10371
|
+
oracle_assurance: oracleAssuranceReport()
|
|
10372
|
+
}));
|
|
10373
|
+
} else {
|
|
10374
|
+
out2(
|
|
10375
|
+
`verify: checkpointed-local verifier is unsupported on ${process.platform}; no trusted local shell contract is defined. Failing closed before candidate execution.`
|
|
10376
|
+
);
|
|
10377
|
+
}
|
|
10378
|
+
return 2;
|
|
10379
|
+
}
|
|
10342
10380
|
const dependencyEnvironment = isolated ? null : opts.dependencyEnvironment ?? discoverDependencyEnvironment(cwd, cmd);
|
|
10343
10381
|
const dependencyReport = () => dependencyEnvironment ? dependencyEnvironmentReport(dependencyEnvironment) : {
|
|
10344
10382
|
status: "verifier-owned",
|
|
@@ -10604,6 +10642,12 @@ var err = (s) => process.stderr.write(s + "\n");
|
|
|
10604
10642
|
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
10605
10643
|
return platform === "linux";
|
|
10606
10644
|
}
|
|
10645
|
+
function waitForSettleSync(seconds) {
|
|
10646
|
+
if (!Number.isFinite(seconds) || seconds <= 0) return;
|
|
10647
|
+
const ms = Math.ceil(seconds * 1e3);
|
|
10648
|
+
const word = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
10649
|
+
Atomics.wait(word, 0, 0, ms);
|
|
10650
|
+
}
|
|
10607
10651
|
function canReuseAdjacentDependencyAttestation(_lifecycleOwned, _platform = process.platform) {
|
|
10608
10652
|
return false;
|
|
10609
10653
|
}
|
|
@@ -11216,8 +11260,9 @@ function runEnvelope(opts) {
|
|
|
11216
11260
|
}
|
|
11217
11261
|
const lifecyclePlatform = opts.lifecyclePlatformOverride ?? process.platform;
|
|
11218
11262
|
if (!authoritativeRunLifecyclePlatform(lifecyclePlatform)) {
|
|
11263
|
+
const alternative = lifecyclePlatform === "win32" ? "Use standalone tamperward check; checkpointed-local verify is unsupported on Windows, while container verify must pass its own Docker authority preflight." : "Use standalone tamperward check/verify or an isolated execution domain.";
|
|
11219
11264
|
err(
|
|
11220
|
-
`tamperward run: authoritative agent lifecycle ownership is unavailable on ${lifecyclePlatform}; this release only certifies run on Linux with the trusted subreaper/ECHILD backend. Failing closed before the agent starts.
|
|
11265
|
+
`tamperward run: authoritative agent lifecycle ownership is unavailable on ${lifecyclePlatform}; this release only certifies run on Linux with the trusted subreaper/ECHILD backend. Failing closed before the agent starts. ${alternative}`
|
|
11221
11266
|
);
|
|
11222
11267
|
return 2;
|
|
11223
11268
|
}
|
|
@@ -11339,10 +11384,7 @@ tamperward run \u2014 agent exit ${agentExit}; DEPENDENCY_DRIFT \u2192 ENFORCEME
|
|
|
11339
11384
|
verifierBackend
|
|
11340
11385
|
});
|
|
11341
11386
|
if (opts.settle && opts.settle > 0) {
|
|
11342
|
-
|
|
11343
|
-
execFileSync9("sleep", [String(opts.settle)]);
|
|
11344
|
-
} catch {
|
|
11345
|
-
}
|
|
11387
|
+
waitForSettleSync(opts.settle);
|
|
11346
11388
|
}
|
|
11347
11389
|
const mutatedDuringAdjudication = treeFingerprint(cwd, protectedIgnored) !== fpBefore;
|
|
11348
11390
|
if (mutatedDuringAdjudication) {
|
|
@@ -11438,7 +11480,7 @@ function lifecyclePlatformCheck(platform = process.platform, linuxPython = platf
|
|
|
11438
11480
|
return {
|
|
11439
11481
|
id: "platform",
|
|
11440
11482
|
state: "BROKEN",
|
|
11441
|
-
detail: "Windows: authoritative tamperward run lifecycle ownership is unavailable; taskkill /T /F is only a best-effort tree fallback, so run fails closed before agent start. Standalone check
|
|
11483
|
+
detail: "Windows: authoritative tamperward run lifecycle ownership is unavailable; taskkill /T /F is only a best-effort tree fallback, so run fails closed before agent start. Standalone check remains available; checkpointed-local verify is unsupported because this release defines verifier command semantics only through POSIX /bin/sh. A container verifier must pass its own Docker authority preflight."
|
|
11442
11484
|
};
|
|
11443
11485
|
}
|
|
11444
11486
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tamperward",
|
|
3
|
-
"version": "2.16.
|
|
3
|
+
"version": "2.16.5",
|
|
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",
|