PR Monitoring for T3 Code

A first-class "babysit the PR" mode for agent threads — UX, terminology, and flows.

Plan · July 23, 2026 · v2 — open questions resolved with Theo · UX-first, implementation intentionally deferred

1 · Why this should exist

Transcript history on this machine shows the request made ~27 times in four weeks (~22 Claude Code sessions, ~5 Codex-via-T3 sessions), sometimes four times in a single evening. The phrasing is nearly a template, and the failure mode is always the same: the agent silently stops monitoring and the user becomes the babysitter — re-nudging with "More comments", "You broke CI. Fix it", "Are you still going?". One session even hand-rolled the feature with self-scheduled wakeups every ~4.5 minutes, re-serializing PR state into each continuation prompt.

"Make a PR when you're happy with your implementation. Babysit it and address comments until the automated review bots all approve."Claude Code · lakebed
"Make a PR for your changes and babysit it for review comments. Stop when Macroscope, bugbot and coderabbit all approve."Claude Code · t3code
"You forgot to make it a real pr. Drafts don't get reviews. I fixed it. Monitor for more feedback."Codex · the draft-PR footgun
"More comments" · "You broke CI. Fix it and address any other comments." · "Are you still going?"Manual re-nudges — the pain this feature removes

Two findings that should shape the design more than anything else: (1) the reviewers are bots (Bugbot, Macroscope, CodeRabbit) plus CI — a 10–40 minute active loop with a machine-checkable end state, not a days-long human wait. (2) The stop condition is never "merged" — it is always "all review bots approve + CI green". Merging stays with the user, every time. Monitoring therefore has a success state that is not the PR's terminal state, and that success moment is exactly when the thread should demand attention.

2 · Where it fits: a mode, not a status

Thread state in T3 Code today is three orthogonal axes: session status (running / idle / …), the settled lifecycle (settledOverride + the warm-thread rules from #4309), and the derived sidebar status (working / approval / input / failed / ready).

Monitoring should be a thread-level mode that wraps the existing statuses, not a fifth sidebar status. While babysitting, the thread genuinely alternates between existing states — it is working while addressing a comment and is idle between events. What's new is the wrapper: "this thread has an unfinished goal tied to an external signal, so don't treat idle as done."

Working implement + verify MONITORING  (mode wraps normal statuses) Idle / waiting watching PR events Fixing internal only — pill stays Monitoring Input / approval stuck — escalated, loud new comment / red CI pushed fix can't resolve PR created Ready to merge all gates green · notify Settled merged / closed / stopped exit user merges (#4309 warm)

What the mode does

Inbox-zero alignment: a monitoring thread is the ultimate "in-flight, don't look at me" row — it recedes exactly like working threads do. But no running elapsed counter ("Working 2h 14m" reads as stuck). Show what it's waiting on instead. Legibility of the loop is the feature as much as the loop itself — it answers the recurring "Are you still going?".

3 · Terminology

CandidateForAgainst
BabysitThe user's natural word (typed ~12×); memorable; Cursor precedent proves the conceptBorrowing a competitor's coined term reads as chasing; slightly jokey in a status pill
MonitoringThe user's other natural word; accurate; boring in a good way; works as pill label and prompt verb ("monitor the PR" triggers it naturally)Generic — but generic is fine for a state label
WatchingShortest pill textCollides with GitHub "watch" semantics

Recommendation: "Monitoring" as the formal state/pill. Don't fight the colloquialism — the agent enters the mode whenever the user says babysit / monitor / watch in a prompt. The terminology that matters more is the exit state: "Ready to merge" — it names the moment the user actually cares about, and it's the label that makes the feature feel magical.

4 · Mock UIs

4a · Sidebar

Monitoring rows recede like working rows; the sub-line replaces an elapsed counter with what it's waiting on. When gates go green, the row flips to full prominence.

Sidebar — three threads in different monitoring stages

Note the third row: an agent mid-fix keeps the steady Monitoring pill, with the activity spelled out in the sub-line ("addressing 2 review comments"). One calm pill for the whole mode — no state-flicker in the sidebar. (Decided in review: the pill does not flip to Working during fixes.)

4b · Thread header — monitoring strip

Lives at the top of the thread while the mode is active. Shows the gates (editable), the current wait state, and an always-visible stop.

Thread header strip — mid-monitoring
Monitoring PR #4412
CI Macroscope Bugbot reviewing CodeRabbit
2:41 PMBugbot left 2 comments → evaluating against source
2:44 PMFixed null-check finding · dismissed 1 false positive with reply · pushed a41c2f9
2:45 PMCI re-running (2 checks) · waiting for Bugbot re-review

4c · All green — the payoff moment

Thread header strip — success state
Ready to merge All gates green · 3 comments addressed, 1 dismissed · 2 fix commits

Decided (D1): the Merge… button ships, always behind a confirmation dialog. Never auto-merge — the merge decision stays human, it just happens at the payoff moment without a tab switch.

4d · The one notification

History shows a consistent preference: quiet handling, one final report. No play-by-play pushes. Two push-worthy events only: all green, and stuck/escalated.

Push notification — success
T3
Ready to merge — PR #4412now
All reviewers approved, CI green. Addressed 3 comments (1 dismissed as false positive) across 2 commits.
T3
Needs your input — PR #4412now
CI failed 3× on ios-e2e and it doesn't look like flake — same assertion each run. Paused monitoring for your call.

5 · Example end-to-end flow

User kicks off Working
Fix the thread loading flash. Put up a PR following repo conventions and babysit it until Bugbot, Macroscope and CodeRabbit approve.

Thread enters the normal working state. The babysit instruction is parsed from the prompt — no special UI needed to opt in.

Agent implements, verifies, opens the PR

Real PR, never a draft (drafts don't trigger review bots — encoded as default policy, §6). Conventional title, minimal description. Gates are inferred: CI + the three named bots.

Thread enters Monitoring PR #4412

Row recedes in the sidebar. Header strip shows gates. No "Completed" pill fires — the turn ending is not news. Sub-line: "2 checks pending · waiting on Bugbot".

Event: Bugbot leaves 2 comments → agent wakes and fixes

The pill stays Monitoring throughout; the sub-line shows the activity ("addressing 2 review comments"). Agent verifies each claim against source before acting (default policy): fixes the legitimate null-check finding, replies to the false positive with a one-line dismissal, pushes. Sub-line returns to waiting-on. Still receded, still quiet.

Event: CI fails on the new commit

Agent inspects: flaky ios-e2e job (fails on main too) → re-runs it with escalating suspicion. If it failed 3× with the same real assertion instead, the thread would escalate to Awaiting Input — full prominence, push notification, monitoring paused. It never fails silently.

All gates green → Ready to merge

The one success notification fires. Row flips to prominent/unread. Header strip shows the summary: 3 comments addressed, 1 dismissed, 2 fix commits. Monitoring mode ends.

User merges → warm → settled

Existing machinery takes over untouched: merged PR triggers auto-settle, and the #4309 warm-thread rule keeps it un-settled through any follow-up burst before it files itself away.

6 · Default policies (things the user currently re-types every time)

7 · Entry, exit, and control

8 · Decisions (resolved with Theo, July 23)

D1 · Merge action → Confirm-to-merge button
A Merge… button in the green strip, always behind a confirmation. Never auto-merge. Puts the action at the payoff moment while keeping the decision human.
D2 · Durability → Session-scoped
Monitoring lives in the agent session; if the session dies, monitoring ends. This avoids building server-side re-wake infrastructure in v1 — the agent session itself is the watcher. On death, do whatever is easiest UX-wise; the floor is a visible "Monitoring stopped" marker on the strip/pill so a dead babysitter is at least distinguishable from a quiet one (today's silent-stop is the failure mode being fixed). Loud unread/push treatment and auto-resume are explicitly not required for v1.
D3 · Success gates → Universal default in v1
"All requested reviewers/bots approve + all checks green" everywhere. Per-repo bot-list config deferred until the default proves insufficient. A prompt that names specific bots ("until Bugbot and Macroscope approve") can still narrow the gate for that monitor.
D4 · Human reviewers → Bots + CI only in v1
Gates are review bots and checks. A human "changes requested" wakes the thread and gets addressed like any comment, but humans never block "Ready to merge" — bot loops resolve in minutes, humans take days.
D5 · Cost & limits → Circuit breaker only
Pause and escalate to "needs input" after N wake cycles (~10) — doubles as a loop guard against comment ping-pong with a bot. No spend display in v1.
D6 · Pill behavior → Stay "Monitoring" throughout
One steady pill for the whole mode; activity detail lives in the sub-line only ("Monitoring · addressing 2 comments"). Calmer, no state-flicker in the sidebar. (Overrides the original lean; mocks updated.)

9 · Feasibility note (one paragraph, as promised)

The 30-second VCS poller already delivers PR state, and there's a clean changeRequestState → settled pipeline to extend. What does not exist yet: review-comment ingestion. The session-scoped decision (D2) makes the other big gap — a server-side re-wake mechanism — unnecessary for v1: the live agent session is the watcher, so "monitoring" is closer to a structured, first-class version of the wakeup loop one agent already improvised, with the mode/pill/gates/circuit-breaker living in thread state around it. The exit path deliberately hands off to the untouched #4309 warm/settle logic. Server-side durability (surviving restarts) remains the natural v2 upgrade if dead-session stops turn out to hurt in practice.

10 · Proposed v1 scope

V1 = the actual observed loop, tightly scoped: natural-language entry · bot reviews + CI as universal gates (D3, D4) · quiet fix-up cycles under a steady Monitoring pill (D6) with a visible waiting-on strip · wake-cycle circuit breaker (~10) escalating into the existing input state (D5) · one "Ready to merge" notification · confirm-to-merge button, never auto-merge (D1) · session-scoped monitoring with a simple "Monitoring stopped" marker on death (D2) · hand-off to existing warm/settle on merge. Defer: per-repo gate config, human-reviewer gates, spend display, server-side durability/auto-resume.