diff --git a/skills/apsuflow/SKILL.md b/skills/apsuflow/SKILL.md index 85f1a1f..b3dcedd 100644 --- a/skills/apsuflow/SKILL.md +++ b/skills/apsuflow/SKILL.md @@ -44,17 +44,14 @@ in the same change when applicable requirements or CLI behavior change. not add quorum votes. - One signed `apsuflow` executable runs on every supported Linux profile; 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 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. - 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. + detects a distribution, libc, or init system. The control-plane server runs as + the locked `apsuflow` user with zero effective Linux capabilities and access + only to its state directory and listener. A separately supervised, + capability-bounded root agent owns OCI, namespace, cgroup, CNI, firewall, + host-path, and host-network effects. Missing agent prerequisites leave + workloads stopped; the server never becomes an execution fallback. Both + release-supported profiles prove a real agent-owned OCI workload, independent + server and agent restart, and encrypted control-plane 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. @@ -87,7 +84,24 @@ must converge after re-apply. ## Install and update -Use only the exact stable tag and artifact named by `docs/getting-started.md`. +For an existing legacy root daemon, use `apsuflow host migrate` rather than +manually replacing the service. Prepare canonical declarations and separate, +encrypted backup archive/key restore evidence; run the command without +`--commit` first and review its state classification. Unknown state, an +unidentified supervisor, an existing split profile, invalid backup evidence, or +invalid persisted image references must stop before effects. If no unused +bootstrap token remains, provide a retained administrator token file and create +the node-bound `solo-agent` join token through the public CLI before shutdown; +supply them with `--admin-token` and `--agent-token`. Pass +`--allow-secret-env` and `--acknowledge-recovery-risk` when the reviewed +migration declaration requires those same explicit apply acknowledgments. +Commit as root only after review; it quiesces persisted services and reapplies +the exact declarations through public controls. Retain its rollback +directory until the split services, exact declaration reapply, and +application-level data checks pass. Never recursively chown workload data or +repair migration through SQLite, OCI, CNI, firewall, or namespace mutation. + +Use only the exact release tag and artifact named by `docs/getting-started.md`. 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 @@ -107,10 +121,9 @@ 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 -a rollback signal, not a reason to mutate runtime state directly. The first -stable release has no predecessor compatibility case; every later stable release -must carry proved upgrade and rollback evidence against its adjacent stable -predecessor. Apsuflow is not published to a Cargo registry. +a rollback signal, not a reason to mutate runtime state directly. Every +successor release must carry proved upgrade and rollback evidence against its +preceding supported artifact. Apsuflow is not published to a Cargo registry. ## Local operation @@ -128,15 +141,22 @@ Use `fmt` without `--check` only when reformatting is intended. Use `apply removed. Validation reports portability limits before mutation. Capabilities whose failure can require manual recovery—host networking, devices, and writable 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. +source location and consequence before accepting it. A volume source is itself +an exact hard placement requirement; do not duplicate it in `.apsu` constraints. +On each execution host, list the roots the agent may provide, one absolute path +per line, in root-owned mode-0600 `/etc/apsuflow-agent/host-paths`, then restart +the agent. A listed root grants authority; it need not pre-exist. The agent +creates a missing volume directory only below a listed root and rejects paths +outside those roots or through symlinks. Container entrypoints initialize +application content, not host placement. Verify the actual route or job result; +a successful apply alone proves only admission. -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. +The server daemon runs unprivileged without runtime capabilities; the separately +supervised agent remains rootful only for its authorized runtime and host effects. +Do not run client commands with `sudo`: protect server 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 @@ -200,7 +220,9 @@ job backup { - Reference secret names and set values with `apsuflow secret set`; never embed secret values in `.apsu`. - Routes are L4 TCP/UDP forwarding, not HTTP hostname routing or application TLS. -- Writable host paths are node-local and need placement plus separate data backup. +- Writable host paths are node-local; their volume sources imply placement, the + agent's root-owned `host-paths` file declares availability, and data needs a + separate backup. - Use a service plus an external broker for consumers; use a job for bounded migration, backup, maintenance, or scheduled work. - Scheduled declarations create job runs; inspect them with `apsuflow job runs