# Architecture Tend has three deliberately separate boundaries. ## Package boundary `tend package` accepts only a clean checkout whose `HEAD` exactly matches the configured pushed branch. It rejects Go module replacements and unversioned dependencies, builds the configured main package twice with `GOWORK=off`, and requires byte-identical output. The resulting archive contains only: - the service binary; - `RELEASE.json`; - `BUILDINFO.json`; - `SBOM.spdx.json`; and - `SHA256SUMS`. The external archive digest is the release identity used by deployment. ## Target-host boundary `tend deploy` runs on the Linux target. Transfer and SSH authentication stay outside Tend v0.1; application-local transfer commands move the artifact and the identical Tend binary to a root-controlled staging directory. Tend then requires the expected digest to be repeated as a separately approved digest. Dry-run validation extracts into a temporary directory and does not touch the release tree. Activation acquires the shared lock, installs a content-addressed release, verifies all embedded checksums and manifest fields, and starts the candidate without evaluating configuration as shell code. ## Activation boundary Blue/green mode points the inactive slot at the new release, restarts and probes it, atomically replaces one imported Caddy handler, validates the full Caddy configuration, reloads Caddy, and records the prior active slot. Singleton mode starts the new release in a hardened transient systemd unit on a separate loopback address, probes it, stops the candidate, changes the current release pointer, and restarts the installed singleton unit. Any failure before state persistence restores the previously observed Caddy bytes and/or release pointers. Rollback is a separate explicit command over the recorded state. It rechecks health and readiness, but deliberately does not apply the current release's content markers to an older release whose routes may differ. Pruning preserves both active and previous releases.