fix(exporters): write VERIFICATION.md after weight fusion, not before#240
Open
rylinjames wants to merge 1 commit into
Open
fix(exporters): write VERIFICATION.md after weight fusion, not before#240rylinjames wants to merge 1 commit into
rylinjames wants to merge 1 commit into
Conversation
- Root cause: `export_monolithic` called `_write_tether_config` (which
calls `write_verification_report` and SHA-256-hashes every file) inside
the per-family exporter (e.g. `export_smolvla_monolithic`, line 661),
then AFTER that returned ran `fuse_weights` (lines 1540-1541) which
atomically overwrites `model.onnx` with structurally different bytes.
Result: VERIFICATION.md recorded pre-fusion hashes; `tether validate`
recomputed post-fusion hashes → cert mismatch on every monolithic export.
- Fix: after the `fuse_weights` block in `export_monolithic`, call
`write_verification_report(Path(output_dir), parity=None)` again so the
stale report is overwritten with hashes of the now-final post-fusion
files. Wrapped in the same try/except pattern used nearby so a report
failure can never abort the export. The original call inside
`_write_tether_config` is intentionally preserved — other exporters
(split path `export_smolvla`, etc.) depend on it.
- Tests added:
- `test_hash_freshness_after_file_mutation` in test_verification_report.py:
creates a temp dir with a fake model.onnx, calls write_verification_report,
mutates the file, calls again, asserts the recorded SHA-256 changed and
matches the independently computed hash of the new bytes.
- `test_export_monolithic_calls_write_verification_after_fusion` in
test_export_monolithic_model_type_fallback.py: monkeypatches the family
exporter, fuse_weights, and write_verification_report to track call order;
asserts write_verification_report is called at least once AFTER fuse_weights.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
export_monolithicwroteVERIFICATION.md(via_write_tether_config→write_verification_report) inside the per-family exporter (e.g.export_smolvla_monolithic, line 661), then AFTER that returned ranfuse_weights(lines 1540-1541) which atomically overwritesmodel.onnxwith structurally different bytes. Result: every monolithic export shipped aVERIFICATION.mdwith pre-fusion SHA-256 hashes;tether validaterecomputed post-fusion hashes and the cert mismatched on every run.export_monolithic, after thefuse_weightsblock, callwrite_verification_report(Path(output_dir), parity=None)a second time so the stale report is overwritten with hashes of the final post-fusion files. Wrapped in the same defensivetry/exceptpattern used nearby. The original call inside_write_tether_configis preserved — the split-path exporters depend on it.test_hash_freshness_after_file_mutation: creates a temp export dir with a fakemodel.onnx, callswrite_verification_report, mutates the file, calls again, asserts the recorded SHA-256 changed and exactly matches the independently computed hash of the new bytes.test_export_monolithic_calls_write_verification_after_fusion: monkeypatches the family exporter,fuse_weights, andwrite_verification_reportto record call order; assertswrite_verification_reportis called at least once AFTERfuse_weights.Ordering confirmed
write_verification_reportfirst called:monolithic.py:836(inside_write_tether_config, invoked by family exporters at e.g. line 661)fuse_weightscalled:monolithic.py:1541(inexport_monolithic, after family exporter returns)monolithic.py:1554Test plan
pytest tests/test_verification_report.py— 7/7 pass (including newtest_hash_freshness_after_file_mutation)pytest tests/test_export_monolithic_model_type_fallback.py— 18/18 pass (including newtest_export_monolithic_calls_write_verification_after_fusion)py_compileonmonolithic.py— cleanruff checkon touched files — clean (pre-existing F841 at line 505 is inmain, not introduced here)🤖 Generated with Claude Code