Repository navigation
v0.43.0 review fixes: varve env injection, realmless dispatch, and four requirement gaps - #278
Merged
Merged
Conversation
…asure the cap end to end The description lost clauses (1)-(3) when it merged; only clause 4 remained. Restored verbatim. The two CLI tests reached support_horizon before any include was read, so replacing &windows with &[] at the cap_by_includes call passed every test. Add tests that run the binary against a loopback OCI registry serving a signed include and a signed line-status: the cap (clause 1), an include with no line-status / a status stating no window / an unverifiable realm root refusing (clause 2), and --past-includes exceeding it with the reason on stderr and a blank reason refused (clause 3). With &[] in place, 5 of them fail. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
…eck is reported, not dropped payload_from_entry silently dropped entries with no tool version or no source repository, and included layers and non-tool kinds never reached the report, so a line made of them read 'nothing new' over bytes nobody had looked at. classify_entry now returns the reason. Each such entry lands in the line's unchecked list: tool entries and included layers one by one with the missing annotation named, non-tool kinds once per kind with a distinct count. The summary wording is 'N item(s) NOT checked' since the list no longer holds only embedded-component gaps. What the watcher fetches is unchanged. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
…s a function of the signed manifest alone Clause 1: sbom.rs never read eu.pulseengine.source.proof-signer. A component's supplier is now the organisation of the signer where it is a GitHub identity, else the repository owner; the signer is also recorded verbatim as a component property so a reader sees what the supplier came from. Clause 7: the author came from the caller's local realm alias (varve-realms.toml label, or a placeholder outside a project), so one signed manifest emitted different bytes in different projects. emit() now takes the root public key that verified the envelope (PinnedKeyVerifier::public_key) and names the author by its fingerprint, the one fact about 'the realm that signed this' the signed data states. The alias is no longer in the document. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
…an gave it report took a cargo-mutants summary line as proof a shard was measured, so a log reading '12 mutants tested' for a shard planned at 314 was MEASURED with exit 0. N mutants tested counts every mutant run (unviable and timed out included) and the planned count is cargo mutants --list on the same commit, so they must be equal: fewer or more is INCOMPLETE, with both numbers shown, and adds nothing to the measured totals. The plan's stated rate is corrected from ~7 to ~4.75 mutants/minute, measured by workflow_dispatch run 39541389293 (939 mutants; shards of 314/300/298/27 took 66/61/59/7 minutes). The 300 target stays: 63 minutes expected, 66 measured at 314, against the 90-minute cap. VER-MUTANTDEBT-001 now records that run, that it predates this comparison, and that no scheduled run has completed yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
…pplier A Sigstore identity is the job_workflow_ref; for a reusable workflow it names a different organisation from the one that supplied the bytes (slsa-framework/slsa-github-generator signs for every caller). Letting it decide the supplier would misattribute it. The supplier is the signed repository's owner again. The signer stays on the record as a property, and where it is a GitHub identity of another owner a supplier-signer-differs property says so. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
Found by the v0.43.0 clean-room review and reproduced: a cloned repo's varve.toml with `out = "sdk\ntouch PWNED\n#"` made `varve env` print `touch PWNED` on its own line, and `eval "$(varve env)"` ran it. The root and script path were quoted (REQ-ENVQUOTE-001); the comment naming the export was not, and a newline needs no quote to end a comment. A destination with a control character is now refused at parse, and the comment escapes the value anyway. The end-to-end test evals the output in sh and failed on the live attack before the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
Found by the v0.43.0 clean-room review and reproduced: with a pin naming no realm and VARVE_TRUST_ROOT unset, status refused while which printed a store path and run executed it, #198's two answers to one question. which and run_tool (so the shims too) now go through dispatch_ctx and refuse with status's reason. REQ-NOPINNOTOOL-001 clause 2 is reworded to that property and the change is recorded on the artifact: as written it forbade the store every realmless pin installs into. list's note now names VARVE_TRUST_ROOT as what vouches, and its test checks the layer is still on disk. Tampering after install affects every pin and is tracked in #277. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
… a root Second v0.43.0 clean-room review, both reproduced: - dispatch_ctx only checked VARVE_TRUST_ROOT parsed, so any key let which/run dispatch a layer verify refused. A realmless pin now checks the retained envelope against that root (steps 1-2 of verify_installed, shared as verify_retained_envelope: one signature, one small read). shim install goes through the same check. - shim install printed `. "<root>/env"` for the login config, where $(...) in VARVE_ROOT ran; it is now quoted literally. The realmless CLI fixture signs what it lays down, as install would. REQ-NOPINNOTOOL-001 clauses 2-3 and REQ-SBOMFIELDS-001 clauses 1-2 are amended to what the code does, with the reasons recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The independent clean-room review of the v0.43.0 scope dissented on all six requirements. This PR fixes what it found. Every fix has a test that I watched fail on the reported behaviour first.
Security
varve envinjection (REQ-ENVQUOTE-001), reproduced.varve.tomlwith[[export]] out = "sdk\ntouch PWNED\n#"madevarve envprinttouch PWNEDon a line of its own, andeval "$(varve env)"created the file. The store root and script path were quoted, but the comment line naming the export was not.sh. Before the fix it created the canary file.statusrefused ("no trust root configured") whilewhichprinted a store path andrunexecuted it, which is friction:varve which/shims resolve a stale binary from the legacy pre-realm store when no pin is in scope — whilevarve statusrefuses (no trust root) #198's shape.which,runand the shims now go throughdispatch_ctxand givestatus's reason.Requirement gaps
support-horizontests run against a loopback registry serving a signed include. With&windowsreplaced by&[], five of them fail; before this PR every test passed.Evidence (local, combined branch)
-D warnings,rivet validate, verification-evidence, trace-gate, claim-check, tracepack-check, proof-check, the tool unit tests,cargo deny, no-key-on-disk.pin.rs: 77 tested, 68 caught, 9 unviable.advisorywatch.rs,verify.rsandsbom.rs: 3 survivors onPinnedKeyVerifier::public_keywere killed by a new test.verify.rswas re-run: 27 tested, 26 caught.🤖 Generated with Claude Code
https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu