Skip to content

Latest commit

 

History

History
312 lines (261 loc) · 16.1 KB

RELEASING.md

File metadata and controls

312 lines (261 loc) · 16.1 KB

Publish a Ukai Jail developer preview

Linux preview 0.1.0-rc.5, which carries the fixes of the 22–23 October review, was published on 23 October 2026 from 0fe655440db7fd0012257cbbbc7d7a790cd7eca1; its publication record lists the exact-commit checks, the clean-VM evidence and the verified installations.

Linux preview 0.1.0-rc.3, the first release under the Ukai name, was published on 18 October 2026 from f95f2d3963bc8829ab08f8b320d43abbb9f220f8; its publication record lists the exact-commit checks, the refreshed clean-VM evidence (now with a vaulted provider key, since OpenCode's free tier refuses its CLI) and the verified installations.

Linux preview 0.1.0-rc.2, published before the Ukai rename on 15 October 2026, was released on 14 October 2026 from 531d252a6c56e0403ae7b1937988f2037e294853, following the procedure below; its publication record lists the exact-commit checks, the clean-VM evidence and the verified installations.

Linux preview 0.1.0-rc.1 was published on 10 October 2026 from 06a48d5a2de89d5d0ebffa84a9561d034cdd8b5d. All eight signed assets were downloaded anonymously and matched the reviewed candidate. The acceptance and public-install record retains CI, native host checks and a fresh VM installation without Rust.

The first distribution is ukai-jail for Linux x86_64 and ARM64 in monocursive/ukai. Tags use ukai-jail-vVERSION; the previews published before the rename used ouro-jail-vVERSION, starting with ouro-jail-v0.1.0-rc.1. This keeps the archived runtime's v0.1.x releases separate. The fleet, ledger, Homebrew and macOS execution are outside this package.

The separate macOS Linux VM preview has its own offline DMG and Bash installer. It does not add Darwin artifacts to the Linux release or satisfy the native macOS clauses. Its package qualification records signing, notarization, installation and VM fault checks separately. The dedicated prerelease is ouro-vm-v0.1.0-preview.1. The public installer selects it on Apple Silicon and pins the final stapled DMG's SHA-256 in its managed pin block, rendered with render_vm_pin in bootstrap.py. Use the Mac quickstart for installation and limits. The DMG's build-time notes and original qualification metadata retain their unpublished state; publication does not modify the tested artifact. The publication record adds verified public installation, live website delivery and quickstart proof.

The Bash entry point adapts legacy:install.sh: explicit versions, HTTPS, architecture detection, no sudo or compiler, and installation to ~/.local/bin. It embeds the SHA-256 hash for each Linux archive, verifies the selected archive before extracting or executing it, and installs it directly. Users need Bash, curl, tar, and sha256sum or shasum; Minisign is not an installation dependency. A downgrade requires --allow-downgrade.

Never direct Jail users to releases/latest/download/install.sh: that installs the archived runtime. The current public preview command is:

curl --proto '=https' --tlsv1.2 -fsSL \
  https://ukai.sh/install.sh | bash

The HTTPS-served script is the trust anchor for the embedded hashes. A mirror or a downloaded checksum manifest cannot replace those pins. --from-dir DIR also checks the same pinned archive offline. --version and --bin-dir are accepted through bash -s -- ...; versions without embedded pins refuse before any download.

To publish a new installer, assemble the reviewed native archives below. Assembly sets the default release and embeds both archive hashes in bootstrap.sh, while retaining previously pinned releases, the macOS preview's included. After publication, copy that reviewed bootstrap to the root install.sh, set the new version in release.json (the website, the VM tooling and the tests read the coordinates there), set that platform's published_tag to the actual published tag, update the docs, and deploy the website, which serves the root install.sh and release.pub directly. Verify the website script's bytes and an actual public installation. Never discover a trusted hash from a mutable remote manifest at install time.

The original immutable RC1 GitHub bootstrap.sh and low-level install.sh remain signed historical assets and still require Minisign. The live website and current repository installer provide the dependency-free SHA-256 path. The release binaries and their tag are unchanged.

Maintainer candidate signing and publication checks still use the dedicated release public key, created on 10 October 2026. Users of the current installer do not need this key. Its private half retains its pre-rename location outside the repository at ~/.config/ouroboros/release-keys/ouro-jail-2026-10-10.key, in a mode-0700 directory with file mode 0600. It is unencrypted for local noninteractive signing; maintain a private backup for future releases. Private key material is never sent to CI.

Linux-only Jail release scope

On 10 October 2026, the Linux evidence gaps were closed by live CLI tests, native signed-install tests and a recorded fresh-VM OpenCode workflow. The acceptance record gives each clause's disposition and raw evidence. Future releases require the exact-commit validation and publication steps below.

Use cargo xtask gates --linux-release and cargo xtask conformance --linux-release for this developer preview. This fixed scope reports the explicit jail.unsupported_clauses in release.json as unsupported: K22.2, K23.1, K24.1, K26.1, K29.1, L02.12, M01.4 and each .1 clause from K87.1 through K113.1, individually listed in that file. These are the untested native or proposed Mac VM acceptance claims; no prefix exemption is used. Tested component clauses remain required. The full verdict without the flag continues to fail those untested clauses. Every Linux clause, shared test and macOS execution-refusal test remains required; no failing Linux test is waived. The signed release plan binds this scope and both native Linux targets.

macOS Jail bundle (pending entitlement — NOT yet releasable)

The Linux-only scope above has a macOS counterpart defined by jail-macos.md §4.12 and §8. J16–J18 are work in progress on dev, not supported or releasable. The new custody implementation has not run with live Endpoint Security; decision 5's measurement spike has not run. J16 still needs its bundle, Info.plist, entitlements and ~/Applications installer. J18 still lacks network, the agent profile, a workspace share and in-guest credentials. Apple's Endpoint Security grant (request S9YJTLLH28, submitted 2026-09-29) is necessary, but does not by itself make the release run ready. The procedure below is a release requirement, not an implemented packaging workflow.

Current implementation: native execution is off by default. Setting UKAI_JAIL_MACOS_NATIVE=dev enables development only; a native receipt records native_execution=dev. Native credential, vault and vendor staging answer unsupported and refuse. J17_OBSERVE=false: ObserveRun exists but is unwired; fs.write would still be degraded/partial even if wired. Every run --vm refuses before connecting: no qualified VM backend exists yet. The released VM preview remains the only Mac deliverable.

After implementation, packaging and the measurement spike are complete and the entitlement is granted, prepare a Mac release bundle as follows:

  1. One entitled executable. The supervisor and the guardian are both ukai-jail inside Ukai.app/Contents/MacOS/ukai-jail, carrying com.apple.developer.endpoint-security.client, authorised by the bundle's embedded provisioning profile.
  2. Bundle identifier com.monocursive.ouroboros.jail — the identifier request S9YJTLLH28 names. It predates the rename; it stays rather than reopening the request.
  3. Signing requirements. Developer ID, hardened runtime and notarization; macOS 27 or later (es_new_descendants_client, by reading). No root, no TCC approval and no Full Disk Access.
  4. Install shape. The installer places the bundle in ~/Applications without sudo and links ukai-jail onto the PATH.
  5. Protected-Mac release run. Before publishing, repeat every J16 row (jail-macos.md §9.1, including K23–K26) on a normally protected Mac with SIP enabled and the approved provisioning profile, on the release build (K104). A SIP-disabled development VM run does not satisfy this.

The existing live-ES evidence comes from historical prototypes in a SIP-disabled development VM, not this implementation. That VM was deleted on 2026-10-22 and must be re-cloned using macos-development.md for further development measurements; release evidence requires the protected Mac.

Prepare and validate

Commit and review the release tree. Require rust, contracts and the actual conformance reference-host job to pass on that exact commit. Conformance runs the suite with UKAI_RELEASE_EVIDENCE=1, so the recorded clean-VM and real-vendor evidence (K11, K27) must match this build's inputs; a source change since the recorded VM run needs a new one first (onboarding_vm.py). A plain cargo test skips those two checks. The reference host needs at least 4 GiB free for a release build. Record successful conformance with cargo xtask freeze --doctor, then require cargo +1.98.1 run -q -p xtask -- freeze --check to pass. A tree-only freeze, skipped reference host or an older passing run is insufficient. The next release needs a fresh reference conformance rerun on the VPS, followed by cargo xtask freeze --doctor <successful-run>/doctor.json. The current milestone-1-freeze.toml has no [tested] record: regenerating a tree-only freeze intentionally removes it and cannot establish release readiness.

Set the reviewed coordinates and production key:

release_version=0.1.0-rc.5
release_revision=$(git rev-parse HEAD)
release_public_key=$(sed -n '2p' crates/ukai-jail/dist/release.pub)
release_private_key="$HOME/.config/ouroboros/release-keys/ouro-jail-2026-10-10.key"

Build the same clean checkout or Git archive on both native Linux hosts with Rust 1.98.1. A Git archive avoids macOS ._ metadata entering release inputs:

UKAI_BUILD_REVISION="$release_revision" UKAI_BUILD_DIRTY=false \
  cargo +1.98.1 build --locked --release -p ukai-jail
target/release/ukai-jail version --json
python3 crates/ukai-jail/dist/test_install.py target/release/ukai-jail

Set release_inputs from build.inputs in the version output. Stage each binary on its native host; staging executes version --json and checks architecture, revision, optimization, toolchain and source inputs:

python3 crates/ukai-jail/dist/prepare_release.py stage \
  --binary target/release/ukai-jail --target x86_64-unknown-linux-gnu \
  --revision "$release_revision" --inputs "$release_inputs" \
  --version "$release_version" --out /private/stage-x86

Use aarch64-unknown-linux-gnu and /private/stage-arm on ARM64. Both records must name the same inputs and revision. Retain native doctor, contained-command, receipt and installation evidence. Host limits remain in the release notes; installation alone does not establish enforcement support.

Alternatively, run the release-candidate Actions workflow on the chosen commit, or push its tag. Native Ubuntu x86_64 and ARM64 jobs exercise installation using temporary keys, stage both packages, and upload an unsigned candidate. Download the native stages for local signing:

gh run download RUN_ID --repo monocursive/ukai \
  --name native-x86_64-unknown-linux-gnu --dir /private/stage-x86
gh run download RUN_ID --repo monocursive/ukai \
  --name native-aarch64-unknown-linux-gnu --dir /private/stage-arm

Sign and inspect

Assembly uses a fresh directory and signs both archives, the low-level installer, the pinned Bash bootstrap, release notes and provenance plan:

python3 crates/ukai-jail/dist/prepare_release.py assemble \
  --stage /private/stage-x86 --stage /private/stage-arm \
  --revision "$release_revision" --inputs "$release_inputs" \
  --version "$release_version" --out /private/release-candidate \
  --signing-key "$release_private_key" --public-key "$release_public_key"
python3 crates/ukai-jail/dist/publish_release.py check \
  --candidate /private/release-candidate --public-key "$release_public_key"

Review the plan, support notes and validation evidence. Native records are builder attestations; signatures do not replace conformance. Test the SHA-256-pinned bootstrap on both native hosts without Minisign available to the user:

bash /private/release-candidate/bootstrap.sh \
  --from-dir /private/release-candidate --bin-dir "$HOME/.local/bin"
ukai-jail version --json
ukai-jail doctor --profile tool --json

Run the user guide's first command, inspect its settled receipt and preserve unavailable capabilities.

Draft and publish

Once source, candidate and validation agree, push the exact tag and create a draft:

git tag -a "ukai-jail-v$release_version" "$release_revision" \
  -m "Ukai Jail $release_version developer preview"
git push origin "ukai-jail-v$release_version"
python3 crates/ukai-jail/dist/publish_release.py draft \
  --candidate /private/release-candidate --public-key "$release_public_key"

The helper requires a clean tree at the candidate commit, tested freeze, successful exact-commit CI, live reference conformance and the correct remote tag. It creates a prerelease draft with exactly eight assets, downloads every draft asset and verifies its bytes. It never overwrites an existing release. Smoke-test installation from those downloaded draft assets on both native hosts.

After reviewing that concrete draft and its evidence:

python3 crates/ukai-jail/dist/publish_release.py publish \
  --candidate /private/release-candidate --public-key "$release_public_key"

This rechecks the gates and draft bytes, publishes with --latest=false, then downloads all public assets without authentication and verifies their digests. If public verification fails after GitHub accepts publication, the release may already be public. Inspect it and rerun verify; do not assume rollback:

python3 crates/ukai-jail/dist/publish_release.py verify \
  --candidate /private/release-candidate --public-key "$release_public_key"

Verify the public installer and first command on a clean supported Linux host. Then update the README, guide and website with the real release link, trusted archive hashes and host requirements. GitHub's release procedure documents draft and prerelease behavior.

Local checks

shellcheck install.sh crates/ukai-jail/dist/install.sh
python3 -m unittest discover -s crates/ukai-jail/dist -p test_bootstrap.py
python3 -m unittest discover -s crates/ukai-jail/dist -p test_publish.py
python3 -m unittest discover -s crates/ukai-jail/dist -p test_release.py
python3 -m unittest discover -s crates/ukai-jail/dist -p test_versions.py
python3 crates/ukai-jail/dist/test_install.py target/release/ukai-jail

Bootstrap tests use pinned fixture archives and local download adapters, with Minisign calls forced to fail. Maintainer tests use temporary signing keys. They cover installation, upgrade/downgrade, truncated pipes, tampering, signed provenance and publication gates; they do not establish public availability.