From bec592bf5ac0ca58e6054b4128f8256c674fd5d8 Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Thu, 18 Jun 2026 16:39:43 -0400 Subject: [PATCH] fix(agent-team): systemd unit loads ~/orchestrator/.env + uses venv python (D-2/D-7) D-2: add EnvironmentFile=-/home/adam/orchestrator/.env (optional '-') so the P2 GPT-4.1 review loop's cross_reviewer sub-process can read the non-Claude provider key once a task reaches REVIEW. Mirrors the sea-haven-secrev unit. D-7: point ExecStart at the agent-team venv interpreter (/home/adam/orchestrator/agent-team/.venv/bin/python) instead of /usr/bin/env python3, which resolved the system interpreter without the installed deps under systemd's PATH. All hardening (NoNewPrivileges / ProtectSystem=full / ProtectHome=read-only / ReadWritePaths) is retained unchanged (locked decision). --- .../systemd/agent-team-coordinator.service | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/agent-team/systemd/agent-team-coordinator.service b/agent-team/systemd/agent-team-coordinator.service index 20d25d2..3261b3d 100644 --- a/agent-team/systemd/agent-team-coordinator.service +++ b/agent-team/systemd/agent-team-coordinator.service @@ -13,8 +13,10 @@ # systemctl status agent-team-coordinator.service # journalctl -u agent-team-coordinator.service -e -f # -# Secrets come from the EnvironmentFile (leading '-' = optional, no failure if -# absent), ~/secrev.env (mode 600, NOT in git): +# Secrets come from the EnvironmentFile(s) (leading '-' = optional, no failure if +# absent). Two files are loaded, mirroring the sea-haven-secrev unit: +# +# ~/secrev.env (mode 600, NOT in git) - the agent-team runtime keys: # CLAUDE_CODE_OAUTH_TOKEN -> subscription OAuth (from `claude setup-token`). # A raw ANTHROPIC_API_KEY must NOT be set on this # box; it would silently win and meter to API @@ -24,7 +26,18 @@ # REQUIRED for Socket Mode; opens the inbound # WebSocket that receives answers. Without it the # coordinator can post but never hear replies. +# serve() starts the inbound SlackListener only when +# the transport is live Slack AND this token is set. # SLACK_CHANNEL_ID -> target channel for clarifier questions. +# AGENT_TEAM_SLACK_OWNER_IDS -> comma-separated authorized answerer ids +# (AUTHZ-01). The listener FAILS CLOSED if unset. +# +# ~/orchestrator/.env (mode 600, NOT in git) - the P2 review-loop provider key: +# The production serve() wires the GPT-4.1 cross-review loop, which shells the +# local orchestrator run.py -> cross_reviewer once a task reaches REVIEW. That +# sub-process needs the non-Claude provider key from ~/orchestrator/.env (same +# file the sea-haven-secrev unit loads). Optional ('-') so the daemon still +# starts if it is absent; the review path then fails loudly only at REVIEW. [Unit] Description=Sea Haven agent-team Plane-2 coordinator daemon @@ -36,7 +49,11 @@ Type=simple User=adam WorkingDirectory=/home/adam/orchestrator/agent-team EnvironmentFile=-/home/adam/secrev.env -ExecStart=/usr/bin/env python3 run-team.py serve +EnvironmentFile=-/home/adam/orchestrator/.env +# Use the agent-team venv interpreter (where the runtime deps are installed by +# the DEPLOY-R720 / PROVISIONING-RUNBOOK step), NOT the bare system python3 that +# `/usr/bin/env python3` would resolve under systemd's PATH (D-7). +ExecStart=/home/adam/orchestrator/agent-team/.venv/bin/python run-team.py serve Restart=on-failure RestartSec=5 # Hardening - matches the level the sea-haven-secrev unit relies on, scoped for a