Skip to content

fix(ci): don't parse guest_launch_measurements for HostOS proposals - #11458

Open
r-birkner wants to merge 2 commits into
masterfrom
rjb/fix-repro-check
Open

fix(ci): don't parse guest_launch_measurements for HostOS proposals#11458
r-birkner wants to merge 2 commits into
masterfrom
rjb/fix-repro-check

Conversation

@r-birkner

Copy link
Copy Markdown
Contributor

repro-check -p <proposal-id> crashed with an uncaught KeyError: 'guest_launch_measurements' on every HostOS version-election proposal.

process_proposal() read and transformed guest_launch_measurements from the proposal payload before branching on the proposal type. HostOS election payloads only carry hostos_version_to_elect, hostos_versions_to_unelect, release_package_sha256_hex and release_package_urls — no launch measurements. Since main() only catches VerificationError and RuntimeError, the KeyError surfaced as a traceback with exit code 1, indistinguishable from a real reproducibility mismatch. As HostOS and GuestOS are elected in separate proposals each release, this affected roughly half of all election proposals.

The measurements are only used in the GuestOS return branch anyway, so parsing them up front was both wrong and unnecessary.

Changes:

  • Extract payload parsing into a module-level parse_proposal_payload(), which reads guest_launch_measurements only in the GuestOS branch.
  • Detect the proposal type from the payload keys rather than substring-matching json.dumps(proposal_data) — the old check also matched versions appearing in *_to_unelect lists.
  • Correct the process_proposal() return annotation (the measurements element is a dict, not a str) and drop the unused self.proposal_launch_measurements attribute.
  • Add ci/scripts/repro_check_test.py (+ a py_test in a new ci/scripts/BUILD.bazel) covering a HostOS payload without measurements, the GuestOS hex→bytes conversion, and the missing-version error.

Verified with bazel test //ci/scripts:repro_check_test, bazel build //ci/scripts:all --nobuild, and bazel run //:buildifier.

repro-check read guest_launch_measurements from the proposal payload
before branching on the proposal type. HostOS election proposals don't
carry that field, so `repro-check -p <hostos-proposal-id>` died with an
uncaught KeyError, which looked like a reproducibility mismatch.

Move the payload parsing into parse_proposal_payload(), which reads the
measurements only in the GuestOS branch, and detect the proposal type
from the payload keys instead of substring-matching the serialized JSON
(which also matches *_to_unelect entries). Add a test covering both
payload shapes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

HostOS processing still unconditionally performs the GuestOS measurements comparison with None.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Refactors election proposal parsing to distinguish GuestOS and HostOS payloads safely.

Changes:

  • Adds payload-type-specific parsing.
  • Corrects measurement return typing and removes unused state.
  • Adds parser tests and a Bazel test target.
File summaries
File Description
ci/scripts/repro-check Refactors proposal parsing.
ci/scripts/repro_check_test.py Tests payload parsing behavior.
ci/scripts/BUILD.bazel Defines the Python test target.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ci/scripts/repro-check
measurement["measurement"] = list(bytes.fromhex(measurement["measurement"]))
return (payload["replica_version_to_elect"], sha256_hex, measurements, None)
if payload.get("hostos_version_to_elect"):
return (payload["hostos_version_to_elect"], None, None, sha256_hex)
run() called compare_proposal_measurements_vs_cdn() unconditionally, and
that method only skipped when there was no proposal id. For a HostOS
proposal the measurements are None, so it compared the GuestOS CDN
measurements against None and then crashed building the mismatch message
in format_measurements(None) -- or, with --hostos, read a
launch-measurements.json that was never downloaded. Guard on the
measurements the same way compare_proposal_vs_cdn() guards on the hashes.

Also make parse_proposal_payload() copy the measurements instead of
converting them in place, so it doesn't mutate the caller's payload.

The previous test only covered the extracted parser, which is why it
missed this. Add tests that drive run() end to end for both proposal
types with the network and the local build stubbed out; the HostOS one
fails with the originally reported KeyError on the pre-fix script.
@r-birkner
r-birkner marked this pull request as ready for review September 7, 2026 06:50
@r-birkner
r-birkner requested review from a team as code owners September 7, 2026 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants