| name | wicked-vault:cross-check-evidence |
| description | Declare a consumer-authored contract and get a mechanical PASS/REJECT verdict for a scope+phase by re-deriving every required artifact. Use when answering "is this claim actually backed by evidence that still holds?" โ gate logic, release readiness, or merge checks. Fail-closed when no contract is declared. |
wicked-vault:cross-check-evidence
Evaluate a whole contract โ the set of evidence a scope+phase requires โ and
return a single mechanical verdict. Cross-check re-derives every required
artifact (it does not trust cached statuses) and reports PASS only when all of
them hold.
This is the "is the work backed?" question. The contract is consumer-
authored; the vault only decides whether it's satisfied, never what it
should require (G9). The vault has no gate logic of its own to leak.
When to use
- A gate / release-readiness / merge check that aggregates several claims.
- Answering: "is this claim actually backed by evidence that still holds?"
- Any time a stored "ready to merge" / "tests pass" must be re-proven, not
asserted.
For a single artifact, use wicked-vault:verify-evidence instead.
Step 1 โ Declare the contract
Write a JSON spec listing the required evidence, then declare it for a
scope+phase. A claim with a verifier pin also constrains how its evidence may
be recorded (G8 โ see wicked-vault:record-evidence).
{
"required_evidence": [
{ "claim_id": "tests-pass", "kind": "test-run", "criteria": "all unit tests pass (exit 0)", "verifier": { "kind": "exit_code_eq" } },
{ "claim_id": "no-secrets", "kind": "test-run", "criteria": "no secrets in the diff", "verifier": { "kind": "not_contains" } },
{ "claim_id": "design-ok", "kind": "review-verdict", "criteria": "the change adequately addresses the documented failure modes", "require_attestation": true },
{ "claim_id": "changelog", "kind": "file", "required": false }
]
}
npx wicked-vault declare-contract --scope checkout --phase release --spec contract.json
required: false makes a claim optional โ its absence is PASS, not MISSING.
criteria pins the acceptance criteria for the claim. This is the
trusted path โ criteria authored in the contract (separately from the
worker), so a recorded artifact must match it (criteria_authored_by: contract). Strongly preferred over worker-supplied criteria.
require_attestation: true marks a claim that needs an independent
judgment (the judgment tier) โ see Step 4. Use it for free-form criteria a
deterministic verifier can't express ("adequately addresses the failure
modes").
- The
contract_version is a hash of the required-evidence set (G8 pinning).
Authoring strong contract criteria (the trusted path's whole point)
The contract is where criteria are authored separately from the worker, so it
is the place to set a bar a self-grading worker cannot lower. A pinned criterion
should be measurable, not a vibe. For a high-blast-radius claim (schema /
data change, integration cutover, production transition), pin criteria that
assert all three of:
- Verification โ the concrete, automatable check and who signs it: row
counts / checksums / reconciliation, golden-master diff = 0, contract tests
green, perf against the known hotspots. Not "migrated" but "row counts match
source ยฑ 0 and the recon report is signed".
- Tested rollback โ a rehearsed (not merely written) rollback with its
trigger (who decides, on what signal, by when) and the point of no
return stated explicitly. "Rollback tested, not just written."
- Enumerated blast radius โ every reader and writer of the surface listed
explicitly, not assumed, and how each is protected during the change.
This is the same triad documented in wicked-vault:record-evidence (with a
worked example), lifted in shape from a migration factory's gated-change specs
(db-endpoint-update / cutover). It directly counters the T1 โ lax-bar
self-grade risk in wicked-vault:analyze-evidence by raising the floor on what
the bar must say. It is authoring guidance only: the vault still adds no
gate, policy, or risk-class behaviour โ cross-check remains a pure mechanical
function of (consumer-authored contract, recorded artifacts) (G9). A
require_attestation: true claim plus a criterion that names its rollback and
blast radius is what makes the independent judge's "does this adequately address
the failure modes?" answerable rather than a rubber stamp.
Step 2 โ Record the evidence
Record one artifact per required claim (wicked-vault:record-evidence). Each claim_id
must match the contract, and --criteria must match the contract's pin. The
latest active artifact for a claim wins.
Step 3 โ Cross-check (integrity tier โ the default, CI-safe)
npx wicked-vault cross-check --scope checkout --phase release
This is --integrity-only by default: deterministic, offline, no model
calls โ safe to put on a CI gate. It evaluates hash integrity + any
deterministic verifier per claim.
{
"scope": "checkout", "phase": "release",
"contract_version": "...",
"overall": "PASS",
"claims": [
{ "claim_id": "tests-pass", "artifact_id": "...", "hash_ok": true, "verifier_status": "pass", "result": "PASS", "detail": "exit_code=0" },
{ "claim_id": "no-secrets", "artifact_id": "...", "hash_ok": true, "verifier_status": "pass", "result": "PASS", "detail": "/(?i)secret/ absent" }
],
"evaluated_at": "..."
}
Verdicts and exit code
Exit 0 iff overall === "PASS". Per-claim result is one of:
| result | meaning |
|---|
PASS | required artifact present, hash intact, verifier passed (and โ in --with-attestations โ an independent pass opinion when require_attestation) |
MISSING | a required claim has no active artifact |
FAIL | artifact present but tamper or verifier failed |
UNATTESTED | require_attestation claim has no independent opinion recorded |
REJECT | require_attestation claim has a non-pass / stale independent opinion |
ERROR | verifier-kind pin mismatch against the contract |
overall is PASS only if every claim is PASS; ERROR if any claim errored;
otherwise REJECT.
Step 4 โ Judgment tier (opt-in, NOT for the default CI gate)
npx wicked-vault cross-check --scope checkout --phase release --with-attestations
--with-attestations consults the latest independent opinion per claim (the
attestations recorded by wicked-vault:analyze-evidence). For a claim with
require_attestation: true, it PASSes only when integrity passes and a
non-stale, independent pass opinion exists; otherwise UNATTESTED / REJECT.
For other claims the opinion is advisory (surfaced, doesn't change the result).
This mode is not deterministic and not for the default gate โ opinions come
from a model and are point-in-time. Run wicked-vault:analyze-evidence first to
produce the attestations, then use this mode for a release sign-off that
requires a third-party judgment. Keep --integrity-only on the fast CI path.
Fail-closed (G5)
If no contract is declared for the scope+phase, cross-check returns
overall: "ERROR" and a non-zero exit โ it never reports PASS by default. An
undeclared expectation can't be silently satisfied.
wicked-bus event
If wicked-bus is installed, cross-check publishes wicked.contract.checked
(domain wicked-vault, subdomain vault.cross_check) carrying the overall
verdict โ this is the signal a gate consumer subscribes to. A detected tamper
also publishes wicked.evidence.tampered. declare-contract publishes
wicked.contract.declared. Emission is fire-and-forget and a no-op when the bus
is absent or WICKED_VAULT_NO_BUS=1.
Inspecting what's recorded
npx wicked-vault list --scope checkout --phase release