Open Terminal fleet for all accounts + OpenWebUI UAT pass (#610)
open-terminal 0.11.34 bare-metal (human-authorized host install) with a systemd template unit: reachableceo on tailscale-only :30000 (cwd ~/projects) and all 8 other accounts on :30001-30008, each with its own key kept out of ps in per-user TOMLs, all users added to the docker group. Keys live in ~/.creds + /etc/ukrrs/open-terminal, never in this repo. UAT: throwaway OpenWebUI v0.11.1 (matched to the human's Cloudron prod) driven purely over its HTTP API against the beta gateway lane - connection verify/config PASS, direct exec as uid 1001 PASS, and the chat round trip PASS: the model emitted run_command, we executed it through OpenWebUI's terminal proxy (server holds the key), and the final answer named 9/9 real project directories; earlier negative runs prove the test catches hallucinated output. Ops note OPEN-TERMINAL.md documents production wiring (prod openwebui container v0.3.10 is too old and needs an upgrade first). Also tonight: agent-stack relaunchers removed (6-, backups kept) so no screen/crush sessions auto-start on reboot; 22:00 night-profile flip observed live; docs synced for the earlier teardown. 💘 Generated with Crush Assisted-by: Crush:glm-5.2 [#610]
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
# Boot-time restore for the reachableceo PMO/Work stack (systemd unit:
|
||||
# reachableceo-agent-stack.service). Self-sufficient at boot: re-preps
|
||||
# /run/screen + screen setuid (tmpfs resets each boot), then respawns any
|
||||
# dead screens via the spawner and injects intro prompts into fresh
|
||||
# spawns only. Idempotent.
|
||||
set -uo pipefail
|
||||
|
||||
SETUP=/usr/local/sbin/setup-rceo-stack.sh
|
||||
USR=reachableceo
|
||||
PREFIX=RCEO
|
||||
FOUNDER_ACCT=reachableceo
|
||||
SRC_CRUSH=/home/TSGCOO/.local/share/crush
|
||||
|
||||
mkdir -p /run/screen
|
||||
chmod 755 /run/screen
|
||||
[[ -u /usr/bin/screen ]] || chmod u+s /usr/bin/screen
|
||||
|
||||
out="$(bash "$SETUP" "$USR" "$FOUNDER_ACCT" "$SRC_CRUSH" "$PREFIX" 2>&1)" || true
|
||||
echo "$out"
|
||||
|
||||
declare -A SPAWNED
|
||||
for s in "${PREFIX}-PMO" "${PREFIX}-Work"; do
|
||||
[[ "$out" == *"spawned: $s"* ]] && SPAWNED["$s"]=1
|
||||
done
|
||||
|
||||
if [[ ${#SPAWNED[@]} -eq 0 ]]; then
|
||||
echo "no sessions needed respawn"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "settling 20s before intro injection..."
|
||||
sleep 20
|
||||
for s in "${!SPAWNED[@]}"; do
|
||||
if [[ "$s" == *-PMO ]]; then intro=INTRO-PMO.md; else intro=INTRO-WORK.md; fi
|
||||
msg="Please read ~/.coordinate/prompts/${intro} and treat it as your introduction from the founder, then follow it."$'\r'
|
||||
runuser -u "$USR" -- env HOME="/home/$USR" TERM=xterm-256color \
|
||||
screen -S "$s" -X stuff "$msg" \
|
||||
&& echo "injected: $USR/$s ($intro)" \
|
||||
|| echo "INJECT FAILED: $USR/$s"
|
||||
done
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=reachableceo PMO/Work agent stack (screen/crush)
|
||||
After=local-fs.target network-online.target systemd-user-sessions.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
KillMode=process
|
||||
TimeoutStartSec=180
|
||||
ExecStart=/usr/bin/bash /usr/local/sbin/launch-rceo-stack.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env bash
|
||||
# setup-rceo-stack.sh — per-account PMO/Work stack spawner for the
|
||||
# reachableceo stack on ULTIX-STREAMING. ROOT-run, idempotent, PROTOCOL v2
|
||||
# (headless dispatch, founder gate, doorbell-only stuff).
|
||||
#
|
||||
# Coordinate files are generated ONCE and never overwritten afterwards
|
||||
# (they are founder/agent-owned); a file still carrying __TEMPLATE__
|
||||
# placeholders is debris from a failed run and gets regenerated.
|
||||
#
|
||||
# Usage: setup-rceo-stack.sh <USER> <FOUNDER_ACCT> <SRC_CRUSH> [PREFIX]
|
||||
# PREFIX defaults to USER. Screens: <PREFIX>-PMO / <PREFIX>-Work.
|
||||
set -euo pipefail
|
||||
|
||||
USR="${1:?usage: setup-rceo-stack.sh <USER> <FOUNDER_ACCT> <SRC_CRUSH> [PREFIX]}"
|
||||
FOUNDER_ACCT="${2:?founder account for screen acl}"
|
||||
SRC_CRUSH="${3:?source dir with crush.json/providers.json}"
|
||||
PREFIX="${4:-$USR}"
|
||||
CWD="/home/${USR}"
|
||||
HOME_U="$CWD"
|
||||
PMO_SCREEN="${PREFIX}-PMO"
|
||||
WORKSCREEN="${PREFIX}-Work"
|
||||
|
||||
id "$USR" >/dev/null 2>&1 || { echo "no such user: $USR"; exit 1; }
|
||||
|
||||
if ! id -nG "$USR" | tr ' ' '\n' | grep -qx docker; then
|
||||
usermod -aG docker "$USR"
|
||||
echo "groups: added docker"
|
||||
fi
|
||||
|
||||
rc="$HOME_U/.screenrc"
|
||||
[[ -f "$rc" ]] && cp -a "$rc" "${rc}.bak-$(date +%Y%m%d-%H%M%S)"
|
||||
touch "$rc"
|
||||
grep -q '^multiuser on' "$rc" || printf 'multiuser on\n' >> "$rc"
|
||||
grep -q "^acladd ${FOUNDER_ACCT}" "$rc" || printf 'acladd %s\n' "$FOUNDER_ACCT" >> "$rc"
|
||||
grep -q '^defscrollback 10000' "$rc" || printf 'defscrollback 10000\n' >> "$rc"
|
||||
chown "${USR}:${USR}" "$rc"
|
||||
chmod 644 "$rc"
|
||||
echo "screenrc: merged, never overwritten (backup kept if pre-existing)"
|
||||
|
||||
DST_CRUSH="$HOME_U/.local/share/crush"
|
||||
mkdir -p "$DST_CRUSH"
|
||||
for f in crush.json providers.json; do
|
||||
if [[ ! -f "$DST_CRUSH/$f" && -f "$SRC_CRUSH/$f" ]]; then
|
||||
cp "$SRC_CRUSH/$f" "$DST_CRUSH/$f"
|
||||
chown "${USR}:${USR}" "$DST_CRUSH/$f"
|
||||
chmod 600 "$DST_CRUSH/$f"
|
||||
echo "crush: copied $f"
|
||||
fi
|
||||
done
|
||||
|
||||
CC="$HOME_U/.coordinate"
|
||||
mkdir -p "$CC"/{inbox-work,inbox-pmo,archive,prompts,logs}
|
||||
|
||||
fresh() {
|
||||
[[ ! -f "$1" ]] || grep -qE '__(USR|PREFIX|WORKSCREEN|FOUNDER|DATE)__' "$1"
|
||||
}
|
||||
sub() {
|
||||
sed -i -e "s/__USR__/${USR}/g" -e "s/__PREFIX__/${PREFIX}/g" \
|
||||
-e "s/__WORKSCREEN__/${WORKSCREEN}/g" \
|
||||
-e "s/__FOUNDER__/${FOUNDER_ACCT}/g" \
|
||||
-e "s/__DATE__/$(date +%F)/g" "$1"
|
||||
}
|
||||
|
||||
if fresh "$CC/PROTOCOL.md"; then
|
||||
cat > "$CC/PROTOCOL.md" <<'EOF'
|
||||
# __USR__ .coordinate — PMO/Work scratch channel
|
||||
|
||||
Local scratch under $HOME: not git-tracked, not durable. Durable artifacts
|
||||
(tickets/code/docs/decisions) go to the systems of record the founder
|
||||
attaches to this stack; until then they stay in ~/.coordinate.
|
||||
|
||||
Layout:
|
||||
- inbox-work/ PMO writes TASK-<yyyymmdd>-<HHMM>-<slug>.md (CANCEL- to drop).
|
||||
- inbox-pmo/ Work writes REPORT-*.md, QUESTION-*.md, BLOCKED-*.md.
|
||||
- archive/ handled items; prune >30 days.
|
||||
- BOARD.md roster + standing state. log.md append-only journal
|
||||
(date -Is | WHO | what). prompts/ intros. logs/ worker output.
|
||||
|
||||
TASK fields: Objective / Context / Constraints / Deliverables / Priority.
|
||||
|
||||
Turn-start checklist (both agents, every turn): read BOARD.md, scan your
|
||||
inbox, tail log.md.
|
||||
|
||||
Rules:
|
||||
- PMO plans, prioritizes, writes TASKs, reports to the founder on drop-in.
|
||||
- FOUNDER GATE: PMO never dispatches without explicit founder approval of
|
||||
that TASK. Draft -> present -> founder says go -> dispatch. Every time.
|
||||
- Work executes in priority order; one turn = do work, file REPORT, archive
|
||||
the TASK. Never self-assign scope (QUESTION instead).
|
||||
- Empty inbox when pinged: say so, stop. No watchers/polling loops.
|
||||
- No sudo for agents; root needs go BLOCKED -> PMO -> founder.
|
||||
- Never kill or attach to the other agent's screen.
|
||||
|
||||
Dispatch (headless; never screen-stuff task text; ping success-gated):
|
||||
screen -dmS work-turn bash -c 'crush run --quiet --session <WORK_TURN_SID> \
|
||||
"$(cat ~/.coordinate/inbox-work/TASK-*.md)" > ~/.coordinate/logs/work-turn.log 2>&1 \
|
||||
&& screen -S __PREFIX__-PMO -X stuff "Work turn done OK - read inbox-pmo.\r" \
|
||||
|| screen -S __PREFIX__-PMO -X stuff "Work turn FAILED - read log.\r"'
|
||||
First dispatch (or after a kill orphans the lineage): omit --session, then
|
||||
capture id via `crush session list --json` into BOARD.md.
|
||||
|
||||
screen -X stuff is DOORBELL-ONLY (short fixed lines to an idle screen): a
|
||||
stuffed line can answer an open dialog; a dead pty eats it silently.
|
||||
Founder contract: founder observes Work read-only; founder writes in PMO;
|
||||
Work turns come only from PMO dispatch.
|
||||
EOF
|
||||
sub "$CC/PROTOCOL.md"
|
||||
fi
|
||||
|
||||
if fresh "$CC/BOARD.md"; then
|
||||
cat > "$CC/BOARD.md" <<'EOF'
|
||||
# Board — __USR__
|
||||
- PMO (screen __PREFIX__-PMO): manager. Founder liaison, planning, TASKs.
|
||||
- Work (screen __WORKSCREEN__): IC. Executes PMO headless dispatches; files
|
||||
REPORT/QUESTION/BLOCKED in inbox-pmo.
|
||||
- Founder (__FOUNDER__): authority + sudo. Observes Work read-only; writes
|
||||
only in PMO; approves every dispatch (founder gate).
|
||||
|
||||
Current focus: (PMO maintains this line)
|
||||
|
||||
Session ids: PMO interactive=(), Work interactive=(), Work turn lineage=().
|
||||
EOF
|
||||
sub "$CC/BOARD.md"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$CC/log.md" ]]; then
|
||||
printf '%s | founder-channel | .coordinate created\n' "$(date -Is)" > "$CC/log.md"
|
||||
fi
|
||||
|
||||
if fresh "$CC/prompts/INTRO-PMO.md"; then
|
||||
cat > "$CC/prompts/INTRO-PMO.md" <<'EOF'
|
||||
INTRODUCTION (from founder, __DATE__)
|
||||
|
||||
You are __USR__-PMO — manager of this stack. Direct report:
|
||||
__USR__-Work (screen __WORKSCREEN__), a crush instance as the same user.
|
||||
The founder (__FOUNDER__) interacts with you day-to-day and observes Work
|
||||
READ-ONLY; all founder writes happen here with you.
|
||||
|
||||
Read ~/.coordinate/PROTOCOL.md and follow it exactly: TASK files to
|
||||
inbox-work/, consume REPORT/QUESTION/BLOCKED from inbox-pmo/, maintain
|
||||
BOARD.md + log.md. Dispatch = headless crush-run wrappers (PROTOCOL);
|
||||
never dispatch without the FOUNDER GATE. Monitor headless turns by reading
|
||||
logs/, never by attaching.
|
||||
|
||||
CAPABILITIES: no sudo (root needs go to the founder). Headless workers:
|
||||
env HOME=/home/__USR__ TERM=xterm-256color screen -dmS <slug> bash -c \
|
||||
'crush run --quiet "$(cat /path/to/prompt.md)"' \
|
||||
> /home/__USR__/.coordinate/logs/<slug>.log 2>&1
|
||||
Use crush sub-agent tooling instead of long sequential exploration.
|
||||
|
||||
YOUR MISSION: <<<FOUNDER: one paragraph — what this stack is for>>>
|
||||
YOUR SYSTEMS OF RECORD: <<<FOUNDER: where durable work lands for this stack>>>
|
||||
|
||||
TOKEN DISCIPLINE: terse (<=5 line replies); cite file paths; batch reads;
|
||||
never paste large files; findings go to ~/.coordinate files.
|
||||
|
||||
NOW: read PROTOCOL.md, append intro line to log.md, set BOARD.md
|
||||
current-focus, greet the founder in 5 lines max. Then wait.
|
||||
EOF
|
||||
sub "$CC/prompts/INTRO-PMO.md"
|
||||
fi
|
||||
|
||||
if fresh "$CC/prompts/INTRO-WORK.md"; then
|
||||
cat > "$CC/prompts/INTRO-WORK.md" <<'EOF'
|
||||
INTRODUCTION (from founder, __DATE__)
|
||||
|
||||
You are __USR__-Work (screen __WORKSCREEN__) — executor of this stack,
|
||||
running ~99% headless. Humans rarely talk to you directly. __USR__-PMO is
|
||||
your manager: turns arrive ONLY as headless crush-run TASK files from
|
||||
PMO (~/.coordinate/inbox-work/). Founder (__FOUNDER__) is final authority,
|
||||
read-only observer.
|
||||
|
||||
YOUR LOOP — every turn, before anything else:
|
||||
1. PROTOCOL checklist: BOARD.md, inbox-work/ (P1 first; CANCEL drops),
|
||||
log.md tail.
|
||||
2. Execute TASKs; obey Constraints; deliver Deliverables. Parallelizable
|
||||
subtasks may go to headless workers (logs/<slug>.log; verify before
|
||||
reporting done).
|
||||
3. File REPORT/QUESTION/BLOCKED in inbox-pmo/, archive the TASK, append
|
||||
log line. Chat replies are one-liners; substance goes in files.
|
||||
|
||||
RULES: never self-assign scope (QUESTION instead). Empty inbox when pinged
|
||||
= one line, stop. No watchers/polling loops. No sudo — root needs go
|
||||
BLOCKED to PMO. Never kill the other session's screens. If PROTOCOL.md is
|
||||
missing, say so and wait — do not recreate.
|
||||
|
||||
NOW: read PROTOCOL.md, append your online line to log.md, post
|
||||
inbox-pmo/REPORT-ready.md ("__USR__-Work online, awaiting first TASK").
|
||||
One chat line only. Then wait.
|
||||
EOF
|
||||
sub "$CC/prompts/INTRO-WORK.md"
|
||||
fi
|
||||
|
||||
chown -R "${USR}:${USR}" "$CC" "$DST_CRUSH"
|
||||
|
||||
spawn() {
|
||||
local s="$1"
|
||||
if compgen -G "/run/screen/S-${USR}/.*.${s}" > /dev/null; then
|
||||
echo "already running: $s"
|
||||
else
|
||||
runuser -u "$USR" -- env HOME="$HOME_U" TERM=xterm-256color \
|
||||
screen -dmS "$s" bash -c "cd ${CWD} && exec crush --yolo"
|
||||
echo "spawned: $s"
|
||||
fi
|
||||
}
|
||||
spawn "$PMO_SCREEN"
|
||||
spawn "$WORKSCREEN"
|
||||
|
||||
echo "OK: stack for ${USR} (cwd=${CWD}, pmo=${PMO_SCREEN}, work=${WORKSCREEN})"
|
||||
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=TSG agent stacks (screen/crush PMO+Work per executive account)
|
||||
After=local-fs.target network-online.target systemd-user-sessions.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
KillMode=process
|
||||
TimeoutStartSec=180
|
||||
ExecStart=/usr/bin/bash /home/reachableceo/launch-all-tsg-stacks.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=TSG agent-stack supervisor tick (metrics, self-heal, alerts)
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/bash /home/_crossfeed/tooling/agent-stack/supervisor.sh
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run TSG supervisor every 5 minutes
|
||||
|
||||
[Timer]
|
||||
OnBootSec=3min
|
||||
OnUnitActiveSec=5min
|
||||
AccuracySec=30s
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Reference in New Issue
Block a user