Skip to content

ci: mask the engine version in the replay-off golden pins - #634

Merged
luisleo526 merged 2 commits into
mainfrom
ci/replay-golden-version-mask
Oct 29, 2026
Merged

luisleo526 merged 2 commits into
mainfrom
ci/replay-golden-version-mask

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Fixes the red test_replay_off_golden on main after the v1.8.0 release commit.

The replay-off golden pins six byte digests of sink and report dumps. Those dumps carry the engine version (the engine provenance major/minor/patch and the sink header's "engine" string), so the release bump changed the digests without changing any trade or report data: the byte counts stayed identical.

  • scripts/check_replay_off_golden.py: masks ONLY those version fields, alongside the build-identity fields it already masked. Each field must occur exactly once; no byte that carries trade or report data is masked.
  • scripts/test_check_replay_off_golden.py (new): a 1.7.0-shaped and a 1.8.0-shaped input mask to equal bytes, and a changed report byte still fails the pin.
  • docker/replay_off_golden.json: the six digests re-recorded from a measured run with the new mask, so the next version bump keeps them valid.
  • scripts/test_run_unittest_shards.py: registers the new test.

Verified: test_replay_off_golden and test_replay_rq_fixture pass on this head in a cloud Release build.

🤖 Generated with Claude Code

luisleo526 and others added 2 commits October 29, 2026 20:58
…only the commit identity

test_replay_off_golden compares the default JSON report and the primary sink stream as
raw bytes against recorded digests. It already blanks the build identity in the report
(version string, commit, fingerprint token and digest), but the engine's major, minor and
patch numbers in the provenance block and the engine version in the sink header stayed in
the compared bytes. The digests were recorded at 1.7.0, so the release commit that only
moved VERSION to 1.8.0 turned the row red on every build leg, with the same byte counts
and different digests.

Mask exactly those version fields: the three numbers of the engine provenance object in the
raw report, in the base64 token spelling and in the decoded provenance that is appended to
the hashed bytes, and the engine member of the sink header line. Each is required to be
present exactly once, so a report that loses or duplicates the field is refused. Every other
byte, including trade values and numbers named major or minor elsewhere, is still compared.

New real-byte tests cover: 1.7.0 and 1.8.0 shaped reports mask to equal bytes, a changed
trade price or input or runtime number still differs, missing or duplicated fields are
refused, and the sink body is untouched. The new test case is imported by
test_run_unittest_shards.py so the existing preflight entry point runs it.

The six recorded digests are re-recorded in the next commit from a measured run.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…8.0 run

With the version fields masked, the six recorded digests change shape. They are taken from
the ctest row's own measured output on a CLOUD build of the tagged v1.8.0 tree plus the
masking change (default JSON 9288, 8939 and 8950 bytes; sink 1565, 1451 and 1464 bytes),
not edited by hand. The byte counts grew by exactly the bytes the extended mask adds (102
per default JSON, 11 per sink stream), so no other length moved. The source note names the
re-recording and what is now masked.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
import run_unittest_shards as shards_runner # noqa: E402
# This module is an explicit preflight entry point. Import the regression
# TestCase so unittest also runs it here, without a second CI registration.
from test_check_replay_off_golden import ReplayOffGoldenTests # noqa: E402,F401
from pathlib import Path
import subprocess
import tempfile
import unittest

@graphify-labs graphify-labs Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.

Not checked: tests were not run; formal verification proved 0 of 2 changed function(s) (2 not verified).

Formal verification. PR-changed functions: 0/2 verified (0 proven, 0 may-equivalent, 0 distinguished) · 2 not verified (2 vacuous).

Not verified on this run: mask\_build\_identity (vacuous: never exercised), measure (vacuous: never exercised).


Graphify review — findings

Extends the replay-off golden mask to blank the engine major, minor and patch numbers and the sink header's engine version, so the recorded digests no longer depend on VERSION. mask_build_identity and mask_sink_build_identity raise unless each member is found exactly once, and the golden JSON is re-recorded on v1.8.0 with byte counts growing by exactly the bytes the extended mask adds. Adds ReplayOffGoldenTests with real-byte fixtures and registers the class in the unittest shard verifier's partition, where its re-export from the shard test module can surface the same test under duplicate IDs in discovery.

Worth a look

  • Re-exported TestCase yields duplicate test IDs under discovery — scripts/test_run_unittest_shards.py:27 · Escalate · medium
    • NOT verified (no proof, no reproducing execution) — needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 46 functions depend on the 46 functions this change touches.

Health — grade A; no new coupling hotspots.

Verification — 46 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 46 function(s) in the blast radius were not formally verified this run

Docs that may be stale (advisory)

…and 10 more.

Formal verification

Could not verify: Could not verify mask\_build\_identity.

The verifier did not have enough to check mask\_build\_identity, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: not verifiable: all 260 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly AttributeError — names the real obstacle, not a sampling gap)

Could not verify: Could not verify measure.

The verifier did not have enough to check measure, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: not verifiable: all 263 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly AttributeError — names the real obstacle, not a sampling gap)

@luisleo526
luisleo526 merged commit d24a823 into main Oct 29, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant