Release 2.4.1, ID 442808765, was published at 2026-11-12 10:46:44 UTC. Its immutable tag resolves to a3b09eca6333c2befda3504850f357f09cc25542. Linux 43192014736, macOS 43203354756, Flatpak 43203358489 and Windows 43203362035 all completed successfully on attempt 1.
The full public audit passed at 11:28:33 UTC: 23 assets, nine installers, three source archives, five checksum sets/12 rows and six authenticated Linux payloads. Public Windows qualification records separate installation, payload equality, native UI, scripted endurance and real-model outcomes.
Main independently rechecked all 15 required gates for x86_64 and aarch64, including source/run/attempt, immutable artifact identities and script/package hashes. The protected-source activation pinned a3b09ec and added the exact v2.4.1 allowance with existing review protections retained. Fresh environment, tag-rule and tooling readbacks preceded signing approval at 10:44:07 UTC.
APT verification passed at 10:50:26 UTC after job 131132225135. Both signatures verified against current fingerprint 1BC07B5ECFDB514673A296FB021CAB3F2F7A1F61; six signed index sizes/hashes matched and both 2.4.1 pool DEBs matched the verified public release. This verifier installed no package.
Current Linux download names:
| Role | x86_64 | aarch64 |
|---|---|---|
| AppImage | ShadowCode_2.4.1_amd64.AppImage |
ShadowCode_2.4.1_aarch64.AppImage |
| Debian package | ShadowCode_2.4.1_amd64.deb |
ShadowCode_2.4.1_arm64.deb |
| Runtime sources | ShadowCode_2.4.1_appimage-runtime-sources.tar.gz |
ShadowCode_2.4.1_aarch64_appimage-runtime-sources.tar.gz |
Checksums/manifests/envelopes/signatures retain their per-target filenames. Ed25519 authentication covers the six Linux payloads; other platforms have separate checksum and qualification records. No new physical Mac/Linux installation acceptance is claimed for 2.4.1. Tags and versioned assets remain immutable.
The following is the retained November 12 checkpoint. Its current/pending wording describes that historical state, not the new release.
The current published Linux release is 2.4.0,
from immutable tag v2.4.0 at 25c8345f99f246b37ea45bf9306eb551da9c0819.
Release run 43145082420,
attempt 1, passed all 15 required gates for each of x86_64 and aarch64,
then protected signing, publication and APT publication. GitHub release
442500290 became public on November 12, 2026 at 04:35:24 UTC
(November 11 in US Eastern time). At 04:37:08 UTC, all 14 Linux public assets
were downloaded and their hashes checked; all six payloads were authenticated
against the tracked Ed25519 trust bundle. Required gates had no required skips;
explicitly optional live checks retain the exclusions recorded in their receipts.
Windows, macOS and Flatpak 2.4.0 are also published. Their separate workflows passed and all 23 final public assets were downloaded and checked against their published hashes. See platform workflow results and public-byte verification. Physical Windows qualification then exposed composer overlap with the terminal Hide control at 175% zoom in a short window. A 2.4.1 source candidate is being prepared for that fix; the immutable 2.4.0 release remains unchanged and the website download promotion waits for the corrected installer’s qualification. The local Mac development qualification in MAC_FLAGSHIP_UPGRADE.md remains separate from native platform acceptance.
The verified 14-asset Linux publication contains exactly these seven files per target; later platform attachments are outside this inventory:
| Role | x86_64 | aarch64 |
|---|---|---|
| AppImage | ShadowCode_2.4.0_amd64.AppImage |
ShadowCode_2.4.0_aarch64.AppImage |
| Debian package | ShadowCode_2.4.0_amd64.deb |
ShadowCode_2.4.0_arm64.deb |
| Runtime sources | ShadowCode_2.4.0_appimage-runtime-sources.tar.gz |
ShadowCode_2.4.0_aarch64_appimage-runtime-sources.tar.gz |
| Checksums | SHA256SUMS |
SHA256SUMS-aarch64 |
| Manifest | RELEASE-MANIFEST.json |
RELEASE-MANIFEST-aarch64.json |
| Signed envelope | RELEASE-AUTH |
RELEASE-AUTH-aarch64 |
| Ed25519 signature | RELEASE-AUTH.sig |
RELEASE-AUTH-aarch64.sig |
The APT job
succeeded at 04:38:26 UTC. Independent live verification at 04:40:38 UTC
confirmed 2.4.0 for amd64 and arm64, both repository signatures, all six signed
index files and byte-for-byte equality of the APT pool packages with the public
GitHub DEBs. The pinned GPG fingerprint is
1BC07B5ECFDB514673A296FB021CAB3F2F7A1F61; see APT repository.
The external publication evidence is retained under publication-2.4.0/:
release-handoffs/{x86_64,aarch64}-verified.json,
public-linux/public-verification.json, and apt-public-verification/proof.json. A portable copy of the public Linux verification, APT verification, and x86_64/aarch64 handoff checks is tracked with this documentation.
Pushing a v* tag starts .github/workflows/release.yml. Publication follows
both Linux architectures' build/qualification, protected signing review and
verification of the signed public assets. The publish job then dispatches the
Windows, macOS and Flatpak workflows. Confirm their assets independently before
advertising that platform's new version. Existing versioned assets and tags are
immutable; do not move v2.4.0 or overwrite its published assets.
Live configuration was read back for this publication: the independently reviewed
NATIVE_RELEASE_TOOLING_COMMIT is 25c8345f99f246b37ea45bf9306eb551da9c0819,
and release-signing permits the exact tag v2.4.0 alongside the retained
v2.3.1, v2.3.2 and v2.3.3 rules. Required owner review and self-review settings
are unchanged. All environment settings must be read live for later releases.
Historical preparation snapshot, November 11, 2026: before the 2.4.0 update,
only those three 2.3.x tags were allowed and the reviewed tooling pin was
fd13dc10dbdcc6aac63cdfb292f9ec4d47838347. The reviewed policy extension through
2.4.0 preserved the existing key identity, epoch, historical floor and targets.
These application and packaging fields must carry the same version, and the
tag must be v<version>. The release tag gate checks the four application fields;
the Debian metadata suite independently compares the newest AppStream entry
with Cargo, UI and Tauri versions before packaging:
| File | Field |
|---|---|
Cargo.toml |
[workspace.package] version |
src-tauri/tauri.conf.json |
version |
ui/package.json |
version |
packaging/shadow-agent.desktop |
X-ShadowCode-Version= |
packaging/com.shadowfetch.shadowcode.appdata.xml |
Newest <release version=...> and its date; preserve earlier entries |
Update the workspace package entries in Cargo.lock and the root package
versions in ui/package-lock.json alongside those files; keep locked
builds reproducible. Update CHANGELOG.md and docs/RELEASE_NOTES.md. The notes file becomes the
GitHub release text as it is, so it should start with this release. Notes of
earlier releases may follow below it, as they do now.
The runtime is built from tools/llama.cpp.pin (commit= and
spirv_headers_commit=). On Ubuntu 24.04:
sudo apt-get install cmake ninja-build libssl-dev libvulkan-dev glslc spirv-headers
bash scripts/build-llama.cpp.sh --no-user-install
node --test scripts/test-llama-runtime.mjs- glslc. Without it or the Vulkan headers, the script falls back to a
CPU-only runtime with only a warning. Before packaging, check that
packaging/llama.cpp/bin/COMMITsaysbackend=vulkan+cpu. The script looks for glslc inSHADOWCODE_GLSLC, then onPATH, then in a user-installedorg.freedesktop.Sdkflatpak (tools/glslc-flatpak.sh). - cmake. Found in
SHADOWCODE_CMAKE, then.venv/bin/cmake, then onPATH. - Notices. The script copies the license texts of llama.cpp/ggml,
cpp-httplib, nlohmann/json, stb_image, miniaudio, subprocess.h and
SPIRV-Headers into
NOTICES/. The same texts are pinned with SHA-256 digests in licenses/native (llama.cpp-<short>/,SPIRV-Headers-<short>/). - Moving the pin. Update
tools/llama.cpp.pinand those notice directories together. Run--notices-onlyto refreshNOTICES/andCOMMITof an existing build without recompiling. Packaging refuses a runtime whose commit or notices don't match the pin.
npm --prefix ui ci
npm --prefix ui run typecheck
npm --prefix ui test
npm --prefix ui run build
(cd ui && npm run test:e2e)
cargo +1.95.0 fmt --all --check
cargo +1.95.0 clippy --workspace --all-targets --locked -- -D warnings
cargo +1.95.0 build -p shadowcode-desktop --locked
cargo +1.95.0 test --workspace --locked
node scripts/test-native-cli.mjs
node scripts/test-native-stress.mjs
node scripts/test-native-tui.mjs
node scripts/check-secrets.mjsBuild the desktop executable before running the Rust suite: the process tests
launch target/debug/shadowcode. The scripts need Node.js 22.12 or newer,
like the UI: with an older node first on PATH, test-native-cli.mjs
stops with ERR_UNKNOWN_BUILTIN_MODULE (node:sqlite). A change to the
window also needs the window test on X11 and on a private Wayland
compositor (see NATIVE_DESKTOP.md; Weston 13 and
WebKitWebDriver can be unpacked copies):
node scripts/run-native-x11.mjs node scripts/test-native-desktop.mjs
node scripts/run-native-wayland.mjs node scripts/test-native-desktop.mjscheck-secrets.mjs also runs in the CI
"Checks" workflow, not in release.yml; run it before pushing the tag.
Live turns against real accounts (live_vendor_turn) are described under
Tests in the README.
On the pinned Ubuntu 24.04 build environment, with Docker, or Podman plus
SHADOW_CONTAINER_ENGINE=podman, for the pinned AppImage runtime build:
node --test scripts/test-native-packaging-env.mjs
node scripts/build-native.mjs
node scripts/check-native-package.mjs \
target/release/bundle/appimage/ShadowCode_VERSION_amd64.AppImage \
target/release/bundle/deb/ShadowCode_VERSION_amd64.deb
node scripts/test-native-runtime-write-errors.mjs
node scripts/test-native-runtime-sources.mjs
node scripts/test-native-runtime.mjs
bash scripts/test-install-appimage.shbuild-native.mjscheckspackaging/llama.cpp/bin(pin, SPIRV-Headers commit,architectures.txt, notices) before it builds. It copies the runtime into the AppDir with its relative links kept, and repacks the deb with/usr/lib/shadowcode. It sets its own cleanPATHand records the Git commit (SHADOWCODE_COMMIT,-dirtyfor local changes) for Settings › About. The deb repack (scripts/native-deb.mjs) adds the Debian copyright and changelog (from the AppStream releases), the manual page and shell completions generated by the packaged executable, hicolor icons, lintian overrides and thelibc6floor, strips the runtime and fixes modes.check-native-package.mjschecks both packages:- no absolute, escaping or dangling links;
COMMITmatches the pin;- every
NEEDEDlibrary is bundled or an allowed system library; llama-server --versionprints the pinned commit and--list-devicesruns withLD_LIBRARY_PATHunset;- notice digests match, and there are no Python or Node sidecars;
- the deb depends on
libgomp1andlibssl3; - the deb is what distributions expect: root-owned 0755/0644 modes, no
maintainer scripts or conffiles, copyright with the NOTICE, changelog,
manual page and completions matching the executable, icons at every
hicolor size, a stripped runtime and
libc6 (>= …)covering every binary. When installed,lintianmust report no errors (SHADOWCODE_REQUIRE_LINTIAN=1makes it mandatory) anddesktop-file-validatemust pass.node --test scripts/test-native-deb.mjscovers these checks. See Distributing ShadowCode.
test-install-appimage.shuses fake AppImages in a temporaryHOME. It covers checksum refusal, broken runtimes,--unverified, rollback after the runtime swap and a changed download. Ifpackaging/llama.cpp/binexists, it also runs the realllama-server. Scenarios 20–24 cover the first-window check: a version that hangs, exits or reports another version is stopped and the AppImage, runtime, launchers and database snapshot are restored without lowering the accepted-release record; the check refuses while ShadowCode holds the profile lock; and--recoverafter an installer killed during the check waits for the started version to close, then restores all of it. Run it as an ordinary user: as root, permission-based failure injection (scenario 5) cannot fail. The realVACUUM INTOsnapshot and the first-start marker are covered bycargo test -p shadowcode-core --lib -- install_snapshot first_start.
The v0.33.0 attempt at 9e385cb failed before signing/publication in
run 36414378697.
Do not move or overwrite that tag. The v0.34.0 attempt at 3409d59 likewise
stopped in the native-source gate (run 36499751141)
because two new opt-in network tests were not on the optional-test list, and
the v0.34.1 attempt at 206fd03 stopped in native-window (run 36507326107)
because the window test expected a ready model on the clean CI host; nothing
was signed and both tags stay unchanged. Version 0.33.1 was published from
e15c4480e65db5650af012bb2a9773dbe89acf84, with all 15 required build gates and
protected signing passing in run 36427024374.
The workflow publication job failed on a transient draft-listing response;
publication resumed locally with the same frozen publisher and signed artifact, verifying
all seven remote asset files before publication. This does not make that workflow
run green. Existing 0.33.0 receipts do not qualify the new package bytes.
The first-authenticated install boundary remains 0.33.0; do not silently move
this durable boundary.
The release workflow also runs every required gate on aarch64 (build-aarch64,
on ubuntu-24.04-arm) and hands off its packages and receipts unsigned, exactly
like x86_64 (unsigned-release-aarch64-RUN-ATTEMPT). The trust policy trusts
both targets (target=x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu).
sign waits for both builds and signs each target separately with the same
key: node scripts/sign-native-release.mjs BUNDLE TRUST OUTPUT [TARGET], where
the aarch64 bundle's receipts are checked against the aarch64 gate scripts (the
package names in three gates differ by architecture) and its metadata is
written as RELEASE-AUTH-aarch64, RELEASE-AUTH-aarch64.sig,
RELEASE-MANIFEST-aarch64.json and SHA256SUMS-aarch64. publish takes the
x86_64 bundle and then the aarch64 bundle, authenticates each for its own
target and stages all fourteen assets in one draft before publishing; the
x86_64 bundle is required and no asset name may repeat. apt-repository
verifies and indexes both .deb files. The pinned tooling commit must include
this multi-target signer and publisher; an older pin refuses the aarch64
signing call, so the release fails rather than shipping x86_64 alone.
The tagged 2.4.1 public trust allows the x86_64 and aarch64 targets, epoch 1
and versions 0.33.0–2.4.1. The immutable 2.4.0 policy retains its 2.4.0 ceiling.
The key, epoch, targets and historical floor are unchanged. release/install-policy retains the
first authenticated version 0.33.0. This source change alone does not update
GitHub's independently pinned tooling or signing environment.
The release-signing environment requires review by ShadowfetchStudio
(User ID 209457103), with self-review allowed. Preserve those protections.
NATIVE_RELEASE_SIGNING_ENVIRONMENT points to that environment. After candidate
qualification, add the exact release tag to its deployment policy and set
NATIVE_RELEASE_TOOLING_COMMIT to the independently reviewed immutable release
commit. Read back both settings. A permitted tag is not proof of publication.
Before tagging, finish review and push the tooling commit, then set
NATIVE_RELEASE_TOOLING_COMMIT to that exact 40-character SHA. Read back this pin from GitHub configuration before dispatching the release. Verify the environment protections and source/candidate
receipts before approving signing. Neither the public key nor configured secret
proves that a package has been built, signed or published. See the
authentication contract for bootstrap and custody.
git tag -a vVERSION -m "ShadowCode VERSION"
git push origin vVERSIONrelease.yml then:
- Checks the tag against the version files.
- Builds and tests the UI.
- Runs Rust fmt, clippy and tests.
- Exercises the CLI, stress suite, TUI, both MCP transports and the real WebKit window.
- Builds the llama.cpp runtime, then both packages, and inspects them.
- Rebuilds the AppImage runtime sources without network access.
- Runs the packaged CLI, TUI, window and MCP checks.
- Writes
SHA256SUMSand runs the installer test. - Prepares an unsigned handoff with required receipts. After protected review, a fresh runner verifies that immutable handoff using pinned tooling and signs private snapshots; the build job never receives the key.
- A separate publisher verifies and stages seven assets per target (fourteen for this two-target Linux release), compares every remote asset's bytes, then publishes. The x86_64 names are:
ShadowCode_VERSION_amd64.AppImageShadowCode_VERSION_amd64.debShadowCode_VERSION_appimage-runtime-sources.tar.gzSHA256SUMSRELEASE-MANIFEST.jsonRELEASE-AUTHRELEASE-AUTH.sig
Identical published retries are read-only; changed bytes under an existing version are refused. Do not overwrite published versioned assets.
Don't announce a tag until this job succeeds. Afterwards, compare the uploaded checksums and the release text with what you expect.
The historical 2.4.0 checkpoint above verified
InRelease
and the detached Release.gpg against the independently tracked public key in
release/trust/APT-SIGNING-KEY. The downloaded
binary and armored public keys both matched fingerprint
1BC07B5ECFDB514673A296FB021CAB3F2F7A1F61. Signed index sizes and hashes matched,
Packages.gz decompressed to Packages, and both DEBs' control fields identified
shadow-code 2.4.0 with the correct architecture. Verification installed no package.
After publish, the apt-repository job re-verifies the .deb with
verify-native-release.sh against release/trust, rebuilds the repository
with scripts/build-apt-repo.mjs (keeping every package already in the
gh-pages pool; changed bytes under an existing file name are refused), checks
InRelease with gpgv and pushes apt/ to gh-pages. Pages must be set to
deploy from that branch.
It needs, in the protected signing environment:
secrets.NATIVE_APT_SIGNING_KEY: the ASCII-armored OpenPGP secret key (gpg --armor --export-secret-keys FPR), without a passphrase. Generate it offline; never commit it or a copy of it.vars.NATIVE_APT_SIGNING_FINGERPRINT: its 40-digit uppercase primary fingerprint. The builder refuses a secret holding any other key.
Record the public fingerprint in release/trust/APT-SIGNING-KEY through a
reviewed commit before the first repository publication, so users can check
the keyring they download. Rotating the key is a reviewed change to that file
and the two settings; announce it, since every installed source must import
the new keyring.
Check afterwards:
node --test scripts/test-build-apt-repo.mjs # locally, before tagging
curl -fsSL https://shadowfetchstudio.github.io/ShadowCode/apt/dists/stable/InRelease | gpgv --keyring ./shadowcode-archive-keyring.gpgUse the complete independently authenticated installer bundle, including its
release/trust, install policy, verifier helpers, icon and desktop entry. Keep
the downloaded AppImage beside SHA256SUMS, RELEASE-MANIFEST.json,
RELEASE-AUTH and RELEASE-AUTH.sig.
bash /path/to/trusted-bundle/scripts/install-appimage.sh /path/to/downloads/ShadowCode_2.4.1_amd64.AppImageThe installer accepts a single AppImage path or --recover; it does not accept
--bundle-dir, --trust-dir or --expect-version. Those belong to the separate
read-only verifier. No checksum-only or --unverified bypass is supported.
For manual Debian verification/install, see the README.
With a display, the installer starts the new version itself and waits for its first window (see the README); a failed first start rolls back the AppImage, runtime and database snapshot. Then use the ShadowCode it opened, or open it from the desktop entry, and check:
- Settings, conversations and accounts are still there.
- Settings › Local models › Runtime shows the pinned commit and the
vulkan+cpubackend. - A local model loads.