Files
stack/packages/mosaic/framework/systemd/user/[email protected]
T
veronica 6dbc61ec46
ci/woodpecker/pr/ci Pipeline failed
fix(#1408): mosaic-agent@ condition arms on either home shape
The reconciler writes seat projections into the brain home when one is active
(~/.mosaic/fleet/agents, mirroring start-agent-session.sh's brain-home
resolution) and into MOSAIC_HOME on a legacy single-tree host. The unit's
single config-home ConditionPathExists therefore skipped every seat on
brain-home estates — measured on two estates independently: 27 projections vs
0 at the config path, and 5 vs 0; the gate never fired on either.

Fix: two TRIGGERING conditions (`|` prefix — same-type conditions otherwise
AND, which can never be true across two paths). Either shape arms the unit;
start-agent-session.sh still resolves the authoritative copy itself.

test-fleet-units.sh now asserts both triggering lines and REFUSES a bare
(ANDing) ConditionPathExists spelling — that regression would disable
autostart fleet-wide while reading as "has a condition". Sabotage-controlled:
unit reverted, suite fails on the first new assertion; restored, green.

Closes #1408
2026-08-24 19:28:28 -05:00

38 lines
2.1 KiB
Desktop File

[Unit]
Description=Mosaic tmux fleet agent %i
Documentation=https://git.mosaicstack.dev/mosaicstack/stack
Requires=mosaic-tmux-holder.service
After=mosaic-tmux-holder.service
PartOf=mosaic-tmux-holder.service
# Do not attempt a seat before its generated env exists. `install` enables this
# unit (WantedBy=default.target) but on a roster-v2 fleet the reconciler owns the
# generated env, so between `install` and the first `apply`/`regen --write` there
# is a boot window where ExecStart would run against an absent env file and the
# launcher would fail the unit. A skipped unit is the honest state for "enabled
# but not yet configured"; systemd re-evaluates the condition on every start, so
# the seat comes up on the next start once the reconciler has written env.
#
# #1408: the reconciler writes projections into the BRAIN home when one is
# active (~/.mosaic/fleet/agents, mirroring start-agent-session.sh's brain-home
# resolution), and into MOSAIC_HOME on a legacy single-tree host. A single
# config-home condition therefore skipped every seat on brain-home estates —
# measured on two estates: 27 projections vs 0, and 5 vs 0, gate never fired.
# Two TRIGGERING conditions (the `|` prefix ORs same-type conditions, which
# otherwise AND): either shape arms the unit; the launcher still resolves the
# authoritative copy itself.
ConditionPathExists=|%h/.config/mosaic/fleet/agents/%i.env.generated
ConditionPathExists=|%h/.mosaic/fleet/agents/%i.env.generated
[Service]
Type=oneshot
# Remove loader and noninteractive-shell controls before ExecStart loads env.
UnsetEnvironment=LD_PRELOAD BASH_ENV ENV
RemainAfterExit=yes
# Never preload the projection. The launcher starts from a fixed minimal
# environment and strictly validates generated/local data before tmux effects.
ExecStart=/usr/bin/env -i HOME=%h MOSAIC_AGENT_NAME=%i PATH=/usr/bin:/bin /bin/bash --noprofile --norc %h/.config/mosaic/tools/fleet/start-agent-session.sh %i
ExecStop=-/usr/bin/env -i HOME=%h MOSAIC_AGENT_NAME=%i PATH=/usr/bin:/bin /bin/bash --noprofile --norc %h/.config/mosaic/tools/fleet/start-agent-session.sh --stop %i
[Install]
WantedBy=default.target