CLI and desktop release boundaries
July 20, 2026 · View on GitHub
The command-line client and desktop app share a repository but not a release. CLI source and tests must not enter desktop packaging, updater metadata, signing or notarization, version synchronization, or the desktop release asset contract.
Change classification
The changed-path detector reports explicit cli, desktop, relay, and
shared domains. A CLI-only path selects the CLI job without selecting desktop
build or packaging paths. A shared protocol, MLS, contract, or future shared
crate path selects both client suites. Relay paths remain independently visible.
The detector also reports protected_release and lists matching paths in the
GitHub Actions job summary. Protected paths include the desktop release workflow,
desktop npm and Cargo release manifests and locks, Tauri updater/signing inputs,
release tooling, version synchronization, and the desktop asset contract. A
reported protected path requires explicit release-maintainer review;
classification does not grant permission to change it.
CLI checks
CLI-selected changes run tools/ci/run-cli-checks.mjs. The check proves that no
npm CLI workspace or CLI reference has entered the desktop release workflow,
asset contract, or version tools. It requires the standalone Rust workspace's
independent lockfile and runs formatting, Clippy, packaging policy, and tests
with that workspace manifest.
Desktop release verification remains the existing npm run verify and release
tool test suite. CLI CI does not call desktop packaging, signing, notarization,
updater publication, version synchronization, or release-asset creation.
CLI package boundary
CLI archives are configured and built only by apps/cli/release. They use the
CLI Cargo version, the multAIplayer-cli-v<version>-darwin-arm64 artifact
namespace, an independent checksum manifest, and source-revision metadata. The
archive contains an app-like multAIplayer.app; it does not reuse or modify the
desktop application bundle.
The public CLI identity is fixed to bundle com.multaiplayer.cli, Apple team
AXP55K75AX, and the sole Data Protection Keychain access group
AXP55K75AX.com.multaiplayer.cli. Distribution packaging requires an explicit,
unexpired Developer ID provisioning profile binding that exact application ID.
Apple emits the profile's sole Keychain authorization as the team-scoped
AXP55K75AX.*; the signed app is independently required to request only the
narrower CLI group above. Packaging embeds the profile, enables hardened
runtime, signs the app bundle with the reviewed entitlements, and verifies the
resulting signature, entitlements, and profile. The exact observed leaf
certificate fingerprint—not its potentially duplicated common name—must appear
once in the profile's DeveloperCertificates allowlist. This stable signed
application boundary prevents interactive Keychain ACL prompts in the installed
release.
The local default remains a timestamp-free ad-hoc inspection mode, but carries neither the distribution profile nor protected credential entitlements. It cannot access the public CLI credential group. Manifest metadata and independent verification keep inspection and distribution modes fail-closed and distinct.
The CLI packager requires a clean exact source commit and cannot tag, upload,
publish, notarize, update a channel, or write desktop release metadata.
Publication is a separate, explicit release-maintainer operation.
The installer separately verifies the archive checksum, app bundle identity,
Developer ID metadata, signed entitlements, embedded profile, and Apple's
notarization result. It installs a versioned bundle in the user's local data
directory and creates ~/.local/bin/multAIplayer; it never requires sudo by
default.