tamperward 2.18.0 → 2.20.0
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 +58 -5
- package/dist/cli/index.js +840 -453
- package/package.json +4 -2
- package/schemas/check-v1.schema.json +104 -0
- package/schemas/doctor-v1.schema.json +95 -0
- package/schemas/run-v1.schema.json +508 -0
- package/schemas/verify-v1.schema.json +606 -0
package/README.md
CHANGED
|
@@ -482,6 +482,50 @@ deliberately refuses `backend: container` before launching the agent because the
|
|
|
482
482
|
would share the host identity that controls Docker. Use isolated `tamperward verify`
|
|
483
483
|
from trusted CI, or after an externally isolated agent hands off the frozen candidate.
|
|
484
484
|
|
|
485
|
+
### Machine-readable verdict API
|
|
486
|
+
|
|
487
|
+
From **2.19.0**, the public JSON verdict surfaces are versioned independently of the
|
|
488
|
+
npm package version. `check --json`, `verify --json`, `run --json`, and
|
|
489
|
+
`doctor --json` include top-level `"schema_version": 1`. TamperWard publishes the
|
|
490
|
+
corresponding JSON Schema Draft 2020-12 documents in the npm package and repository:
|
|
491
|
+
|
|
492
|
+
- [`schemas/check-v1.schema.json`](./schemas/check-v1.schema.json)
|
|
493
|
+
- [`schemas/verify-v1.schema.json`](./schemas/verify-v1.schema.json)
|
|
494
|
+
- [`schemas/run-v1.schema.json`](./schemas/run-v1.schema.json)
|
|
495
|
+
- [`schemas/doctor-v1.schema.json`](./schemas/doctor-v1.schema.json)
|
|
496
|
+
|
|
497
|
+
Schema major **1** is deliberately additive: consumers should ignore fields they do not
|
|
498
|
+
understand. Adding new evidence/diagnostic fields does not require a schema bump.
|
|
499
|
+
Removing or renaming a required field, changing its type, or changing the meaning of a
|
|
500
|
+
discriminator requires `schema_version: 2` and new `*-v2.schema.json` files; the v1
|
|
501
|
+
files remain published for existing integrations.
|
|
502
|
+
|
|
503
|
+
`run --json` owns stdout after the wrapped agent starts and emits one final envelope
|
|
504
|
+
document, including post-agent early convictions such as `OBJECT_REWRITE`,
|
|
505
|
+
`HISTORY_REWRITE`, `DEPENDENCY_DRIFT`, or lifecycle cannot-adjudicate. In this mode the
|
|
506
|
+
agent's own stdout is routed to stderr (its stderr is unchanged), so stdout carries
|
|
507
|
+
exactly one document however noisy the agent is. The document's `complete` field says
|
|
508
|
+
whether the full post-agent adjudication ran: `true` documents carry `head`,
|
|
509
|
+
`checks.{diff,worktree,verify}` and `observer`; early convictions and lifecycle refusals
|
|
510
|
+
are `complete: false`. A `CANNOT_ADJUDICATE` document always names which layer could not
|
|
511
|
+
judge in `reason` (`AGENT_LIFECYCLE_NOT_OWNED`, `VERIFY_CANNOT_VERIFY`,
|
|
512
|
+
`CHECK_DIFF_UNJUDGEABLE`, `CHECK_WORKTREE_UNJUDGEABLE`). Argument, trusted-base, policy,
|
|
513
|
+
dirty-start, and other **pre-agent/preflight** failures still fail closed on stderr at
|
|
514
|
+
exit 2 because no agent adjudication occurred.
|
|
515
|
+
|
|
516
|
+
`verify --json` never falls back to prose: every fail-closed exit before a verdict exists
|
|
517
|
+
is a `CANNOT_VERIFY` document whose `reason` is one of the enumerated codes in the schema
|
|
518
|
+
(`POLICY_ERROR`, `NO_SUITE_COMMAND`, `VERIFIER_BACKEND_UNAVAILABLE`, `WORKTREE_CHANGED`,
|
|
519
|
+
`PRISTINE_INTEGRITY_CHANGED`, …) with a human `detail` beside it and, once a suite
|
|
520
|
+
execution was in flight, the `stage` it happened in. The reason vocabularies for both
|
|
521
|
+
`verify` and `run` are defined once in the source and asserted equal to the schema enums
|
|
522
|
+
by the test suite, so a new code cannot ship without the contract.
|
|
523
|
+
|
|
524
|
+
The JSON schemas describe **data shape**, not process status. Exit codes are a separate
|
|
525
|
+
public protocol and are documented in the table immediately below. Consumers should
|
|
526
|
+
validate both independently: schema validation answers “can I parse this verdict?”;
|
|
527
|
+
the process exit answers “did the gate allow, block, time out, or fail to adjudicate?”
|
|
528
|
+
|
|
485
529
|
### CLI reference
|
|
486
530
|
|
|
487
531
|
Every flag below is what the command's parser actually reads (`src/cli/main.ts`,
|
|
@@ -498,7 +542,7 @@ option can never be reinterpreted as the agent command.
|
|
|
498
542
|
| `verify` | `--base <rev>` (default `HEAD`) · `--cmd <suite command>` · `--budget <seconds>` · `--json` · `--keep` (keep the two materialised copies and report their paths) · `--require-ancestor` (refuse a base that is not an ancestor of `HEAD`) · `--cwd <dir>` |
|
|
499
543
|
| `trace-verify` | Linux-only advisory discovery: `--base <rev>` (default `HEAD`) · `--cmd <suite command>` · `--budget <seconds>` · `--runs <positive integer>` (default 2) · `--json` · `--cwd <dir>` |
|
|
500
544
|
| `doctor` | `--base <rev>` (trusted policy revision) · `--workflow <path>` · `--cwd <dir>` · `--json` · `--github` · `--repo <owner/repo>` · `--branch <name>` — read-only installation/authority posture plus CI verifier outer-time validation |
|
|
501
|
-
| `run` | `--base <rev>` · `--cmd <suite command>` · `--budget <seconds>` (per verifier suite) · `--agent-budget <seconds>` (optional wrapped-agent wall clock) · `--observe-transients` (start a session-scoped transient observer) · `--allow-dirty` · `--settle <seconds>` (wait before the final quiescence check) · `--allow-dep-drift` · `--cwd <dir>` · then `-- <agent command...>` |
|
|
545
|
+
| `run` | `--base <rev>` · `--cmd <suite command>` · `--budget <seconds>` (per verifier suite) · `--agent-budget <seconds>` (optional wrapped-agent wall clock) · `--json` (one versioned final envelope document) · `--observe-transients` (start a session-scoped transient observer) · `--allow-dirty` · `--settle <seconds>` (wait before the final quiescence check) · `--allow-dep-drift` · `--cwd <dir>` · then `-- <agent command...>` |
|
|
502
546
|
| `allow` | `<rule>` · `--file <path>` · `--reason "<why>"` (required) · `--cwd <dir>` |
|
|
503
547
|
| `init` | `--cwd <dir>` · `--dry-run` · `--force-workflow` |
|
|
504
548
|
| `watch` | `--dir <dir>` · `--log <file>` — a daemon; it runs until signalled |
|
|
@@ -533,12 +577,12 @@ option can never be reinterpreted as the agent command.
|
|
|
533
577
|
|
|
534
578
|
### The rules
|
|
535
579
|
|
|
536
|
-
|
|
580
|
+
Eighteen rules are specified and seventeen ship (see the table in
|
|
537
581
|
[SPEC.md](./SPEC.md)). The families: test protection (`test-deletion`,
|
|
538
582
|
`test-skip`, `test-content-removal`, plus the warning-only JS/TS
|
|
539
583
|
`assertion-weakening` heuristic), verification-signal protection
|
|
540
584
|
(`coverage-lowering`, `snapshot-rewrite`, `snapshot-only-rewrite`), suppression
|
|
541
|
-
(`ts-any-cast`, `ts-any-launder`, `lint-suppression`), pipeline protection
|
|
585
|
+
(`ts-any-cast`, `ts-any-launder`, `ts-cast-growth`, `lint-suppression`), pipeline protection
|
|
542
586
|
(`ci-tampering`, `hook-tampering`, `no-verify`), and the effect/outcome layers
|
|
543
587
|
(`transient-protected-mutation`, `pristine-verification`, plus the `run` envelope).
|
|
544
588
|
`test-skip` keeps the established regex coverage for diff-only inputs and non-JS
|
|
@@ -554,6 +598,12 @@ specificity removed, or a pure assertion removed from the same suite-qualified
|
|
|
554
598
|
test. It measured 12/12 true-positive fires with 0/20 false positives on the
|
|
555
599
|
committed detector-specific replay and remains `warn`; `guard-removal` is still
|
|
556
600
|
reserved with no detector, and `ts-any-launder` is a permanent warn.
|
|
601
|
+
`ts-cast-growth` (2.20.0) is the assertion budget: net growth of ordinary `as T` /
|
|
602
|
+
`<T>x` / `x!` assertions in non-test source, counted on the AST net of casts the same
|
|
603
|
+
change removed, reported as a warning that never blocks by default. It fires on 8.7%
|
|
604
|
+
of legitimate mainline pairs across four real TypeScript libraries
|
|
605
|
+
(`harness/fp-study/CAST-GROWTH-CORPUS.md`), so block is closed by corpus; the same
|
|
606
|
+
pass removed every assertion from TamperWard's own `src/` (`docs/CAST-INVENTORY.md`).
|
|
557
607
|
|
|
558
608
|
## What Tamperward does not do
|
|
559
609
|
|
|
@@ -619,8 +669,11 @@ and the posts in [docs/blog/](./docs/blog/index.md).
|
|
|
619
669
|
## Stability
|
|
620
670
|
|
|
621
671
|
The public surface is the CLI and its **exit codes**, the hook wire format, the
|
|
622
|
-
`.tamperward.yml` schema, and the
|
|
623
|
-
|
|
672
|
+
`.tamperward.yml` schema, and the versioned `check` / `verify` / `run` / `doctor`
|
|
673
|
+
machine-output schemas under `schemas/`. No `main`, no `exports` — it is a binary,
|
|
674
|
+
not a library. The machine-output schema major is intentionally independent of the npm
|
|
675
|
+
version: additive fields stay compatible within the major; breaking shape/semantic
|
|
676
|
+
changes require a new schema major. The version answers one question: *can taking this
|
|
624
677
|
upgrade turn a green build red without me changing anything?* **Patch never can** —
|
|
625
678
|
bypass fixes and false-positive fixes ship as patches so they reach you automatically.
|
|
626
679
|
Rule graduations (`warn` → `block`) are **opt-in**: they gate on the `version:` field in
|