tamperward 2.16.3 → 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 +28 -5
- package/dist/cli/index.js +62 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -220,11 +220,34 @@ BROKEN platform posture rather than misdiagnosing it as a missing Python install
|
|
|
220
220
|
`--agent-budget <seconds>`
|
|
221
221
|
adds an operator-owned wall-clock boundary around the same lifecycle (separate from the
|
|
222
222
|
verifier's `--budget`). A clean timeout is `AGENT_TIMEOUT` / exit 124; enforcement or
|
|
223
|
-
cannot-adjudicate still outranks it.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
cannot-adjudicate still outranks it. **From 2.16.4, `tamperward run` is Linux-only
|
|
224
|
+
for authoritative lifecycle certification.** Windows, macOS and other non-Linux platforms
|
|
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. 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.
|
|
228
251
|
|
|
229
252
|
`tamperward verify` materialises two temporary copies — they are **not
|
|
230
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",
|
|
@@ -10601,6 +10639,15 @@ function parseVerify(args) {
|
|
|
10601
10639
|
// src/cli/run.ts
|
|
10602
10640
|
var out = (s) => process.stdout.write(s + "\n");
|
|
10603
10641
|
var err = (s) => process.stderr.write(s + "\n");
|
|
10642
|
+
function authoritativeRunLifecyclePlatform(platform = process.platform) {
|
|
10643
|
+
return platform === "linux";
|
|
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
|
+
}
|
|
10604
10651
|
function canReuseAdjacentDependencyAttestation(_lifecycleOwned, _platform = process.platform) {
|
|
10605
10652
|
return false;
|
|
10606
10653
|
}
|
|
@@ -11211,6 +11258,14 @@ function runEnvelope(opts) {
|
|
|
11211
11258
|
return 2;
|
|
11212
11259
|
}
|
|
11213
11260
|
}
|
|
11261
|
+
const lifecyclePlatform = opts.lifecyclePlatformOverride ?? process.platform;
|
|
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.";
|
|
11264
|
+
err(
|
|
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}`
|
|
11266
|
+
);
|
|
11267
|
+
return 2;
|
|
11268
|
+
}
|
|
11214
11269
|
const verifierBackend = prepareVerifierBackend(frozenPolicy.verify);
|
|
11215
11270
|
out(`tamperward run \u2014 trusted base ${base.slice(0, 10)}; agent exit is untrusted.`);
|
|
11216
11271
|
out(`tamperward run \u2014 verifier backend: ${verifierBackendSummary(verifierBackend)}`);
|
|
@@ -11329,10 +11384,7 @@ tamperward run \u2014 agent exit ${agentExit}; DEPENDENCY_DRIFT \u2192 ENFORCEME
|
|
|
11329
11384
|
verifierBackend
|
|
11330
11385
|
});
|
|
11331
11386
|
if (opts.settle && opts.settle > 0) {
|
|
11332
|
-
|
|
11333
|
-
execFileSync9("sleep", [String(opts.settle)]);
|
|
11334
|
-
} catch {
|
|
11335
|
-
}
|
|
11387
|
+
waitForSettleSync(opts.settle);
|
|
11336
11388
|
}
|
|
11337
11389
|
const mutatedDuringAdjudication = treeFingerprint(cwd, protectedIgnored) !== fpBefore;
|
|
11338
11390
|
if (mutatedDuringAdjudication) {
|
|
@@ -11427,14 +11479,14 @@ function lifecyclePlatformCheck(platform = process.platform, linuxPython = platf
|
|
|
11427
11479
|
if (platform === "win32") {
|
|
11428
11480
|
return {
|
|
11429
11481
|
id: "platform",
|
|
11430
|
-
state: "
|
|
11431
|
-
detail: "Windows: taskkill /T /F is a best-effort tree fallback,
|
|
11482
|
+
state: "BROKEN",
|
|
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."
|
|
11432
11484
|
};
|
|
11433
11485
|
}
|
|
11434
11486
|
return {
|
|
11435
11487
|
id: "platform",
|
|
11436
|
-
state: "
|
|
11437
|
-
detail: `${platform}:
|
|
11488
|
+
state: "BROKEN",
|
|
11489
|
+
detail: `${platform}: authoritative tamperward run lifecycle ownership is unavailable because this release has no subreaper/ECHILD-equivalent backend; run fails closed before agent start. Standalone check/verify remain available.`
|
|
11438
11490
|
};
|
|
11439
11491
|
}
|
|
11440
11492
|
var VERIFY_COMMAND = /\btamperward(?:@\S+)?\s+verify\b/;
|
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",
|