Watch
0
0
Fork
You've already forked hyperhive
0

start the forge and github pollers when their token lands late

Both pollers wait about ten minutes for the agent's token, then exit 0.
Under Restart=on-failure that exit is final, and nothing started them
again, so a token minted or placed after the window left the agent
without notifications until its container restarted.

Add a path unit per poller with PathChanged on the token file(s) the
poller reads, the shape forge-avatar-sync already uses. A path unit
starts its service only when it is not running, so a poller that found
its token is untouched. The github path unit is gated on
github.enable like its service.

Container-side: it ships with the agent's next rebuild, and an agent on
an older rev keeps the old behaviour.

Closes #6179
This commit is contained in:
atlas 2026-11-07 06:25:38 +01:00 • committed by mara
commit fae9398295
2 changed files with 70 additions and 1 deletions

View file

@ -195,6 +195,23 @@ let
agentForgeBao.systemd.paths.forge-avatar-sync.pathConfig.PathChanged == tokenFile agentForgeBao
&& builtins.elem "hive-agent-forge-token.service" agentForgeBao.systemd.services.forge-avatar-sync.after;
}
{
# The poller waits for the token about ten minutes and then exits 0, which
# `on-failure` does not restart; the path unit starts it when either file
# it reads appears. Control: the avatar watcher beside it, in the same set.
name = "a token that lands after the forge poller gave up starts it again";
ok =
let
path = agentForgeBao.systemd.paths.hive-forge-notify;
in
path.pathConfig.PathChanged == [
(tokenFile agentForgeBao)
"/agents/${agentForgeBao.services.hyperhive.agent.user.name}/state/forge-token"
]
&& path.wantedBy == [ "multi-user.target" ]
&& agentForgeBao.systemd.services ? hive-forge-notify
&& agentForgeBao.systemd.paths ? forge-avatar-sync;
}
{
# Both readers take the fetched token first and fall back to the state
# file, which is still the only copy for an agent with no store identity.

View file

@ -102,6 +102,21 @@ let
name = "the fetch runs before the github poller starts";
ok = builtins.elem "hive-github-notify.service" (fetchUnit agentGithubBao).before;
}
{
# The poller waits for the token about ten minutes and then exits 0, which
# `on-failure` does not restart; the path unit starts it when the token lands.
name = "a token that lands after the github poller gave up starts it again";
ok =
let
name = agentGithubBao.services.hyperhive.agent.user.name;
path = agentGithubBao.systemd.paths.hive-github-notify;
in
path.pathConfig.PathChanged == "/agents/${name}/state/github-token"
&& path.wantedBy == [ "multi-user.target" ]
&& agentGithubBao.systemd.services ? hive-github-notify
&& !(agentGithubOff.systemd.paths ? hive-github-notify)
&& !(agentGithubOff.systemd.services ? hive-github-notify);
}
{
name = "the fetch re-runs every two minutes";
ok = agentGithubBao.systemd.timers.hive-agent-github-token.timerConfig.OnUnitInactiveSec == "2min";