docs: extract best-effort oneshot service contract + matrix-avatar (#718 batch 6)
Two new sections housing rationale that was inline in `harness-base.nix`: - `docs/conventions.md::Best-effort oneshot services` — shape contract shared by `tea-login`, `forge-avatar-sync`, and `matrix-avatar-sync`: always exit 0, no `set -e`, skip silently on missing prerequisites, wired to multi-user.target, re-runnable. Plus the artefact-under-agent-home + service-stays- root posture and the operator-visible-via-journalctl trade-off. - `docs/persistence.md::matrix-avatar-sync` — the two-step `media upload` → `set avatar_url` matrix-spec dance + why `RemainAfterExit = false` (so the `.path` watcher's re-fire on token appearance actually re-executes the unit). In-code comments trim to one-liner purpose + pointers; the script bodies stay (they're the actual implementation) but their inline `#` rationale comments collapse where the docs cover them. `description = ''…''` blocks (operator-facing options docs) preserved per iris #718. `nix flake check` clean; `nix fmt` clean.
This commit is contained in:
parent
fe6f96397e
commit
a043c61828
3 changed files with 94 additions and 56 deletions
|
|
@ -206,3 +206,53 @@ Stage and commit when work *looks* ready, then run validation
|
|||
(`cargo check`, `nix flake check`, real deploy). Failures get a
|
||||
follow-up commit rather than an amend. The commit history is the
|
||||
work log; rewriting it loses signal.
|
||||
|
||||
## Best-effort oneshot services
|
||||
|
||||
The harness ships a family of one-shot systemd services that
|
||||
configure agent-side surfaces from values hive-c0re writes into
|
||||
the state dir at provisioning time:
|
||||
|
||||
- `tea-login` — writes `~/.config/tea/config.yml` from the
|
||||
`forge-token` written by `hive-c0re::forge::ensure_user_for`,
|
||||
so `tea repos create` / `tea pulls create` work without
|
||||
interactive prompts.
|
||||
- `forge-avatar-sync` — uploads `hyperhive.icon` SVG to the
|
||||
agent's Forgejo profile, so the icon shows up on commits / PRs /
|
||||
issue comments.
|
||||
- `matrix-avatar-sync` — same idea for matrix profile avatars
|
||||
(two-step `media upload` → `set avatar_url` dance — see
|
||||
`docs/persistence.md::matrix-avatar-sync` for the protocol
|
||||
detail).
|
||||
|
||||
Shape contract — every one of these:
|
||||
|
||||
1. **Always `exit 0`**, even on internal failure. A non-zero exit
|
||||
would mark the unit `failed`, which in turn aborts
|
||||
`nixos-container update` and blocks rebuilds. The agent's
|
||||
capability surface is not allowed to gate the container
|
||||
build.
|
||||
2. **No `set -e`** in the script body. Subshell failures must not
|
||||
propagate. Use `... || true` on every external call that can
|
||||
fail (forge unreachable, missing icon, parse error, etc.)
|
||||
3. **Skip silently when prerequisites are missing**: no token
|
||||
file, no icon, no reachable upstream → `echo` a short skip
|
||||
line + `exit 0`. The next boot tries again.
|
||||
4. **Wired to `multi-user.target`** so they run on every boot
|
||||
(lets a rotated token / new icon take effect without
|
||||
`systemctl restart` gymnastics).
|
||||
5. **Re-runnable**: a second invocation produces the same final
|
||||
state (idempotent uploads, idempotent config rewrites). Used
|
||||
by the `.path` watchers that re-fire on token appearance
|
||||
(#571 — see `docs/persistence.md::matrix-avatar-sync`).
|
||||
|
||||
The artefact lives under the agent user's home where applicable
|
||||
(`~/.config/tea/config.yml`) and is chown'd to that user, but the
|
||||
service itself stays root-owned so the bootstrap ordering doesn't
|
||||
need a user-existence check before each fire.
|
||||
|
||||
This pattern keeps the rebuild path resilient: any failure inside
|
||||
these services degrades the corresponding surface (no tea config,
|
||||
no avatar) but never blocks the container from coming up. The
|
||||
operator notices through `journalctl -u <unit>` rather than a
|
||||
broken switch-to-configuration.
|
||||
|
|
|
|||
Loading…
Reference in a new issue