cc-ci host: the orchestrator is an opencode agent; no Claude on the box; /secrets convention

Operator 2026-09-07 (evening): Claude sessions stay on notplants-orchestrator;
on the cc-ci host the orchestrator is an opencode agent (agents.toml:
opencode/glm-5.2) steered from https://oc.ci.commoninternet.net, next to the
upgrader/report sessions. claude-install and CLAUDE_BIN are gone from the
modules; launch-upgrader/report print the real UI URL; README "Operating the
orchestrator" rewritten and a "Weekly upgrade run" section added.

Secrets: only cc-ci's, under /secrets/files with runtime paths symlinked
(README §4 table), nothing from other projects — tangled key and the
tailscale line dropped from the host.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
This commit is contained in:
2026-09-07 21:27:23 +00:00
co-authored by Claude Fable 5.1
parent 01caa90e76
commit a72a816b48
7 changed files with 66 additions and 70 deletions
+12 -12
View File
@@ -17,7 +17,7 @@
systemd.services.cc-ci-loops = {
description = "cc-ci Builder/Adversary loops + watchdog (launch.sh start)";
wantedBy = [ "multi-user.target" ]; # enabled after workspace staged (Hetzner cutover)
after = [ "network-online.target" "claude-install.service" ];
after = [ "network-online.target" "opencode-install.service" ];
wants = [ "network-online.target" ];
serviceConfig = {
# KillMode=process: this unit only LAUNCHES the tmux server, it does not own it. With the
@@ -32,14 +32,14 @@
# Append one line to REBOOTS.md per genuine reboot (boot_id-gated; not on manual restart).
ExecStartPre = "${pkgs.bash}/bin/bash /srv/cc-ci/cc-ci-plan/reboot-log.sh";
};
# CLAUDE_BIN points at the standalone CLI installed by claude-install.service; the loops
# backend defaults to claude (persisted in .loop-backend). Without this, launch.py's preflight
# `which(claude)` fails because the systemd `path` below has no /home/loops/.local/bin.
environment = { RESUME_PHASE = "1"; HOME = "/home/loops"; CLAUDE_BIN = "/home/loops/.local/bin/claude"; };
# The loops backend is persisted in .cc-ci-logs/.loop-backend (opencode on the cc-ci host —
# no Claude there since 2026-09-07). The build phases are all DONE; on boot launch.sh just
# re-confirms that and exits.
environment = { RESUME_PHASE = "1"; HOME = "/home/loops"; };
path = [ pkgs.bash pkgs.tmux pkgs.git pkgs.python3 pkgs.openssh pkgs.nettools ];
script = ''
# Put the standalone claude/opencode binaries on PATH. On a cold boot this is the env the
# tmux server (and thus every agent session) inherits, so bare `claude` resolves everywhere.
# Put the standalone opencode binary on PATH. On a cold boot this is the env the tmux
# server (and thus every agent session) inherits.
export PATH="/home/loops/.local/bin:$PATH"
[ -x /srv/cc-ci/cc-ci-plan/launch.sh ] && /srv/cc-ci/cc-ci-plan/launch.sh start || \
echo "workspace not staged yet skipping loop start"
@@ -50,9 +50,9 @@
# lichen-orchestrator / project-orchestrator above: this unit only LAUNCHES the orchestrator's
# tmux session via the agent-orchestrator harness (cc-ci-plan/agents.py); it does not own the
# session or the tmux server. The orchestrator agent is declared in cc-ci-plan/agents.toml
# (backend/model chosen there — Claude Code under Remote Control since 2026-09-07; before that
# opencode/glm-5.2 attached to the shared opencode web server, opencode-web.service in
# orchestrator-host.nix, which the upgrader still uses). The harness watchdog (started by
# (backend/model chosen there: an opencode agent, opencode/glm-5.2, attached to the shared
# opencode web server opencode-web.service in orchestrator-host.nix — and steered from its
# web UI; no Claude on this host, operator 2026-09-07). The harness watchdog (started by
# `agents.py up`) keeps it alive: heal-only (no stall reboots — a persistent supervisor must not
# be killed just for idling). Added 2026-08-03 for reboot-resilience.
systemd.services.cc-ci-orchestrator = {
@@ -85,7 +85,7 @@
# wantedBy multi-user.target) so it never runs on boot/activation — only on the schedule.
systemd.services.cc-ci-upgrade-all = {
description = "cc-ci weekly /upgrade-all run (recipe upgrade survey + PRs, never merges)";
after = [ "network-online.target" "claude-install.service" ];
after = [ "network-online.target" "opencode-install.service" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot"; # launch-upgrader.py spawns the cc-ci-upgrader tmux session and returns
@@ -103,7 +103,7 @@
# timer fire. Holds no secrets (the tinfoil API key lives in the opencode config / auth.json).
EnvironmentFile = "-/srv/cc-ci/upgrader.env";
};
environment = { HOME = "/home/loops"; CLAUDE_BIN = "/home/loops/.local/bin/claude"; };
environment = { HOME = "/home/loops"; };
path = [ pkgs.bash pkgs.tmux pkgs.git pkgs.python3 pkgs.openssh pkgs.nettools ];
script = ''
export PATH="/home/loops/.local/bin:$PATH"