okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffaufdocs(stream): define active output ownership and recovery contracts4b61f2e

main
4.5 KiB77 linesraw

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.

Connection flow

  1. Discover reads the local record and probes its authenticated /server resource. 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.
  2. Attach validates the protocol and required capabilities, then returns an API connection. Build identity is update information. A different build with the required API remains usable.
  3. The ordinary interactive CLI offers to restart a running daemon when the candidate build may differ from the running one: the content digests decide when both sides hashed their code trees, the build labels otherwise, and an unprovable comparison keeps the offer. Proven sameness attaches without asking. Keeping the daemon 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.
  4. Launch starts a local daemon only under the application's policy. Concurrent launchers coordinate through a persistent advisory launcher.lock; the daemon's storage lock remains the authority for home ownership.
  5. Upgrade requires 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.

A protocol 2 daemon has no /server resource. When that route returns 404 and daemon.json reports a different protocol, discovery reports incompatibility. It preserves the record and does not authorize attachment, shutdown, or launch. Stop that daemon with its matching client, then launch the protocol 3 client. The current client does not call older API routes.

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: an ALBEDO_BUILD label plus a content digest of the code tree the daemon runs (sha256 over the sorted relative paths and bytes of every regular file under the application's ebin/ and priv/ trees, symlinks followed; the CLI hashes its candidate build with the same recipe, pinned across both implementations by the fixture in test/fixtures/build-digest). 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 requires protocol 3 and the durable_inputs, session_replay, collection_invalidation, and tool_progress capabilities. session_replay requires version 2; the other required capabilities use version 1. Optional features check their own capabilities. Authentication, malformed server responses, and capability lookup failures propagate to callers.

1# Daemon attachment and local startup
2
3Albedo's API connection and its local process launcher have separate jobs. A
4client can attach to a supplied endpoint without reading local installation
5files, starting a process, or replacing one.
6
7## Connection flow
8
91. `Discover` reads the local record and probes its authenticated `/server` resource.
10   It reports absence, a proven stale record, or a running daemon. Invalid records,
11   authentication failures, unreachable endpoints, and unhealthy daemons return
12   actionable errors. A failed health check does not authorize another launch.
132. `Attach` validates the protocol and required capabilities, then returns an API
14   connection. Build identity is update information. A different build with the
15   required API remains usable.
163. The ordinary interactive CLI offers to restart a running daemon when the
17   candidate build may differ from the running one: the content digests decide
18   when both sides hashed their code trees, the build labels otherwise, and an
19   unprovable comparison keeps the offer. Proven sameness attaches without
20   asking. Keeping the daemon is the default. The prompt warns that restarting
21   interrupts active work across sessions. Scripts keep a compatible daemon and
22   report incompatibility instead of replacing it.
234. `Launch` starts a local daemon only under the application's policy. Concurrent
24   launchers coordinate through a persistent advisory `launcher.lock`; the
25   daemon's storage lock remains the authority for home ownership.
265. `Upgrade` requires the exact snapshot approved by the caller. It validates the
27   replacement executable before stopping anything, rechecks the approved target,
28   drains the supported daemon, and launches its replacement. If the target
29   changed, the caller must obtain fresh approval. Unknown protocols cannot
30   authorize shutdown.
31
32`albedo daemon --stop` inspects the existing daemon without prompting or starting
33one. An absent or stale daemon needs no shutdown. Discovery failures are reported.
34
35A protocol 2 daemon has no `/server` resource. When that route returns 404 and
36`daemon.json` reports a different protocol, discovery reports incompatibility.
37It preserves the record and does not authorize attachment, shutdown, or launch.
38Stop that daemon with its matching client, then launch the protocol 3 client.
39The current client does not call older API routes.
40
41## Authentication and defaults
42
43Bearer authentication remains the same. The daemon owns its home directory and
44token: by default it uses `~/.albedo` and generates a random token. It publishes
45`daemon.json` atomically with mode `0600` inside the private home directory. The
46record contains the endpoint, PID, protocol, token, and optional build identity:
47an `ALBEDO_BUILD` label plus a content digest of the code tree the daemon runs
48(sha256 over the sorted relative paths and bytes of every regular file under the
49application's `ebin/` and `priv/` trees, symlinks followed; the CLI hashes its
50candidate build with the same recipe, pinned across both implementations by the
51fixture in `test/fixtures/build-digest`). It is a local discovery file, not an
52API compatibility contract.
53
54The shared `priv/bin/albedo-daemon` bootstrap installs VM defaults before Erlang
55starts. Source, test snapshots, and packaged startup use that bootstrap. Deliberate
56`ALBEDO_HOME`, `ALBEDO_TOKEN`, `ALBEDO_BUILD`, and `ERL_FLAGS` overrides remain
57available; operator VM flags follow the defaults and take precedence. The local
58launcher filters provider overrides so saved daemon configuration remains the
59source of provider settings.
60
61Cancellation ends discovery, lock acquisition, startup waits, shutdown waits,
62and the restart prompt. It does not kill a detached daemon that has already
63started. A client disconnect cannot stop a daemon shared by other clients.
64
65## Client development
66
67Use `Attach(ctx, snapshot, rediscovery)` for a validated API connection. Supply no
68rediscovery callback when the endpoint is fixed. A local client can supply
69`Rediscover`, which looks for a verified replacement without launching one.
70API recovery uses the supplied callback and validates the new endpoint before
71installing it. It does not know the client's home directory or executable.
72
73Attachment requires protocol 3 and the `durable_inputs`, `session_replay`,
74`collection_invalidation`, and `tool_progress` capabilities. `session_replay`
75requires version 2; the other required capabilities use version 1. Optional
76features check their own capabilities. Authentication, malformed server responses, and
77capability lookup failures propagate to callers.