Releasing
A release has to be checkable byte for byte by anyone: its checksums, its signature, and the match between the source archive and the tag. These are the steps a maintainer follows.
Version numbers
Three parts, major.minor.patch. Every version’s changes go into the change log: what was added, changed and fixed, changes to file formats and command-line output, and what users have to do when upgrading. Ledger mirrors, the command line’s ledger folders and record kits are read by a new version as usual; local encrypted files, the machine folder and data folders are read in the version’s own form, and when that form changes, the change log, the release notes and the manual’s “Upgrading from an earlier version” say how data comes across by hand. The law’s version is written in its spec name and is independent of the software version.
Before a release
- Every test passes on main: continuous integration builds and tests release builds on macOS, Linux and Windows, the macOS and Linux cells also building the way a release does and checking that the binaries carry neutral path names alone; each platform’s packages are then installed and opened once on a real machine.
- Both digests of the law recompute to their values.
- The cores show zero divergences against the frozen cores, and every chain-facing recording replays identically.
- The contract’s code hash recomputes correctly.
- The Chinese and English manuals match the interface sentence for sentence.
- The six first-launch steps are walked through on a clean machine.
- Install over the previous version on a machine with data; the machine folder and data folders are used as they are, and the ledger check answers “OK”.
- A ledger mirror exported by 0.1.2 is brought across by the manual’s “Upgrading from an earlier version”, and the ledger check answers “OK”.
- A whole-machine backup exported on one system is restored once on each of the others.
Build
Release files are built from the tagged commit, each system with its own tool:
git tag v0.1.5- macOS
- The script first builds
packaging/macos/build.sh --identity Kaptoniazikaron-pack, which gives the compiler flags for the path mappings (zikaron-pack rustflags), then builds the app and the command line with--lockedand checks withzikaron-pack no-pathsthat the binaries carry neutral path names alone, stopping before packaging if anything is left; it then puts the window programzikaron-desk, the command linezikaronand the third-party licences intoZIKARON.app, signs and verifies each one, then makesdist/ZIKARON-<version>-macos-<arch>.dmg(with a link to Applications) and a.pkg(the app into/Applications, the command line into/usr/local/bin), and writesSHA256SUMS-macos-<arch>.txt. Extended attributes are stripped, and the owners, dates and partition names in the dmg and the owners and dates in the pkg are made neutral. - Linux
- Builds on Linux itself, with the same path mappings and path check as on macOS; on another host, use
packaging/linux/build.shcross-build.sh, targeting glibc 2.31.build.shmakes the.debwithdpkg-deb, andcross-build.shwrites it withpackaging/linux/make_deb.py; the AppImage is the pinned AppImage runtime followed by an image made withmksquashfs, these two alone. The runtime is pinned by its bytes (type2-runtime 8f39b89 for x86_64), and a downloaded one that differs stops the build, when the pinned file is handed to the script asAPPIMAGE_RUNTIME; aarch64 still awaits a pinned runtime and gets the.debalone. The third-party licences go in/usr/share/doc/zikaron-desk/, and the binaries’.commentsection is emptied. - Windows
- Built on Windows with MSVC, it lays out the folder
cargo run --release --locked -p zikaron-pack -- windows --out distdist/ZIKARON-<version>-windows-x86_64/, which is then zipped for the release page.
Binaries are stripped of symbols; the paths of the home directory, the Cargo and rustup directories, the source and the build directory are mapped away at compile time, by one table in zikaron-pack shared by all three systems, and every date in a package comes from SOURCE_DATE_EPOCH (the commit time by default), so the product is independent of the build machine.
Checksums and Zikaron record
- Compute the SHA-256 of every release file (each platform’s packages and the source archive) and gather them into one release list,
SHA256SUMS.txt; the three platforms’ third-party licences are published separately. The release page carries ten files: six packages, the release list and three licence lists. - Before publishing, record ten records in the project’s Zikaron ledger and anchor them on chain together: the six packages, the two programs in the Windows package, the release list, and the commit; the transaction, block, recorder address and each fingerprint are on the Checksums page.
- The release page, the website’s download page and the list agree in all three places; the download page’s “Zikaron record” column carries each file’s anchoring transaction.
How users check them is under Checksums.
System signing
The app and the dmg are signed with the project’s own certificate, whose common name is Kaptonia; the project issues this certificate itself, the release is outside Apple’s notarization, and the project publishes it directly. Every version is signed with the same certificate and the same identifier, com.kaptonia.zikaron.app, so the system recognizes each version as the same app. The pkg is checked by its SHA-256. The Windows zip and the two Linux packages are unsigned and checked by their SHA-256.
Files downloaded in a browser carry a quarantine flag, and macOS refuses to open them; on recent macOS, “Open Anyway” works only some of the time. The way the download page and the release notes give is: check the file with shasum -a 256 first, then remove the quarantine flag in Terminal with xattr. On Windows, the first start takes “More info”, then “Run anyway”; on Windows 11 with Smart App Control on, turn it off first. Users who want to confirm where a file came from can check its signer, certificate fingerprint, checksum and Zikaron record; see Checksums.
Release notes
For every version, state what was added, changed and fixed; changes to file formats and command-line output; what users have to do when upgrading; and known limitations. CHANGELOG.md and CHANGELOG.en.md in the repository record each version, and the release notes link to them and to that version’s manual.
Contract and networks
The app carries a table of four known deployments (Ethereum mainnet, Sepolia testnet, Arbitrum One, OP Mainnet), each with a chain ID, registry contract address, start block and two preset nodes. Before adding a row:
- Read the code from the chain and check its code hash.
- Confirm that the start block comes before the first anchor on that contract.
- Choose two preset nodes from different sources, both with TLS, both answering the right chain ID, each measured to hold the complete logs since the start block, matching entry for entry, and refusing too wide a query range in words; nodes that serve only a recent window, charge, or rate-limit are left out.
Once a row is released, its chain ID, registry contract and start block stay as they are, and old ledgers go on being verified by them. A preset node whose logs become incomplete can be replaced: a data folder copies a row’s nodes when it is made, so a replaced pair reaches data folders made afterwards, and an existing data folder’s nodes are the user’s to change.
The website
With every version the website updates the file names, sizes, checksums and Zikaron records on its download page. The pages are generated by a script in the repository, and the output is committed with it.
After a release
- Download a copy from the release page, then check, install and open it by the users’ own steps.
- Confirm that the drop zone on the download page answers “Matches the release list” for every file.
- When a release file turns out to be wrong, publish a new patch version; published files and checksums stay as they are.