Export the reviewed allowlisted snapshot from private source commit 07c1655921f21ee5e4fc4d85639d199e8867b17d. This records the Docker Compose activation, schema-compatible rollback, and stateful migration resource findings from Observatory Preview 19 dogfooding. AI-Assisted: OpenAI Codex Signed-off-by: Cole Speelman <crspeelman@gmail.com>
4.8 KiB
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; andSHA256SUMS.
The external archive digest is the release identity used by deployment.
Transport boundary
tend push sends one bounded protocol frame to a dedicated account through a
pinned OpenSSH host key. It uses an argument vector, disables config files,
forwarding, PTYs, local commands, and proxy commands, and requests exactly
tend-receive-v1. The account's forced command invokes only the root-owned
receiver. The receiver's root-owned policy maps an allowlisted service name to
one exact configuration path and size ceiling.
The target receives no source, repository credential, Go cache, dependency, or arbitrary command. The artifact digest must equal both the produced digest and the separately supplied approved digest before it is staged.
Target-host boundary
Schema-2 configurations live below /etc/tend/services/. Secrets live only in
separate /etc/tend/environment/*.env files that are root-owned, non-symlink,
and mode 0600. Configurations contain the path, never the values. Candidate
and installed units read the same file; Tend overrides only the candidate's
loopback listen address.
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 target release in a hardened transient systemd unit on a separate loopback address and probes it. The unit is named from the service and a fresh bounded operation ID; a separate strict candidate-lease file binds that unit to the candidate release, address, and start time without changing the schema-1 deployment-state contract used by retained recovery binaries. Tend then validates and atomically routes the imported Caddy handler to that candidate. While the candidate serves the canonical origin, Tend changes the current release pointer, restarts and probes the installed fixed-address unit, validates Caddy again, and routes back to it. The candidate remains healthy through the activation window and stops only after the handoff succeeds.
After the local post-activation probes, Tend also checks configured HTTPS public origins throughout a bounded activation window. Blue/green mode also probes the previous slot, and singleton mode probes the handoff candidate, for health and readiness throughout that window. Any failure before success is recorded restores the previously observed Caddy bytes and/or release pointers. State records desired, candidate, active, previous, and last-attempt release identities, including failed attempts without claiming they became active. Rollback is a separate explicit command over the recorded state. It rechecks local health/readiness and public reachability, but deliberately does not apply a future release's content marker to an older release whose routes may differ. Pruning preserves both active and previous releases.
tend reconcile is a read-only observation boundary. It compares persisted
state, systemd activity, current/previous release pointers, and exact handler
file bytes. It does not claim to inspect Caddy's currently loaded in-memory
configuration, and it never clears or stops a candidate. The report makes
retained, inactive, ambiguous, and settled states legible before a future
explicit recovery operation is approved.
Evidence boundary
Every attempted activation and explicit rollback emits bounded, versioned JSONL events with an operation ID, service, approved artifact digest, source commit, release version, phase, slot, elapsed duration, and outcome. Values are validated rather than copied from command output. The log contains no environment values, arbitrary process output, HTTP bodies, or secret paths. Release-identity, event-file, and downstream observability failures are deliberately best effort and cannot control Tend's deployment or rollback result. A fresh operation identity is operationally required for a singleton candidate unit; entropy failure therefore stops either forward activation or rollback before a candidate process or traffic change.