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
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
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.
Failure is closed: there is no root or service-manager-specific fallback. The
current runit profile also passed its complete acceptance path on Void Linux
musl; that is evidence for the capability contract, not a distro special case.
Failure is closed: there is no root or service-manager-specific fallback.
Both release-supported profiles have complete acceptance proof, including the
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
mutable runtime state.
- Services are continuously reconciled. Jobs are finite run-to-completion work.
@@ -76,15 +80,22 @@ that drift before making another change.
## Install and update
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
`latest` URL. Keep the previous executable and state backup until the new one
Official bootstrap and Cloud-Init entry points require that exact version,
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.
For a private image registry, pipe the credential into `apsuflow registry login
<host> --username <user> --password-stdin`; do not put it in `.apsu` or shell
history. Login stores sealed `_registry/{host}` state, and joined agents receive
only their per-node-resealed pull credential during assignment. Confirm the next
pull succeeds; `unauthorized` means the registry host or credential is wrong, not
that the workload should be stopped first.
For a private image registry, pipe the exact registry credential in its
`username:password` form into `apsuflow registry login <host> --password-stdin`;
the command has no separate username flag. Do not put the credential in `.apsu`,
process arguments, shell history, a runtime auth file, or host-side container-tool
configuration. Login stores sealed `_registry/{host}` state, and joined agents
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
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
job result; a successful apply alone proves only admission.
The daemon normally needs root for host effects. Do not therefore run every
client command with `sudo`: protect the daemon data directory and use an operator
context or token. Never make bootstrap tokens or the data directory broadly
readable. `server --no-auth` is acceptable only for disposable loopback use.
The server daemon runs unprivileged in its delegated cgroup; the agent remains
rootful only for its authorized runtime and host-network effects. Do not run
client commands with `sudo`: protect daemon state and use an operator context or
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
@@ -188,11 +201,13 @@ job backup {
## Cluster and network
Start the first server on a stable address. Create a short-lived role-scoped join
token with `apsuflow token create --name NODE --role server`, then start another
server with `apsuflow server --peer FIRST:7946 --token TOKEN`. For an agent,
create an `agent` token and run `apsuflow agent --join FIRST:7654 --token TOKEN`.
Never reuse or commit a bootstrap token.
Start the first server on a stable address. Create a 15-minute, single-use join
credential bound to the exact node ID with `apsuflow token create --name NODE
--role server`, then start that server with `apsuflow server --peer FIRST:7946
--token TOKEN`. For an agent, mint the same node-bound credential with `--role
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:
@@ -241,6 +256,10 @@ apsuflow status --context recovery
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.
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
sealed values with SQLite/SQL. Never invoke crun/youki or host-network tools to