diff --git a/packages/mosaic/framework/systemd/user/mosaic-agent@.service b/packages/mosaic/framework/systemd/user/mosaic-agent@.service index 81f76b54..36db469b 100644 --- a/packages/mosaic/framework/systemd/user/mosaic-agent@.service +++ b/packages/mosaic/framework/systemd/user/mosaic-agent@.service @@ -11,7 +11,17 @@ PartOf=mosaic-tmux-holder.service # 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. -ConditionPathExists=%h/.config/mosaic/fleet/agents/%i.env.generated +# +# #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 diff --git a/packages/mosaic/framework/systemd/user/test-fleet-units.sh b/packages/mosaic/framework/systemd/user/test-fleet-units.sh index 4edc1989..4f7ff5ab 100755 --- a/packages/mosaic/framework/systemd/user/test-fleet-units.sh +++ b/packages/mosaic/framework/systemd/user/test-fleet-units.sh @@ -32,6 +32,17 @@ if grep -qF -- '/bin/bash -lc' "$HOLDER"; then fail "holder must not start tmux through a login shell" fi grep -qF 'Requires=mosaic-tmux-holder.service' "$AGENT" || fail "agent does not require holder" +# #1408: the projection condition must arm on EITHER home shape. Both lines must +# carry the `|` triggering prefix — same-type conditions without it AND together, +# which can never be true (one file cannot exist at two paths), so a bare-spelling +# regression would disable autostart everywhere while reading as "has a condition". +grep -qF 'ConditionPathExists=|%h/.config/mosaic/fleet/agents/%i.env.generated' "$AGENT" || \ + fail "agent lacks triggering condition for the config home projection" +grep -qF 'ConditionPathExists=|%h/.mosaic/fleet/agents/%i.env.generated' "$AGENT" || \ + fail "agent lacks triggering condition for the brain home projection (#1408)" +if grep -qE '^ConditionPathExists=[^|]' "$AGENT"; then + fail "agent has a non-triggering ConditionPathExists — same-type conditions AND, re-arming #1408" +fi grep -qF 'start-agent-session.sh' "$AGENT" || fail "agent unit does not call start-agent-session.sh" if grep -qE '^Environment(File)?=' "$AGENT" "$INTERACTION"; then fail "agent units must not accept ambient or projection environment before strict parsing"