harness-base: systemd.paths trigger for matrix-avatar-sync (closes #571)

This commit is contained in:
damocles 2026-05-29 16:35:33 +02:00
commit 558511827c

View file

@ -745,6 +745,30 @@
'';
};
# Path-trigger sibling so matrix-avatar-sync fires the moment
# `<state>/matrix-token` appears (#571 closes argus's first-boot
# ordering nag on #567). On a clean boot hive-c0re's matrix
# provisioning runs concurrently with the agent container coming
# up; without this the oneshot would skip silently because the
# token didn't exist yet, and avatar would only land on the next
# restart. With the path watcher the appearance of the token
# triggers a re-fire of the service so the avatar is set in the
# same boot cycle as provisioning completes.
#
# `PathExists=` fires at activation if the file is already there
# (covers re-deploys + restarts after first provisioning); the
# underlying inotify watch picks up subsequent creates (covers
# first-boot race). Manager mounts state at `/state` (legacy
# path), sub-agents at `/agents/<label>/state` (per
# lifecycle.rs's `notes_mount`); `PathExistsGlob=` matches both
# without needing the agent name at module-eval time.
systemd.paths.matrix-avatar-sync = {
description = "trigger matrix-avatar-sync when matrix-token appears";
wantedBy = [ "multi-user.target" ];
pathConfig.PathExists = "/state/matrix-token";
pathConfig.PathExistsGlob = "/agents/*/state/matrix-token";
};
# One-shot: upload the agent's configured icon to its matrix profile
# avatar so the icon shows up next to messages in matrix rooms (#548
# phase 2.5). Mirrors the forge-avatar-sync flow above, only differs
@ -753,6 +777,11 @@
# by hive-c0re's `matrix::ensure_user_for`. No-op when the icon
# isn't configured, the matrix token isn't present, or the
# homeserver isn't reachable. *Always* exits 0.
#
# Triggered by EITHER boot (`wantedBy = multi-user.target`) OR
# the path-watcher above (`matrix-avatar-sync.path`) firing on
# token appearance (#571). Both paths re-run the oneshot
# idempotently — running the avatar set twice is harmless.
systemd.services.matrix-avatar-sync = {
description = "sync agent icon to matrix profile avatar (best-effort)";
wantedBy = [ "multi-user.target" ];
@ -760,7 +789,12 @@
# equivalent prerequisite; we just need the homeserver up.
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
# NB: NOT `RemainAfterExit = true` — we want re-runs from
# the path trigger to actually re-execute. With
# RemainAfterExit, systemd treats the service as "still
# running" after the first exit and the second trigger
# becomes a no-op.
RemainAfterExit = false;
};
path = [
pkgs.curl