fix(vex): honest machine diagnostics, stale-doc removal, out-of-sync disclosure; offline proxy-notice suppression - #208
Conversation
…disclosure; suppress the proxy notice under --offline Findings from the 2026-08-18 pnpm e2e campaign's vex probe (real-pnpm projects; the core attestation invariant — verified:true only on matching bytes — was healthy throughout and is untouched): - Property-7 setup-filter drops were invisible in --json: a byte-verified applied patch omitted only because its ecosystem has no install hook (and no setup.manual) produced events:[] and the factually wrong "No applied patches with vulnerability metadata to attest." Drops now emit per-purl skipped events (errorCode ecosystem_not_setup) and the all-drops error message names the filter and both remediations. - A failed vex run left a stale prior attestation byte-untouched at --output. Failed runs now remove a recognizably-OpenVEX file at the path (JSON @context naming openvex.dev — unrelated files never touched). - write_failed errors now name the path; a non-IRI --product override warns (product_not_iri) instead of silently landing in the OpenVEX product @id; the vendored attestation gains a vendored_tree_out_of_sync warning when the PRESENT installed tree hash-mismatches the patched bytes (attestation basis — the committed artifact — unchanged). - apply/vendor/rollback --offline runs no longer print the "using the public patch API proxy" notice (network-implying under strict airgap); the SOCKET_OFFLINE parse is hoisted to a shared is_offline_env() used by the client and telemetry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit dfdc94b. Configure here.
| code: code.to_string(), | ||
| detail, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Embedded JSON drops VEX warnings
Medium Severity
note_warning skips stderr under --json and stores advisories in VexWriteSummary.warnings, but only standalone emit_envelope_success copies that field into the envelope. Embedded apply/scan --json --vex share generate_vex and also silence stderr, so product_not_iri and vendored_tree_out_of_sync stay machine-invisible on the channel this PR aimed to fix.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit dfdc94b. Configure here.
| fn apply_offline_suppresses_public_proxy_notice() { | ||
| // No .socket dir at all: apply exits 0 ("nothing to apply") either way, | ||
| // so the only stderr difference is the advisory under test. | ||
| let tmp = tempfile::tempdir().unwrap(); |
There was a problem hiding this comment.
New tests use bare unwrap
Low Severity
Newly added test fixtures call bare .unwrap() on tempfile::tempdir(), fs::write, and similar Results. On failure CI only reports a generic unwrap panic, with no indication which setup step broke.
Additional Locations (2)
Triggered by learned rule: Prefer .expect("context") over bare .unwrap() in test code
Reviewed by Cursor Bugbot for commit dfdc94b. Configure here.


Problems (found by the 2026-08-18 pnpm e2e campaign's vex/offline probes; all ecosystem-independent)
setup.manual) madevex --jsonexit 1 withevents: []and the factually wrong error "No applied patches with vulnerability metadata to attest." — indistinguishable from "not patched". The explanatory note was human-mode-only.--output— a pipeline reusing one path could ship yesterday's attestation for a now-unpatched tree.--outputwrite failures reported a bare OS error with no path;--productaccepted arbitrary non-IRI strings verbatim into the OpenVEX product@id; a healthy vendored attestation said nothing when the live installed tree was out of sync with the patched bytes.apply/vendor/rollback--offlineruns printed the "using the public patch API proxy" notice — network-implying output under strict airgap — and theSOCKET_OFFLINEparse was duplicated between the client and telemetry.Fixes
skippedevents with errorCodeecosystem_not_setup; when all omissions are filter drops, the error message names the filter and both remediations.@contextnaming openvex.dev) — unrelated files are never touched; the contract is pinned by tests both ways.write_failednames the path; a non-purl/non-IRI product override warns (product_not_iri, honored verbatim); vendored attestations gain avendored_tree_out_of_syncwarning when the present installed tree hash-mismatches (attestation basis unchanged — the committed artifact is the product; the warning says to reinstall).is_offline_env()is hoisted toutils/env_compatand shared by the client (both gates) and telemetry.The core attestation invariant is untouched and was verified healthy throughout the probes:
verified: trueonly ever appears when on-disk bytes hash toafterHash; every tamper flipped the attestation. The stable(vendored)/(redirected)impact-marker strings are unchanged (contract-pinned).Verification
New tests: stale-doc removal + non-OpenVEX preservation, write-failure path naming, setup-filter skipped events + specific message,
product_not_iriwarn + purl control, out-of-sync warn with absent-tree and pristine controls (core), offline proxy-notice suppression. Suites: cli_parse_vex 7, e2e_embedded_vex 12, e2e_vex_vendor 13, cli_apply_silent 5, core vex 241 — all green; verified against main in an isolated worktree before opening.🤖 Generated with Claude Code
Note
Medium Risk
Changes VEX JSON contracts, failure cleanup at output paths, and offline messaging—high impact for CI pipelines consuming envelopes, but core attestation rules (hash-to-afterHash, vendored precedence) are preserved and heavily tested.
Overview
VEX
--jsonand envelopes now expose ecosystem-setup (Property 7) drops as per-purlskippedevents witherrorCodeecosystem_not_setup, with clearer top-level errors when every omission is that filter—not the generic “nothing to attest.” Run-levelwarnings[]covers non-IRI--productoverrides (product_not_iri, still emitted verbatim) and vendored patches whose livenode_modulestree hash-mismatches the committed artifact (vendored_tree_out_of_sync; attestation still based on.socket/vendor).Failed runs delete a recognizably OpenVEX file at
--output/--vexso CI cannot ship a priornot_affecteddoc; unrelated paths are untouched.write_failednames the path and operation.Core verification adds
VerifyOutcome.vendored_out_of_syncwhen a healthy vendored attestation sees a present installed tree with wrong bytes.Offline / airgap: tokenless “public patch API proxy” stderr is suppressed when
SOCKET_OFFLINEis set;is_offline_env()is shared across API client and telemetry instead of duplicated parses.Reviewed by Cursor Bugbot for commit dfdc94b. Configure here.