ADR-0044: focused module surface and optional-provider isolation (35 → 21 projects) - #53
Open
satran004 wants to merge 12 commits into
Open
ADR-0044: focused module surface and optional-provider isolation (35 → 21 projects)#53satran004 wants to merge 12 commits into
satran004 wants to merge 12 commits into
Conversation
Records the accepted target architecture: a focused default product surface (~20 root projects), explicit opt-in product modules, removal of the gnark and Halo2 native runtime providers, isolation of the BLS/BBS WASM assurance providers and MPF/JMT load tools outside the default build, and the verifier-core -> backend-spi and ceremony -> tools mergers. ADR-0020 is marked superseded in part and retained as the historical record of the first module cleanup. Risk: R1 structural, with R2 assurance impact. No cryptographic algorithm, encoding, transcript, public-input order, circuit relation, proof equation, or trusted-setup semantics change under this ADR. Refs: #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rfaces Publication surface: - zeroj-bom-core becomes the single stable BOM and constrains only the default product surface: 14 artifacts. zeroj-crypto-blst and zeroj-tools are added; zeroj-verifier-core, zeroj-prover-spi, zeroj-prover-gnark, zeroj-cardano, zeroj-ccl and zeroj-patterns are dropped, as are the explicit opt-in product artifacts (verifier-plonk, mpf-poseidon, jmt-poseidon), which applications now declare by coordinate and version. - zeroj-bom-all is removed. - The nonPublishable list is extended so the assurance, benchmark and integration-test projects can never be published, even when their opt-in settings flag puts them in the build. CI/snapshot/release: - The gnark (Go) and Halo2 (Rust) native build stages are removed from all three workflows. libblst is still built from source per release for zeroj-blst. New structural guard: - ./gradlew verifyDefaultModuleSurface asserts the stable runtime graph has no edge into an assurance/benchmark/removed module, that MPF and JMT stay independent, that the annotation API and processor stay separate, and that no pure-Java module acquires a native/WASM dependency. Wired into CI, snapshot and release. Test-only edges are allowed by design so differential/assurance wiring stays legal. Docs: - docs/migration/0044-module-cleanup.md records the coordinate migration table. - ADR-0044 implementation status: Not started -> In progress. No cryptographic algorithm, encoding, transcript, public-input order, circuit relation, proof equation, trusted-setup or validation behavior changes. Baseline before this change: ./gradlew cleanTest test --continue, BUILD SUCCESSFUL in 15m24s, 0 failures across all 31 test-bearing projects. Refs: ADR-0044 M1, #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…integration-tests
Creates the non-published zeroj-integration-tests project and moves every
security-relevant regression out of zeroj-examples before removing it. Each of
these spans several modules, so no single product module owns the invariant.
Preserved and green in the new home:
- ComparatorRelationPinningTest — ADR-0037 comparator soundness (oversized
operand rejected, not wrapped)
- SealedBidCircuitTest — circuit relation + BN254 curve-policy refusal
- AnnotatedCircuitExamplesTest — annotation companions, public-input ordering,
envelope binding rejecting mismatched public signals and wrong curve
- *PureJavaE2ETest, ParameterizedCircuitE2ETest — pure-Java Groth16 full stack
through off-chain pairing and Julc VM on-chain verification
- SealedBidE2ETest, BalanceThresholdE2ETest, AnonymousVotingE2ETest,
SnarkjsProverTest — independent-prover interoperability: ZeroJ emits R1CS and
witness, snarkjs proves, ZeroJ's pure-Java verifier accepts. Groth16 + PlonK.
- SealedBidOnChainE2ETest, PureJavaProverYaciE2ETest — Yaci DevKit on-chain
Not preserved, deliberately:
- EndToEndDemo, GnarkPlonkEndToEndDemo, BbsSelectiveDisclosureExample — demos
with no assertions and no assurance value; Git history is the archive
- CircuitSizeTest — printed constraint counts, asserted nothing
- SealedBidGnarkE2ETest, GnarkProverHelper — bound to the gnark runtime that
ADR-0044 removes
De-gnarking is mechanical and preserves every check. The four proof helpers lose
their unused generateGroth16ProofNative convenience method.
AnnotatedAgeVerificationProofHelper.toEnvelope now takes a prover-neutral
ProverOutput record with the same shape as the removed gnark ProveResponse, so
its curve and public-signal binding assertions are unchanged.
WitnessExporter is preserved from the removed zeroj-prover-wasm incubator module
as an integration-test fixture. It has no WASM dependency and exists only to feed
the independent snarkjs oracle; it is deliberately not added to any published
module.
Verification:
./gradlew :zeroj-integration-tests:test 42 tests, 0 failures
(zeroj-examples baseline was 43; the delta is CircuitSizeTest, which
asserted nothing)
./gradlew :zeroj-integration-tests:e2eTest 11 passed, 2 skipped in 6m22s
snarkjs Groth16 + PlonK interop all passed; the 2 skips are the Yaci
on-chain tests, correctly skipped because no DevKit was running locally.
No cryptographic algorithm, encoding, transcript, public-input order, circuit
relation, proof equation or validation behavior changes.
Refs: ADR-0044 M2, #24
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nd benchmark builds
Removed (Decision 3). Each is preserved through Git history; the migration note
records a replacement or an explicit "no replacement":
- zeroj-prover-gnark — the Java/FFM Groth16 and PlonK runtime, its bundled Go
shared library and its native packaging. No subprocess
replacement.
- zeroj-prover-spi — no retained provider implements the contract
- zeroj-verifier-halo2, zeroj-prover-wasm — the whole incubator/ tree
- zeroj-cardano, zeroj-ccl, zeroj-patterns — app-level policy, not SDK layers
Fixture audit before removing gnark (ADR-0044 Decision 6). gnark DOES supply
unique independent evidence: test-vectors/plonk-bls12381 is gnark v0.14.0
output, consumed in the default build by zeroj-verifier-plonk's
GnarkTranscriptCompatTest, which pins that ZeroJ's Fiat-Shamir transcript
derives byte-identical gamma/beta/alpha/zeta to gnark's verifier. The committed
vectors already carry that evidence, so the minimum pinned generator is
preserved at assurance/gnark-fixtures/ to keep it reproducible. It builds no
shared library, exposes no Java FFM API, and is in no Gradle or publication
graph. main.go (the c-shared FFM entry point) and the committed 15MB compiled
binary are not carried over.
Isolated outside the default build (Decision 4), via opt-in settings flags so
sibling project dependencies keep working:
- assurance/zeroj-bls12381-wasm, assurance/zeroj-bbs-wasm -PincludeAssurance
- benchmarks/zeroj-{mpf,jmt}-poseidon-load -PincludeBenchmarks
Preserving the BBS differential oracle. BbsBlsProviderConformanceTest ran the
official CFRG draft-10 vectors through pure-Java, blst AND the zkcrypto WASM
provider. Moving the WASM module out of the default build would have silently
dropped that row. Instead the test now discovers the provider reflectively, and
the assurance build sets zeroj.assurance.requireWasmProvider so a demanded
oracle that cannot be constructed fails the run rather than shrinking it.
Verification:
./gradlew clean build -PskipSigning=true BUILD SUCCESSFUL, no Go/Rust/Cargo/Node/RocksDB
./gradlew :zeroj-bbs:test 4 conformance rows (pure-java, blst) x 2 suites
./gradlew -PincludeAssurance :zeroj-bbs:test
6 rows — the wasm-zkcrypto row is back, Cargo built it
mutation check: demanding the oracle without it on the classpath fails the
test with IllegalStateException, so it is genuinely fail-closed
gnark harness: go vet clean; `make gen-scratch` emits a fresh independent
gnark v0.14.0 PlonK proof, and :zeroj-verifier-plonk:test
passes against it (38 tests incl. GnarkTranscriptCompatTest).
Committed vectors were then restored byte-for-byte. The
generator is NOT byte-reproducible (unsafekzg randomizes the
SRS); the Makefile and README say so and define the real
property as "Java still accepts and agrees with a fresh
independent artifact".
No cryptographic algorithm, encoding, transcript, public-input order, circuit
relation, proof equation, trusted-setup or validation behavior changes.
Refs: ADR-0044 M3 and M5, #24
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… ceremony CLI into tools
Both mergers are packaging-only. No cryptographic behavior moves or changes.
zeroj-verifier-core -> zeroj-backend-spi (Decision 5):
- VerifierRegistry, VerifierOrchestrator and their tests move into the surviving
artifact and KEEP their com.bloxbean.cardano.zeroj.verifier.core package, so
consumer imports are unchanged; only the dependency coordinate changes.
- The native-image directory is carried over verbatim at
META-INF/native-image/com.bloxbean.cardano/zeroj-verifier-core/ rather than
merged into the backend-spi one, keeping the resources byte-identical.
- The zeroj-verifier-core Gradle project is removed.
zeroj-ceremony -> zeroj-tools (Decision 5):
- CeremonyCli, its tests, Picocli configuration and the fatJar/nativeImage/
nativeDistZip tasks move into zeroj-tools. The package, the `zeroj-ceremony`
command name, and every distributable name are preserved: archiveBaseName is
pinned to `zeroj-ceremony`, and the picocli-codegen -Aproject argument is kept
so the generated metadata still lands at
META-INF/native-image/picocli-generated/com.bloxbean.cardano/zeroj-ceremony/.
- No ceremony cryptography moves: ZkeyContributor, SnarkjsHashToG2 and ChaChaRng
already belonged to zeroj-tools. Transcript bytes, randomness, validation and
secret handling are untouched, as is the zeroj.allowInsecureTrustedSetup guard.
- release.yml now calls :zeroj-tools:nativeDistZip; asset names do not change.
New verification gate:
- zeroj-integration-tests/VerifierServiceLoaderPackagingTest asserts backend
discovery from PACKAGED JARS across module boundaries — that every provider
file really is inside a jar, that discovery yields exactly
{groth16-bls12381-blst, groth16-bls12381-java, plonk-bls12381-java,
bbs-bls12381-java}, that the BN254 backends stay unregistered despite being on
the classpath, and that the two Groth16 BLS12-381 backends both remain
registered with stable find() resolution.
Verification:
./gradlew :zeroj-backend-spi:test 15 tests (7 spi + 8 orchestration) — same
count and names as before the merge
./gradlew :zeroj-tools:test 5 tests, incl. CeremonyCliTest full
Option-A ceremony and
ZkeyContributorInteropTest mixed-tool
transcript verified by `snarkjs zkey verify`
./gradlew :zeroj-integration-tests:test --tests "*VerifierServiceLoaderPackagingTest*"
5 tests, all passed
packaged CLI: java -jar zeroj-ceremony-0.1.0-pre11-all.jar --version
-> "zeroj-ceremony 0.1.0-pre11"; --help lists export-r1cs,
contribute, finalize; missing args exits 2
native-image: picocli metadata present in the zeroj-tools jar at the
unchanged .../com.bloxbean.cardano/zeroj-ceremony/ path
./gradlew verifyDefaultModuleSurface passed, 21 default projects
./gradlew clean build -PskipSigning=true BUILD SUCCESSFUL in 8m20s
Refs: ADR-0044 M4, #24
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Active docs now describe the shipped product rather than removed providers: - README: support matrix, module tables, prerequisites, dependency snippet and build commands. The module tables now separate core (BOM-constrained), explicit opt-in product, never-published support, and opt-in assurance/benchmark projects. The Go prerequisite row is gone; the default build is pure Java. - docs/architecture-overview: module organization, dependency graph and the layer breakdown. Layer 6 is now zeroj-backend-spi; Layer 7 drops the unimplemented prover SPI; the old "High-Level Patterns" layer becomes an explicit statement that application authorization is out of scope; Layer 9 is operator tooling. - docs/alternate-prover-backends: retitled to blst + snarkjs, with a "Removed backends" section that states plainly that gnark and Halo2 are NOT shipping runtime providers and gives the migration for each. - docs/getting-started, plonk-support, circuit-dsl-user-guide, circuit-annotation-user-guide, pure-java-prover-guide, usecases/README, docs/README: gradle task paths, example tables and prover options. - docs/ceremony/USER-GUIDE: :zeroj-ceremony: -> :zeroj-tools: task paths. The documented command name and artifact names are unchanged. docs/plonk-support now documents where the independent PlonK vectors come from (gnark v0.14.0), how to regenerate them from assurance/gnark-fixtures, and why the check is "Java still agrees with a fresh artifact" rather than a byte diff. Historical ADRs are annotated, not rewritten. Supersession notes added to ADR-0008, 0009, 0011, 0018, 0019, 0031 and 0036, each scoped to the packaging or artifact-boundary aspect only, and each restating that the cryptographic, conformance and ceremony decisions in those ADRs still stand — in particular that ADR-0044 does not authorize losing the WASM differential oracles. No maturity, audit, constant-time, production or mainnet claim is upgraded anywhere. The experimental/not-externally-audited framing and the open production gates are unchanged. Also drops the now-stale 'zeroj-examples' entry from the root nonPublishable list, so no build file names a removed project except the ADR-0044 guard, which must name them by design. Verification: ./gradlew verifyDefaultModuleSurface passed, 21 default projects ./gradlew clean build -PskipSigning=true BUILD SUCCESSFUL in 8m57s reference sweep: no active settings, build, workflow, README or publication reference to a removed project remains Refs: ADR-0044 M1/M6, #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…gate All structural milestones (M0-M6) are complete and evidenced; the default build, the module-surface guard, both mergers, the preserved differential oracles, the byte-identical canonical resources, and the zeroj-usecases consumer build are all green. Status stays "In progress" rather than "Implemented" for one reason only: the Yaci DevKit on-chain end-to-end tests were migrated and are correctly discovered, but skipped because no local DevKit was running in the implementation environment. The ADR and migration note name that gate explicitly and give the command that closes it. No maturity, audit, side-channel, production or mainnet claim is upgraded. Refs: ADR-0044, #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ADR-0044's implementation status now records that the release pipeline the merged ceremony CLI depends on was actually executed: :zeroj-tools:nativeDistZip produced a GraalVM native binary reporting "zeroj-ceremony 0.1.0-pre11" with export-r1cs/contribute/finalize all present — proving the picocli native-image metadata survived the module move — packaged as zeroj-ceremony-0.1.0-pre11-macos-arm64.zip, matching release.yml's globs. Also records that the eight moved ceremony/verifier sources are byte-identical to their originals. Note: docs/README.md was also updated locally to fix its stale "gnark FFM" backend description and to index the migration notes, but that file is excluded from version control by this checkout's .git/info/exclude, so it is not part of this commit. Refs: ADR-0044, #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…dule docs
Addresses a code review of the ADR-0044 branch. One finding was a real assurance
gap; the rest were documentation that would have misled or broken consumers.
1. The required assurance job did not exist (blocking).
ci.yml pointed at `assurance.yml`, which was never created, so ADR-0044 M2's
requirement to "establish the opt-in BLS/BBS WASM differential job before
changing their default-build membership" was not actually met — the oracles
were preserved and runnable, but nothing ran them.
Adds .github/workflows/assurance.yml with two independently runnable jobs
(push, PR, nightly schedule, manual dispatch):
- wasm-differential: runs the zkcrypto and zkryptium suites AND
:zeroj-bbs:test. That last target is not optional — under -PincludeAssurance
it is what puts the WASM provider on the BBS test classpath and sets
requireWasmProvider, so the official CFRG draft-10 vectors run through the
third provider row. The documented command in settings.gradle omitted it,
which meant the oracle was built but never exercised; both now include it.
- gnark-fixtures: regenerates the pinned gnark v0.14.0 PlonK vectors and
requires the Java verifier to accept them, then restores the committed
vectors rather than auto-committing a changed oracle.
2. zeroj-bom-core/README.md would have broken consumers. Its example depended on
the removed zeroj-verifier-core and on MPF/JMT without versions even though
those are deliberately outside the BOM; its module list still advertised
gnark, prover-SPI, cardano, ccl and patterns. Rewritten to match the generated
BOM, with an explicit "not in this BOM" section.
3. Active instructions that could not work:
- CONTRIBUTING.md told contributors to build the removed gnark and Halo2
providers; replaced with the real opt-in builds and the module-group model.
- zeroj-verifier-plonk and zeroj-codec READMEs still said to verify gnark
binary PlonK artifacts "with gnark native verification", which no longer
exists anywhere in ZeroJ.
- Both benchmark READMEs omitted -PincludeBenchmarks, so every documented
command failed to locate the project; their ../docs and ../zeroj-* links
were also off by one directory after the move.
- The published MPF/JMT READMEs still linked to the old top-level load-module
paths.
4. NOTICE described dependencies that are no longer shipped: it claimed
zeroj-prover-gnark compiles gnark into a loaded shared library, and kept
entries for Halo2 and GraalVM Polyglot. gnark attribution is retained and
corrected (it is now a non-published fixture generator only); the two removed
entries are dropped and Chicory is added for the assurance WASM providers.
Also repairs every remaining broken relative markdown link in the repository,
including three in docs/usecases/README.md that predate this branch. A repo-wide
check now confirms all relative links resolve.
Verification:
yaml parse of all 5 workflows OK
./gradlew -PincludeAssurance :zeroj-bls12381-wasm:test :zeroj-bbs-wasm:test \
:zeroj-bbs:test BUILD SUCCESSFUL 2m31s,
wasm-zkcrypto rows present
assurance.yml gnark job sequence, run verbatim make gen -> plonk suite
passes incl.
GnarkTranscriptCompatTest
-> vectors restored
byte-for-byte
./gradlew verifyDefaultModuleSurface passed, 21 projects
./gradlew build -PskipSigning=true BUILD SUCCESSFUL 2m13s
canonical resource SHA-256 set unchanged
repo-wide relative markdown links all resolve
No cryptographic algorithm, encoding, transcript, public-input order, circuit
relation, proof equation, trusted-setup or validation behavior changes. No
maturity, audit, production or mainnet claim is upgraded.
Refs: ADR-0044 M1/M2/M6, #24
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tatus ADR-0044 M2 requires establishing the BLS/BBS WASM differential job before changing their default-build membership. That job now exists as .github/workflows/assurance.yml, so the status section records it rather than just claiming the oracles were "preserved". Refs: ADR-0044 M2, #24 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…le references
Third review pass. My earlier documentation sweeps only covered tracked markdown,
so a shell script, two Java javadocs and a source comment were missed.
1. docs/ceremony/rehearsal.sh built its classpath from
zeroj-ceremony/build/classes/..., which no longer exists after the merge, so
the rehearsal failed outright in a clean checkout. Repointed at zeroj-tools
(CeremonyCli in main, MulFixtureCircuit in test) and executed end to end:
export-r1cs -> snarkjs setup -> ZeroJ contribution -> snarkjs contribution ->
ZeroJ contribution -> beacon -> `snarkjs zkey verify` ("ZKey Ok!") -> finalize
into a ZeroJ proving-key store. The independent mixed-tool transcript check
passes after the merge.
2. docs/vision-v3.md still described removed modules as current functionality. I
had classified this file as pure history and skipped it, but its "Shipping
today" section is a present-tense claim. Corrected to the retained pure-Java
and blst providers, with the removed gnark/Halo2 runtimes, pattern verifiers
and Cardano transaction helpers listed as deliberately out of SDK scope. The
nullifier/membership paragraph now says plainly that proof validity is not
application authorization, rather than pointing at zeroj-patterns.
ReferenceScriptDeployer's javadoc no longer names zeroj-ccl.
3. Executable commands that could not work:
- both 5M benchmark reports omitted -PincludeBenchmarks on every load-tool
invocation;
- the two migrated Yaci tests still documented :zeroj-examples:e2eTest.
Also adds an ADR-0044 supersession note to ADR-0007, whose whole subject is the
module table, so a reader is not left treating a 2026-03 structure as current.
A sweep over every tracked file type (not just markdown) now shows only correct
paths, deliberate migration guidance, and point-in-time ADR history.
Verification:
docs/ceremony/rehearsal.sh full ceremony, exit 0
./gradlew build verifyDefaultModuleSurface SUCCESSFUL 6m25s, 21 projects
./gradlew -PincludeBenchmarks :zeroj-mpf-poseidon-load:build \
:zeroj-jmt-poseidon-load:build SUCCESSFUL 39s
git diff --check clean
repo-wide relative markdown links all resolve
No cryptographic algorithm, encoding, transcript, public-input order, circuit
relation, proof equation, trusted-setup or validation behavior changes.
Refs: ADR-0044 M6, #24
Co-Authored-By: Claude Opus 5 (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.
Implements ADR-0044: narrows the published surface to the Java-first product path, removes the gnark and Halo2 native runtime providers, and moves the WASM assurance providers and MPF/JMT load tools out of the default build.
Closes #24 once the one open gate below is closed.
Risk
R1 structural, with R2 assurance impact. No cryptographic algorithm, proof equation, transcript, domain separator, public-input order, circuit relation, canonical encoding, trusted-setup rule, or validation rule changes. No maturity, audit, side-channel, production, or mainnet claim is upgraded.
Two proofs of that, rather than an assertion:
git diff a662b2a..HEADacross all 16 cryptographic modules (zeroj-api,zeroj-codec,zeroj-bls12381,zeroj-crypto,zeroj-crypto-blst,zeroj-blst,zeroj-circuit-*,zeroj-verifier-*,zeroj-onchain-julc,zeroj-mpf-poseidon,zeroj-jmt-poseidon,zeroj-test-vectors) is empty.src/**/resources/**file before and after shows zero content changes to any surviving resource — test vectors, ServiceLoader files and native-image metadata are byte-identical. The only removals are the 20 files owned by removed providers; nothing was added.Module surface: 35 → 21 root projects
zeroj-bom-core)zeroj-api,zeroj-codec,zeroj-backend-spi,zeroj-verifier-groth16,zeroj-bls12381,zeroj-blst,zeroj-crypto,zeroj-crypto-blst,zeroj-circuit-dsl,zeroj-circuit-lib,zeroj-circuit-annotation-api,zeroj-circuit-annotation-processor,zeroj-onchain-julc,zeroj-toolszeroj-verifier-plonk,zeroj-bbs,zeroj-mpf-poseidon,zeroj-jmt-poseidonzeroj-test-vectors,zeroj-integration-tests,zeroj-bom-coreassurance/zeroj-bls12381-wasm,assurance/zeroj-bbs-wasm(-PincludeAssurance);benchmarks/zeroj-{mpf,jmt}-poseidon-load(-PincludeBenchmarks);assurance/gnark-fixtures(plain Go)Removed:
zeroj-prover-gnark,zeroj-prover-spi,zeroj-verifier-halo2,zeroj-prover-wasm,zeroj-cardano,zeroj-ccl,zeroj-patterns,zeroj-examples,zeroj-bom-all.Merged:
zeroj-verifier-core→zeroj-backend-spi,zeroj-ceremony→zeroj-tools. Packages preserved (…verifier.core,…ceremony), so consumer imports do not change — only the dependency coordinate does. All 8 moved files are byte-identical to their originals.Coordinate migration table:
docs/migration/0044-module-cleanup.md.Assurance preserved, not lost
This is the part worth reviewing closely, since removing modules is how differential coverage silently disappears.
test-vectors/plonk-bls12381is gnark v0.14.0 output, consumed in the default build byGnarkTranscriptCompatTest, which pins that ZeroJ's Fiat-Shamir transcript derives byte-identical γ/β/α/ζ to gnark's verifier. So the minimal pinned generator survives atassurance/gnark-fixtures/— no shared library, no Java FFM API, in no Gradle or publication graph. Verified by generating a fresh independent proof and confirming the Java PlonK suite still accepts it.BbsBlsProviderConformanceTestran the official CFRG draft-10 vectors through pure-Java, blst and WASM. Moving the WASM module out would have silently dropped a row. It now discovers the provider reflectively and the assurance build setszeroj.assurance.requireWasmProvider, so a demanded oracle that cannot be constructed fails the run rather than shrinking it. Mutation-tested: demanding it without the classpath entry fails withIllegalStateException..github/workflows/assurance.ymlruns both WASM suites and:zeroj-bbs:test(that last target is what actually exercises the WASM row), plus a gnark-fixture job — on push, PR, nightly and manual dispatch.verifyDefaultModuleSurfaceguard asserts the stable runtime graph has no edge into an assurance/benchmark/removed module, that MPF and JMT stay independent, that the annotation API and processor stay separate, and that no pure-Java module acquires a native/WASM dependency. Wired into CI, snapshot and release.Test migration
Every security regression moved out of
zeroj-examplesbefore it was deleted, green inzeroj-integration-tests(47 tests): ADR-0037 comparator soundness, circuit relation + BN254 curve policy, annotation companions and public-input ordering, pure-Java Groth16 full stack, snarkjs independent-prover interop (Groth16 + PlonK), Julc VM and Yaci on-chain, plus a new packaged-JAR ServiceLoader test.Dropped deliberately: three assertion-free demos,
CircuitSizeTest(printed only), and the gnark-bound test/helper.Verification
./gradlew build verifyDefaultModuleSurface-PincludeAssurance…:zeroj-bbs:testwasm-zkcryptorows present-PincludeBenchmarksload tools:zeroj-integration-tests:e2eTest:zeroj-tools:nativeDistZipzeroj-ceremony 0.1.0-pre11, all 3 subcommands, correct zip namedocs/ceremony/rehearsal.shsnarkjs zkey verify→ "ZKey Ok!"zeroj-usecases~/.m2so the test was genuinegit diff --check, repo-wide relative linksThe Yaci DevKit on-chain E2E suite has not been executed. The tests were migrated and are correctly discovered, but skipped because no local DevKit was running. ADR-0044's implementation status is therefore deliberately "In progress", not "Implemented".
To close it:
# with Yaci DevKit running ./gradlew :zeroj-integration-tests:e2eTestSealedBidOnChainE2ETestandPureJavaProverYaciE2ETestmust show passing, not skipped. Then flip the ADR status.Known pre-existing issue (not from this PR)
R1csSnarkjsCeremonyRoundTripTestandZkeyPkStoreImporterTestinzeroj-cryptohardcode$HOME/.npm-global/bin/snarkjsand only check the script is executable, so they fail hard whennodeis absent rather than skipping. Reproduced identically onmain(a662b2a); this branch never toucheszeroj-crypto. Also conflicts with AGENTS.md's "no developer-specific absolute paths" rule. Worth a follow-up issue.🤖 Generated with Claude Code