feat(release): require challenge-bound nvattest proofs in candidate evidence master
Wire the landed nvattest native-proof primitive into the candidate rail. Every fresh candidate now generates a 64-hex challenge, extracts nvattest authority from its own root wheels, materializes a lock-verified eight-wheel support set, and requires one challenge-bound nvattest receipt per native target alongside the existing install receipt. What a candidate now requires before promotion: - a fresh challenge per attempt, so two attempts over identical version, source, and payload inputs differ only in the challenge and the receipts bound to it - authority extracted from the candidate's own root wheels, proven byte-identical across all three targets, digested into the ledger, and passed to every lane - the eight locked support wheels materialized into retained evidence and verified against uv.lock before the ledger is written and before any host call - one valid nvattest receipt per target in a sibling nvattest/ directory, so the existing install-proof gates stay exact and unweakened Evidence inventory grows from {ledger.json, proofs} to {ledger.json, proofs, nvattest, support}, each gate exact in both directions. The ledger gains one top-level nvattest key carrying the challenge, the authority payload, its byte digest, and the locked support declarations. The target list is not restated there; proofs.expected_targets stays the single source of truth for both receipt kinds. The proof-host seam is renamed run_target_proofs and returns both receipt paths from a single host round-trip. release_install_smoke.run_install_proof, the install prover the adapter harness invokes, is deliberately unchanged. bundle_digest now binds the nvattest receipt digests. This intentionally changes a reported candidate identity for future retained candidates; without it the bundle digest would not cover the new evidence. Lock verification is deliberately candidate-side only. Recovery anchors support verification in retained bytes and the retained ledger's declarations, which are themselves the lock-derived declarations captured at cut time. Anchoring recovery in the checkout lock would make a retained candidate stop validating after any support dependency bump, and would block publishing valid retained bytes because publish_release gates on _verify_recover. Real remote lanes, production URL reach, journal publication, and live SPP composite acceptance remain VPE post-ship work; no test contacts a host, downloads a wheel, or runs a real build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>