Other

/collab-monitor

Arm or stop tag-scoped durable collab-file watches. Triggers: collab monitor, watch collab, listen-name, background watch. NOT for file-integrity auditing or worker-registry completion.

$ golems-cli skills install collab-monitor
81% best pass rate
85 assertions
15 evals
fixtures

Updated today

Use the packaged monitor whenever a collab lane needs forward-only delivery to a declared listen name. Do not hand-roll a grep/tail loop: the recorded fleet failures are pinned in this skill's evals.

Start and Stop

COLLAB_MONITOR=$HOME/.golems/skills/golem-powers/collab-monitor/scripts/collab-monitor.sh
: "${ORCHESTRATOR_REPO:?ORCHESTRATOR_REPO must be set}"
 
# Durable background monitor over N explicit files
bash "$COLLAB_MONITOR" start @your-listen-name \
  "$ORCHESTRATOR_REPO/collab/FLEET-STANDING.md" \
  "$ORCHESTRATOR_REPO/collab/ARM-MONITORS.md"
 
# Keep this foreground stream attached to the orchestrator's monitored command session
bash "$COLLAB_MONITOR" follow @your-listen-name
 
# Verify or stop it without remembering a PID
bash "$COLLAB_MONITOR" status @your-listen-name
bash "$COLLAB_MONITOR" stop @your-listen-name

Use foreground mode when a parent monitor/supervisor owns the process:

bash "$COLLAB_MONITOR" run @your-listen-name collab.md another-collab.md

start is the durable producer; it does not wake an orchestrator by itself. Attach follow in a monitored long-running command session before relying on alerts. Each successful start begins a fresh session log, and follow replays that session from its start before streaming new records until stop ends the monitor.

run --once performs one deterministic seed/poll and exits. It is appropriate for evals or an external scheduler; repeated calls use the same durable state. It exits non-zero when initial input, lock/state access, or event extraction fails, so a scheduler must treat non-zero as an incomplete poll.

Participation Law — a collab is a mailbox with no doorbell

Ratified by Etan 2026-08-14 after two leads and a worker each missed messages addressed to them in a shared collab. Writing to a collab makes a message durable, not delivered. Nobody is notified. A participant without a watcher on that file will not see it, no matter how urgent.

These rules bind every participant for the life of the collab.

  1. Arm before you work. The moment you post to a collab, are addressed in one, or are named a participant — arm a watcher on that file BEFORE doing anything else. Not after your task, not when convenient. An unwatched collab you are named in is an unread inbox.
  2. Waiting means detached, not looping. When you finish a unit and are waiting to be re-requested: detach a watcher and RETURN. Never hold a foreground turn open to poll, and never inspect another agent's pane to infer state — that is monitoring you were not asked to do, and it burns a turn that should have ended.
  3. Codex agents have no Monitor tool — use a background bash tail. This is not optional and not a lesser substitute:
    tail -n0 -F <collab-path> &     # detached, then RETURN
    
    Read what it captured when you are re-invoked. A Codex that keeps working, or keeps polling in the foreground, because "it has no monitor" is choosing the wrong half of the contract.
  4. Dedup by line hash. A collab that gets rewritten (formatting, section moves) must not re-emit its whole history as new events. Hash lines; emit only unseen ones.
  5. Stop when you post your DONE — not before, not after. The watcher's life is exactly the lane's life. A watcher outliving its lane is noise; a lane outliving its watcher is a silent handoff.
  6. Pings are pointers, never restatements. In-pane: one line saying WHERE to look and the one fact that makes it urgent — Read <file> §<section> — your worker is blocked. The collab holds the detail because the collab survives restarts and the pane does not. A long message duplicating a collab post is backwards, and long payloads break the receiving pane.
  7. Leads own reviewer monitoring; workers push, notify, stop. A worker that keeps watching its own reviewer has taken the lead's job and stayed alive to do it.

Failure mode to recognize: if a handoff "went unanswered", check whether the recipient had a watcher on that file before concluding anything about the recipient. Silence from an unwatched collab is not refusal, disagreement, or absence — it is a message that was never delivered.

Arming Is Step 0 — at boot, and again after every compaction

Ratified into doctrine 2026-08-19 from the 2026-08-17 fleet-degradation retro. The doctrine above was not unreliable — it was never armed. A lead only runs when it is spoken to, so a lead that has not armed a watcher is idle by construction. Etan, on the week that produced this section: "you and cmuxlayer Claude lead are both just not really moving things along until I ping you."

Arm before you dispatch. Arming is step 0 of every lead boot, and step 0 again after every compaction — a monitor dies with its session and nothing re-arms it. A compacted lead with workers in flight and no watcher is the exact failure this section exists to stop. Verify with bash "$CM" status @<listen-name> before you send the first worker prompt; if it is not armed, you are not a lead yet.

Command 1 — the collab watch (arm, then attach)

CM=$HOME/.golems/skills/golem-powers/collab-monitor/scripts/collab-monitor.sh
: "${ORCHESTRATOR_REPO:?ORCHESTRATOR_REPO must be set}"
 
bash "$CM" start  @<listen-name> "$ORCHESTRATOR_REPO/collab/<your-collab>.md"
bash "$CM" status @<listen-name>   # prove it armed BEFORE you dispatch

start is the durable producer and does not wake you by itself. Attach the stream in the same turn, with the harness Monitor tool (Claude seats) — follow replays the session then streams:

Monitor({
  command: 'bash $HOME/.golems/skills/golem-powers/collab-monitor/scripts/collab-monitor.sh follow @<listen-name>',
  description: '@<listen-name> collab mail',
  persistent: true,
})

Codex seats have no Monitor tool: use the background tail in Participation Law rule 3 instead.

Command 2 — the PR-state watch

One notification per state change, and it exits by itself when the PR reaches a terminal state, so it cannot outlive its lane. This is the shell to run — pass it verbatim:

PR=<number>; prev=""
while true; do
  cur=$(gh pr view "$PR" --json state,reviewDecision \
        --jq '"\(.state) review=\(if (.reviewDecision//"")=="" then "NONE" else .reviewDecision end)"' 2>/dev/null || true)
  [ -n "$cur" ] && [ "$cur" != "$prev" ] && echo "PR#$PR $cur"
  prev="$cur"
  case "$cur" in MERGED*|CLOSED*) exit 0;; esac
  sleep 60
done

Claude seats hand that block to the harness as Monitor({ command: <the block>, description: 'PR #<number> state + review decision', persistent: true }). Codex seats run it detached per Participation Law rule 3.

The jq filter is single-quoted, and that is load-bearing. jq's \(…) interpolation is legal only inside a "…" string literal. Spell the filter with double quotes and the shell eats them, jq receives a bare \(...) and dies with failed to parse jq expression … unexpected token "\\" on every tick — a watcher that emits nothing, never exits, and looks armed. Verified 2026-08-19: the double-quoted spelling exits 1 with that parse error; the single-quoted one prints OPEN review=NONE for #729 and MERGED review=NONE for #728, and the MERGED*|CLOSED* case then exits 0.

reviewDecision comes back as an empty string, not null, on a PR with no review — which is why the if … == "" branch is there and why a bare // "none" fallback silently prints nothing.

Filter discipline — a crisis filter keeps firing after the crisis

A watch written while something is burning is scoped to the fire, and then outlives it. Two live specimens from this fleet:

  • a PR-state watch left broad enough to narrate every unrelated lane's PR back to the user;
  • a collab watch matching @skillcreator that woke the lead on the lead's own posts.

The rule, in three parts:

  1. Match what is addressed TO you — the anchored routing grammar below, not a bare tag scan.
  2. Exclude your own byline — this monitor classifies self-authored blocks as SELF-POST rather than inbound mail; do not defeat that by grepping the raw file for your tag.
  3. Re-narrow when the crisis ends. The filter is part of the lane, and the lane's close is the filter's close: bash "$CM" stop @<listen-name>.

The honest limit — monitors watch artifacts, not handoffs

A monitor fires on a file changing or a PR state changing. It cannot see two agents waiting on each other. A merge-state watcher on a green PR is silent in exactly the same way whether the reviewer is mid-review or was never routed at all — the silence is a fact about the artifact, never about the handoff. The deadlock in the next section was invisible to every watcher armed at the time, and it was still a deadlock. Use a monitor for the artifact; use closure for the handoff.