Daemon attachment and local startup #
Albedo's API connection and its local process launcher have separate jobs. A client can attach to a supplied endpoint without reading local installation files, starting a process, or replacing one.
Before #
The CLI's connection helper read daemon.json, checked health, compared the
running build with the bundled executable, and could start or replace the daemon.
Many discovery failures looked like absence. The launcher also supplied the
token and VM defaults, so starting the daemon independently behaved differently.
After #
Discoverreads the local record and probes its authenticated health endpoint. It reports absence, a proven stale record, or a running daemon. Invalid records, authentication failures, unreachable endpoints, and unhealthy daemons return actionable errors. A failed health check does not authorize another launch.Attachvalidates the protocol and required capabilities, then returns an API connection. Build identity is update information. A different build with the required API remains usable.- The ordinary interactive CLI offers to restart a running daemon once per invocation. Keeping it is the default. The prompt warns that restarting interrupts active work across sessions. Scripts keep a compatible daemon and report incompatibility instead of replacing it.
Launchstarts a local daemon only under the application's policy. Concurrent launchers coordinate through a persistent advisorylauncher.lock; the daemon's storage lock remains the authority for home ownership.Upgraderequires the exact snapshot approved by the caller. It validates the replacement executable before stopping anything, rechecks the approved target, drains the supported daemon, and launches its replacement. If the target changed, the caller must obtain fresh approval. Unknown protocols cannot authorize shutdown.
albedo daemon --stop inspects the existing daemon without prompting or starting
one. An absent or stale daemon needs no shutdown. Discovery failures are reported.
Authentication and defaults #
Bearer authentication remains the same. The daemon owns its home directory and
token: by default it uses ~/.albedo and generates a random token. It publishes
daemon.json atomically with mode 0600 inside the private home directory. The
record contains the endpoint, PID, protocol, token, and optional build identity.
It is a local discovery file, not an API compatibility contract.
The shared priv/bin/albedo-daemon bootstrap installs VM defaults before Erlang
starts. Source, test snapshots, and packaged startup use that bootstrap. Deliberate
ALBEDO_HOME, ALBEDO_TOKEN, ALBEDO_BUILD, and ERL_FLAGS overrides remain
available; operator VM flags follow the defaults and take precedence. The local
launcher filters provider overrides so saved daemon configuration remains the
source of provider settings.
Cancellation ends discovery, lock acquisition, startup waits, shutdown waits, and the restart prompt. It does not kill a detached daemon that has already started. A client disconnect cannot stop a daemon shared by other clients.
Client development #
Use Attach(ctx, snapshot, rediscovery) for a validated API connection. Supply no
rediscovery callback when the endpoint is fixed. A local client can supply
Rediscover, which looks for a verified replacement without launching one.
API recovery uses the supplied callback and validates the new endpoint before
installing it. It does not know the client's home directory or executable.
Attachment currently requires protocol 2 and the operation_receipts,
session_stream_generation, and agents_stream_overflow capabilities. Optional
features check their own capabilities. Authentication, malformed health, and
capability lookup failures propagate to callers.
Implementation ownership and verification #
The API agent owns connection extraction, health validation, explicit recovery, and controlled transport tests. The launcher agent owns local discovery, launch/upgrade coordination, daemon defaults, bootstrap, and packaging. The validation agent owns isolated real-daemon lifecycle scenarios. The lead owns CLI policy, confirmation, integration, documentation, and final review. Shared files have one writer, and daemon builds run serially.
Correctness tests cover independent startup and startup parity, protected records, operator overrides, compatible different builds, attachment failures without process changes, canceled waits, concurrent starters, interactive keep/restart, approval races, and upgrade during active sessions. Transport tests cover health validation and recovery boundaries that the real daemon cannot intentionally violate. No obsolete wire-format readers or compatibility fixtures are retained.
After focused tests, verification runs Go race tests, Gleam checks, Erlang
compilation with warnings treated as errors, Go vet, and ./test.sh. Cross-review
checks ownership boundaries, cancellation and resource cleanup, error handling,
unnecessary forwarding helpers, and tests that only mirror implementation.