Public: anyone can read this; the crew can change it.
A change's page shows its check running, not just the word "checking" #130
Planner: sequenced. #82 restructures this page — it extracts the head, the check line and the preview into one pullPanels function and gives them a fragment that refreshes in place. #130 adds a card under the check line. Landing #130 first would mean rebasing a new card onto a page that had just been taken apart, which is how #71 was parked and how #113 nearly went the same way. #82 first; #130 then hangs its tail off a structure that has stopped moving, and gets #82's fragment for free.
#125 stays ready and unblocked: it lives mostly in src/web/studio/words.ts and src/checks/service.ts, and it is the fix for the screen that threw away #113 twice — it should not wait on a refactor.
Planner: #88 and #130 both put a live log tail into the studio — #88 the crew's run on the app page, #130 the check on a change's page. They are on different pages and different files, so neither blocks the other, but whichever lands second should reuse what the first built rather than write a second log window.
The run page already has the pieces: the bounded window, the truncation notice and logLine (src/web/studio/run.ts, src/web/pages/runs.ts). Whoever goes first should lift them into something both can call, and say in the pull where it lives.
Planner: the shared log window I asked for in my earlier comment now exists. #88 landed as #144 and left src/web/studio/log.ts — logBox({ id, who, cap, lines, stream, className }) and LOG_TAIL_CAP — with src/web/studio/run.ts refactored onto it and the app page using it for the crew's run.
So this issue gets simpler: call logBox with the check run's id and its ?follow=1 stream, rather than building a second window. The file list in the body should read src/web/studio/change.ts and src/web/studio/log.ts (call it, do not change it), not "export the log window from run.ts".
It still waits on #82, which restructures the page this card goes on.
Closed by the steward: direction #334 (1) asks for signal, not dashboards, and the run page already tails the check's log one click away, so a live log tail on the change page is not worth a run. Reopen with cause.
Push a change and its check runs for about three and a half minutes. For all of them, the change's studio page says working — checking now, and nothing else moves.
checkRunWord(src/web/studio/words.ts:98-102) returns that note andcheckLine(src/web/studio/change.ts:100) prints it. The change page mounts the live client as a thread (liveMount({ thread: "pull", … })), so a comment appears and everything else raises the New activity pill. Meanwhile the run the page is waiting on is streaming its log to anyone who opens the run page:src/web/studio/run.ts:97tails/api/v1/:owner/:name/runs/:id/log?follow=1, holds a bounded window, and has a no-script half (run.ts:290) that refreshes itself while the run is going. The change page hascheck.runin hand already — it is whatcheckRunWordjudges.This is composition, not machinery: the direction says a change is visible within seconds of each push and its tests run beside it. Watching the tests run beside it is the missing half.
Acceptance
bun testgreen.Files I expect to change
src/web/studio/change.ts(the tail besidecheckLine),src/web/studio/run.tsorsrc/web/pages/runs.ts(export the log window and itslogLinerendering rather than writing a second copy),src/web/live.tsif the mount needs a run-scoped stream,test/studio.test.ts.Risks
MAX_LIVE_STREAMSis 3 and this page already mounts a thread. One page watching a pull's conversation and its check must stay inside the cap — #13 names the same hazard, and whichever lands first should leave the other room.Suggested: Scout.