Skip to content

Allow reproducible builds with javy.#1151

Merged
saulecabrera merged 8 commits intobytecodealliance:mainfrom
nolag:rtinianov_reproducible_builds
Mar 17, 2026
Merged

Allow reproducible builds with javy.#1151
saulecabrera merged 8 commits intobytecodealliance:mainfrom
nolag:rtinianov_reproducible_builds

Conversation

@nolag
Copy link
Contributor

@nolag nolag commented Mar 6, 2026

Description of the change

Allow reproducible builds with javy via a flag

Why am I making this change?

Our customers need to prove their binary image ran. We have signatures on the binary that ran, alongside the data it produced.

Checklist

  • [N/A] I've updated the default plugin import namespace and incremented the major version of javy-plugin-api if the QuickJS bytecode has changed.
  • [ ✔️] I've updated the relevant CHANGELOG files if necessary. Changes to javy-cli, javy-plugin, and javy-plugin-processing do not require updating CHANGELOG files.
  • [✔️] I've updated the relevant crate versions if necessary. Versioning policy for library crates
  • [✔️] I've updated documentation including crate documentation if necessary.

Copy link
Member

@saulecabrera saulecabrera left a comment

Choose a reason for hiding this comment

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

Changes look reasonable to me, but in general maybe we could consider integrating https://github.com/Shopify/deterministic-wasi-ctx, instead? The motivation of that crate is the same as what you're describing in your PR, modulo it covers several other sources of non-determinism e.g., random.

nolag added 2 commits March 10, 2026 10:57
Adds `deterministic` option to the test runner Builder and an
integration test that verifies two separate deterministic builds
of the same JS source produce byte-identical WASM output.
@nolag nolag requested a review from saulecabrera March 10, 2026 15:13
Copy link
Member

@saulecabrera saulecabrera left a comment

Choose a reason for hiding this comment

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

I think this is moving in the right direction. I think we should still fix the comments around dependencies and duplication.

@nolag
Copy link
Contributor Author

nolag commented Mar 11, 2026

Changes look reasonable to me, but in general maybe we could consider integrating https://github.com/Shopify/deterministic-wasi-ctx, instead? The motivation of that crate is the same as what you're describing in your PR, modulo it covers several other sources of non-determinism e.g., random.

Nice, I'll try replacing mine with this. I'm glad I read this because I was about to open another draft with a few small changes to plug into more places that I didn't see before.

…Shopify/deterministic-wasi-ctx

The `with_determinism` helper only fixed wall and monotonic clocks but
left `secure_random` and `insecure_random` using per-context random
state. During Wizer pre-initialization the QuickJS runtime calls WASI
random (e.g. for hash seeds), causing the memory snapshot to differ
across runs.

- Replace both secure and insecure random with constant zero-filled
  deterministic sources when deterministic mode is enabled
- Disable parallel compilation and enable NaN canonicalization for the
  Wasmtime Engine in deterministic mode
- Add `test_deterministic_init_plugin` test
- Update CHANGELOG and all flag docs with security note about random
  sources being non-secure when determinism is active

Made-with: Cursor
@nolag nolag requested a review from saulecabrera March 11, 2026 14:00
Copy link
Member

@saulecabrera saulecabrera left a comment

Choose a reason for hiding this comment

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

I think this is close, thanks for your patience iterating on this.

@@ -0,0 +1,150 @@
// Exercises many runtime code paths during Wizer pre-initialization to stress
// parallel compilation ordering and NaN canonicalization in Cranelift.
Copy link
Member

Choose a reason for hiding this comment

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

See my comment in with_deterministic_engine

@saulecabrera
Copy link
Member

saulecabrera commented Mar 12, 2026

Also, it seems that CI is failing with compilation errors https://github.com/bytecodealliance/javy/actions/runs/22958007777/job/66803827504?pr=1151

@nolag nolag requested a review from saulecabrera March 12, 2026 18:00
@nolag
Copy link
Contributor Author

nolag commented Mar 12, 2026

I think this is close, thanks for your patience iterating on this.

Same, thanks for your patience as well. I wish I knew Rust and the details of the WASM compilation better.

Lmk if the reasoning that Claude provided on why we need the engine flags makes sense or not.

@saulecabrera saulecabrera force-pushed the rtinianov_reproducible_builds branch from 7b8f646 to d73ef48 Compare March 13, 2026 15:19
@saulecabrera saulecabrera force-pushed the rtinianov_reproducible_builds branch from d73ef48 to 4e6e31e Compare March 13, 2026 15:26
Invokes init-plugin --deterministic twice on the same uninitialized
plugin and asserts byte-identical output, then verifies the resulting
plugin is functional.

Made-with: Cursor
Copy link
Member

@saulecabrera saulecabrera left a comment

Choose a reason for hiding this comment

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

Thanks!

@saulecabrera saulecabrera merged commit d82434d into bytecodealliance:main Mar 17, 2026
4 checks passed
@nolag nolag deleted the rtinianov_reproducible_builds branch March 17, 2026 13:06
@nolag
Copy link
Contributor Author

nolag commented Mar 17, 2026

Thanks!

My pleasure, any chance you can tag it and cut a release for the crate today?

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.

2 participants