docs(skill): align release-ready host guidance

This commit is contained in:
tmk241
2026-08-13 14:36:48 +02:00
parent 2e1debaba0
commit 3619cb6336
+40 -21
View File
@@ -46,11 +46,15 @@ in the same change when applicable requirements or CLI behavior change.
profiles contain only host configuration and service scripts. The daemon never profiles contain only host configuration and service scripts. The daemon never
detects a distribution, libc, or init system. Before opening its listener it detects a distribution, libc, or init system. Before opening its listener it
must prove its unprivileged effective UID and create/remove a child beneath a must prove its unprivileged effective UID and create/remove a child beneath a
writable delegated cgroup v2 path exposing `cpu`, `memory`, and `pids`. writable delegated cgroup v2 parent exposing `cpu`, `memory`, and `pids` while
the daemon itself remains in a leaf cgroup. On systemd profiles this requires
`Delegate=yes` plus `ProtectControlGroups=private`; Apsuflow then moves itself
into `/daemon` before proving or creating workload children.
`doctor` reports the same kernel-observed parent-process and cgroup facts. `doctor` reports the same kernel-observed parent-process and cgroup facts.
Failure is closed: there is no root or service-manager-specific fallback. The Failure is closed: there is no root or service-manager-specific fallback.
current runit profile also passed its complete acceptance path on Void Linux Both release-supported profiles have complete acceptance proof, including the
musl; that is evidence for the capability contract, not a distro special case. Void-musl/runit PID-1 path in a local KVM/QEMU VM with a real OCI workload,
restart, limits, and encrypted backup/restore.
- `.apsu` contains desired workloads and infrastructure, never secret values or - `.apsu` contains desired workloads and infrastructure, never secret values or
mutable runtime state. mutable runtime state.
- Services are continuously reconciled. Jobs are finite run-to-completion work. - Services are continuously reconciled. Jobs are finite run-to-completion work.
@@ -76,15 +80,22 @@ that drift before making another change.
## Install and update ## Install and update
Use only the exact stable tag and artifact named by `docs/getting-started.md`. Use only the exact stable tag and artifact named by `docs/getting-started.md`.
Verify `SHA256SUMS` and its SSH signature before installing; never use a mutable Official bootstrap and Cloud-Init entry points require that exact version,
`latest` URL. Keep the previous executable and state backup until the new one verify `SHA256SUMS` with the repository-pinned SSH release identity, verify the
selected archive hash, replace atomically, and retain `apsuflow.previous`; never
use a mutable `latest` URL. Keep the previous executable and state backup until the new one
passes `version`, `doctor`, workload diagnosis, and each operator-facing route. passes `version`, `doctor`, workload diagnosis, and each operator-facing route.
For a private image registry, pipe the credential into `apsuflow registry login For a private image registry, pipe the exact registry credential in its
<host> --username <user> --password-stdin`; do not put it in `.apsu` or shell `username:password` form into `apsuflow registry login <host> --password-stdin`;
history. Login stores sealed `_registry/{host}` state, and joined agents receive the command has no separate username flag. Do not put the credential in `.apsu`,
only their per-node-resealed pull credential during assignment. Confirm the next process arguments, shell history, a runtime auth file, or host-side container-tool
pull succeeds; `unauthorized` means the registry host or credential is wrong, not configuration. Login stores sealed `_registry/{host}` state, and joined agents
that the workload should be stopped first. receive only their per-node-resealed pull credential during assignment. Establish
and verify this login before the first apply, then confirm the digest-pinned pull
and workload health through Apsuflow. If a known-good credential still yields
`unauthorized`, stop: that is an Apsuflow credential-delivery defect, not permission
to use `skopeo login`, copy an OCI archive, invoke the runtime, or otherwise bypass
the control plane.
For host-network workloads, confirm the old container released its host ports and For host-network workloads, confirm the old container released its host ports and
the successor is the sole running generation; repeated replacement failures are the successor is the sole running generation; repeated replacement failures are
@@ -112,10 +123,12 @@ host paths—also require `apply --acknowledge-recovery-risk`; read the reported
source location and consequence before accepting it. Verify the actual route or source location and consequence before accepting it. Verify the actual route or
job result; a successful apply alone proves only admission. job result; a successful apply alone proves only admission.
The daemon normally needs root for host effects. Do not therefore run every The server daemon runs unprivileged in its delegated cgroup; the agent remains
client command with `sudo`: protect the daemon data directory and use an operator rootful only for its authorized runtime and host-network effects. Do not run
context or token. Never make bootstrap tokens or the data directory broadly client commands with `sudo`: protect daemon state and use an operator context or
readable. `server --no-auth` is acceptable only for disposable loopback use. token. Join credentials are node-bound, role-bound, single-use, and expire after
15 minutes; never reuse, commit, or broaden them. `server --no-auth` is
acceptable only for disposable loopback use.
## Multiple environments ## Multiple environments
@@ -188,11 +201,13 @@ job backup {
## Cluster and network ## Cluster and network
Start the first server on a stable address. Create a short-lived role-scoped join Start the first server on a stable address. Create a 15-minute, single-use join
token with `apsuflow token create --name NODE --role server`, then start another credential bound to the exact node ID with `apsuflow token create --name NODE
server with `apsuflow server --peer FIRST:7946 --token TOKEN`. For an agent, --role server`, then start that server with `apsuflow server --peer FIRST:7946
create an `agent` token and run `apsuflow agent --join FIRST:7654 --token TOKEN`. --token TOKEN`. For an agent, mint the same node-bound credential with `--role
Never reuse or commit a bootstrap token. agent` and run `apsuflow agent --node-id NODE --join FIRST:7654 --token TOKEN`.
The `--node-id` value must exactly match the credential name. Never reuse or
commit a join credential.
Allow between nodes only required control-plane traffic: Allow between nodes only required control-plane traffic:
@@ -241,6 +256,10 @@ apsuflow status --context recovery
This backs up Apsuflow control-plane state, not bind-mounted application data, This backs up Apsuflow control-plane state, not bind-mounted application data,
databases, object stores, or brokers. Back those up natively and test both paths. databases, object stores, or brokers. Back those up natively and test both paths.
Restore replaces authentication state and removes the empty target's bootstrap
token because it cannot match restored credential hashes. Retain an original
administrator credential outside the lost server data directory; without one,
recovery is blocked rather than silently granting new access.
Never mutate `store.db`, WAL files, generations, assignments, certificates, or Never mutate `store.db`, WAL files, generations, assignments, certificates, or
sealed values with SQLite/SQL. Never invoke crun/youki or host-network tools to sealed values with SQLite/SQL. Never invoke crun/youki or host-network tools to