Liking cljdoc? Tell your friends :D

Vinary Tree 4.0.0-rc.4 release ledger

Train opened: 2026-08-24
Canonical tag: v4.0.0-rc.4
Policy: coordinated release runbook
Predecessor evidence: 4.0.0-rc.3
State: local source validation complete; immutable source freeze in progress.

This append-only ledger is the operational source of truth for RC.4. It records the clean-build corrections after RC.3, exact source commits and workflow runs, registry digests, and independent installed-byte proofs. The living runbook defines reusable procedure; this ledger records observed facts.

Why the train advanced

RC.3 root validation exposed two hidden prerequisites: a JavaScript test job loaded a native addon that it never built, and a JVM collection test used a native dictionary provider that it never staged. The RC.4 correction closes those defects and the version-drift weakness found while reproducing them:

  1. The npm package job invokes the shared runtime's existing local configuration, native SDK bootstrap, and release addon build against exact RC.4 siblings.
  2. The JVM job stages exact RC.4 interop and libdictenstein sources, builds libdictenstein with its ffi contract, publishes the interop JAR to an isolated staging repository, and passes the provider directory explicitly.
  3. Gradle canonicalizes both default and caller-supplied native directories to absolute paths before tests fork.
  4. Each Rust owner synchronizer now writes and validates its own family package entries in Cargo.lock. Native SDK bootstrap passes --locked and executes Cargo from each crate owner, preventing a runtime-only patch overlay from leaking patch.unused metadata into independent lockfiles.
  5. The root JavaScript facade removed unused @cljs-oss/module-deps. The actual ClojureScript compiler path does not use it; removal eliminates its obsolete Babel/core-js dependency graph and the three critical clean-install advisories it introduced.

These are release-reproducibility repairs. They do not change dictionary or matching semantics.

Clean-layout reproduction evidence

A build-clean family was created under a unique /tmp/vinary-release-family-rc4.* directory by cloning each current owner through Git's shared-object mechanism and applying only its tracked RC.4 working diff. No target, Gradle build, native addon, npm installation, or runtime SDK output existed at the start.

ContractClean-layout observationResult
seven-owner identityall seven owner synchronizers accepted RC.4; the root train checker accepted seven standalone owners, exact edges, npm next, Hackage/fpm embargoes, and legacy latest protectionpassed
runtime bootstraplocal interop types installed with zero advisories; configure/bootstrap compiled libdictenstein, liblevenshtein, lling-llang, and duallity; node-gyp produced native/build/Release/vinary_tree_native.nodepassed
locked SDK rebuildall five owner lockfiles were copied from source, native bootstrap rebuilt with --locked, and byte comparison proved every lockfile remained unchangedpassed
root npm facadenpm ci installed only three local family packages with no obsolete bundler graph; build, TypeScript contract tests, three runtime facade tests, and two ClojureScript tests/four assertions passedpassed
JVM dependency stagingexact interop 4.0.0-rc.4 staged locally; exact libdictenstein 4.0.0-rc.4 built with ffi; root tests received absolute native directoriespassed
JVM collection/resource behaviorclean Gradle test javadoc completed successfully, including DictionaryCollectionsTest; local JDK 26 compiled Java 22 bytecode, while the tag workflow remains pinned to JDK 25passed
workflow syntaxevery YAML workflow/action in all seven repositories parsed successfullypassed

The temporary family is retained only until commits and local tags have been verified, then removed explicitly together with older RC rehearsal directories.

Local release-gate evidence

The clean-layout reproduction was followed by the owner-native gates below. Every command used Rust 1.95 where the owner declares that MSRV. Generated artifacts were rebuilt before package inspection rather than accepted from a prior candidate.

Owner or surfaceLocal observationResult
vinary-tree-interopfull verifier passed Rust layout/evolution tests, C17 and C++23 headers, JavaScript, Python, Go, .NET, JVM/Javadoc, Swift, Fortran, OCaml, and Haskell; cargo package --locked built and verified the crate archivepassed
javascript-runtimesource and built verifiers passed native, leak, property, browser-WASM, WASI, and package-shape tests; a full npm prepack rebuilt both WebAssembly targets and produced the expected 15-file archivepassed
libdictenstein862 default tests, 3,046 debug all-feature tests, and 3,046 release all-feature tests passed; the exact FFI suite passed 97 tests and the query-start snapshot contract passed 7; binding, documentation, ABI, MathJax, Clippy, npm prepack, and native staging gates passedpassed
liblevenshtein-rust1,775 default tests, 4,903 debug all-feature tests, and 4,903 release all-feature tests passed with five intentional skips in each all-feature run; the exact snapshot contracts passed 7, 10, and 5 tests; binding, ABI, MathJax, Clippy, npm/TypeScript/ClojureScript, JVM/Javadoc, and native staging gates passedpassed
lling-llang2,567 default and 2,841 release all-feature tests passed; both release-workflow FFI matrices, binding/documentation/ABI/MathJax, Clippy, npm prepack, native staging, and installed shared/static CMake consumers passedpassed
duallity257 default and 374 release all-feature tests passed; the FFI-only workflow matrix passed 152 unit, 33 integration, and 10 documentation tests; binding/documentation/ABI/MathJax, Clippy, npm prepack, native staging, and installed shared/static CMake consumers passedpassed
scoped and compatibility npm facadesall seven prepack lifecycles passed and exposed exact 4.0.0-rc.4 identities, exact family pins, and the intended archive file setspassed
repository policyall seven workflow trees parsed as YAML, all synchronizers and the aggregate train checker accepted the graph, formatting and whitespace checks passed, and all seven pgmcp bug-gate invocations reported no open bug anchored to a changed filepassed

Cargo fully verified the dependency-free interop crate archive. Packaging each downstream crate then stopped at its first exact, intentionally unpublished RC.4 crates.io edge. This is the expected dependency barrier, not a substituted source dependency: each downstream cargo package/cargo publish verification is repeated only after its exact upstream registry version resolves.

RC.4 source freeze

Populate this table only after each worktree is clean, every local gate passes, and the enumerated commit has been created. Tags are annotated locally only after the complete source graph is frozen. No branch or tag is pushed without a fresh, explicit operator approval naming the exact repositories and refs.

OwnerRC.4 commitLocal gatesImmutable-tag runState
vinary-tree-interop1614a522172ca33c90815920c82c5e07afec6918full platform verifier, crate/npm package, docs, lock, and policy gates passedpendingsource frozen
javascript-runtime589b7570f38e9fbb98b10c54258bab8fcabde252native/WASM/WASI, leak/property, npm package, docs, lock, and policy gates passedpendingsource frozen
libdictenstein085f61c22f714f6a9c2aee528077be180b9545d4default/all-feature, exact FFI/snapshot, binding, native/npm package, docs, lock, and policy gates passedpendingsource frozen
liblevenshtein-rustrecorded by the RC.4 tag after this ledger commitdefault/all-feature, exact snapshot, binding, clean npm/JVM, native/npm package, docs, lock, and policy gates passedpendingfreezing
lling-llang0930c458dbec804210f521425ef901ebd00be86b on local release/4.0.0-rc.4default/all-feature, FFI, binding, native/npm package, docs, lock, and policy gates passedpendingsource frozen
duallity6a79b8c571dac0ec3f1477c3046ab1bd86164199 on local release/4.0.0-rc.4default/all-feature, FFI, binding, native/npm package, docs, lock, and policy gates passedpendingsource frozen
liblevenshtein-npm44c9812d983bddd7343828ee48095a2c3732aa0ccompatibility, delegation, npm package, legacy-channel, and policy gates passedpendingsource frozen

Dependency-ordered publication barriers

Every stage begins only after the exact public bytes from the preceding stage resolve and pass an independent consumer:

  1. interop crate and @vinary-tree/interop;
  2. libdictenstein crate, followed by its registry-shaped bindings;
  3. liblevenshtein crate, followed by its registry-shaped bindings;
  4. lling-llang crate, then duallity crate;
  5. @vinary-tree/vinary-tree native/WASM/WASI runtime;
  6. scoped libdictenstein, liblevenshtein, lling-llang, and duallity npm facades;
  7. unscoped liblevenshtein under next only; and
  8. scoped npm dist-tag normalization after an all-package installed-byte smoke.

Each GitHub dispatch uses refs/tags/v4.0.0-rc.4, one registry selector, and a tag-restricted protected environment. A downstream dispatch never substitutes a source checkout for a required public dependency.

Registry evidence

CoordinateWorkflow/protected environmentPublic digestIndependent consumerState
vinary-tree-interop@4.0.0-rc.4pendingpendingCargo ABI/status/resource smoke pendingnot published
@vinary-tree/interop@4.0.0-rc.4pendingpendingCommonJS/ESM identity smoke pendingnot published
libdictenstein@4.0.0-rc.4pendingpendingdictionary/map/snapshot smoke pendingnot published
@vinary-tree/libdictenstein@4.0.0-rc.4pendingpendingCRUD/traversal/batching/disposal smoke pendingnot published
liblevenshtein@4.0.0-rc.4 cratependingpendingconstruction/query smoke pendingnot published
@vinary-tree/liblevenshtein@4.0.0-rc.4pendingpendingquery/stream/disposal smoke pendingnot published
lling-llang@4.0.0-rc.4 crate and facadependingpendingautomata/traversal smoke pendingnot published
duallity@4.0.0-rc.4 crate and facadependingpendingWFST/bridge/disposal smoke pendingnot published
@vinary-tree/vinary-tree@4.0.0-rc.4pendingpendingnative CJS/ESM, browser-WASM, and WASI smoke pendingnot published
liblevenshtein@4.0.0-rc.4 compatibility facadepending under next onlypendingCommonJS/ESM delegation smoke pendingnot published

npm postconditions

Only after all exact RC.4 tarballs pass the combined installed-package smoke:

  • the six scoped coordinates must report latest = next = 4.0.0-rc.4;
  • no scoped coordinate may retain bootstrap;
  • every immutable 0.0.0 namespace reservation must carry the documented bootstrap deprecation;
  • rejected @vinary-tree/libdictenstein@4.0.0-rc.1 must direct users to RC.4 or newer; and
  • unscoped liblevenshtein must report latest = 2.0.4 and next = 4.0.0-rc.4.

Interactive web authentication is used for dist-tag and deprecation mutations. Publishing uses the repository workflow's provenance-bearing trusted publisher; no long-lived 2FA-bypass token is required.

Operator checklist

  • [x] RC.3 failure is closed with exact run/job evidence and no moved tag.
  • [x] All seven canonical models and generated dependency edges identify RC.4.
  • [x] Synchronizers own and validate every primary Cargo lockfile family entry.
  • [x] Clean JavaScript and JVM reproductions close both RC.3 defects.
  • [x] Complete every pre-publication default/all-feature, FFI, binding, documentation, registry-shape, native/npm package, and pgmcp bug-gate validation; retain downstream Cargo package verification at its exact public-dependency barrier.
  • [x] Render every changed PlantUML diagram headlessly and validate MathJax.
  • [ ] Create seven descriptive, enumerated commits and seven local annotated tags; verify every tag peels to its intended commit.
  • [ ] Request and receive explicit approval naming every branch/tag push before using any remote push command.
  • [ ] Dispatch validate-only workflows in dependency order and record exact run URLs, commits, job conclusions, and GitHub release checksums.
  • [ ] Publish each authorized registry coordinate only after its public upstream dependencies resolve; verify exact downloaded bytes independently.
  • [ ] Normalize npm metadata, update this ledger and pgmcp with final evidence, clean all temporary release directories, and prove every worktree clean.

Completion condition

RC.4 is complete only when all intended coordinates have exact source, workflow, digest, and clean-consumer evidence; every npm tag/deprecation invariant holds; all documentation and pgmcp records agree; temporary evidence has been removed; and every release worktree is clean. A local pass, tag, upload, or registry metadata listing alone is not completion.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close