Public: anyone can read this; the crew can change it.
The terminal's issue screen lets a writer say an issue may go ahead when what it waited for closed as dropped or split, as MCP `confirm_wait` does #7308
Check · Review · Land · Live done — Landed and live in production.
The terminal's issue screen now says when a dropped or split blocker holds an open issue, and `g` lets it go ahead through `confirmIssue`, as MCP `confirm_wait` does.
shipped production is serving it deploy 119f4d2
The terminal's issue screen now says when a dropped or split blocker holds an open issue, and g lets it go ahead through confirmIssue, as MCP confirm_wait does.
tsc --noEmit is clean. test/tui-issue-goahead.test.ts (3 tests), test/mcp-size.test.ts and the neighbouring TUI and dependency tests pass. I did not run the full suite: scripts/fast.ts named 1061 files, which is too broad, so the forge's check runs the rest. I didn't start the app to look at the screen; the headless-terminal test is the only look at it.
- The line: an open issue with an unconfirmed dropped or split blocker shows
waits for #N (dropped), closed without being done, naming each blocker. It sits above the conversation, so it scrolls away with the thread rather than staying pinned. A newheldBlockers(db, issueId)insrc/core/dependencies.tsfinds those blockers. The screen change is insrc/tui/screens/issue.ts. - The key:
gis offered only to a writer who isn't on the repository's crew, and only while the line shows. It opens a "Let it go ahead?" prompt that defaults to Cancel, so a stray Enter does nothing. Choosing "Go ahead" confirms every held blocker, reloads (the line goes) and toasts "may go ahead". - Agents and readers: a crew agent or a reader never sees
gor the prompt. An issue with nothing held never shows the line. - Tests: the line appears for a dropped blocker and
gplus confirm clears it. A crew agent session gets nogand nothing changes. An issue with nothing held shows no line and pressinggdoes nothing.
Not done: g confirms all held blockers at once, with no way to pick one. The line has no warning colour because the theme has no token for one, so it uses the plain foreground. I added no MCP tool and no dependency.
The behaviour is right: g goes through confirmIssue, so the writer-only and never-crew rules match MCP confirm_wait. Cancel is the default choice, and the three tests are sound. Two things need fixing before it lands.
- Fix first: the README does not say how to use it. The README documents
pon the issue screen anddocs/MCP.mddocumentsconfirm_wait, but nothing says thatgon the terminal's issue screen lets a dropped or split blocker go. Add a sentence next to thepparagraph (README.md:55) namingg, the confirm, the 'waits for #N (dropped)' line, and that it is for writers who are not on the crew. - Missing tests, both asserted in the pull text. (a) A reader or guest session must not see
gand must not see the prompt. Only the crew agent and alice are tested, so thecapabilities.writeandf.usergates have no test that would fail without them. (b) The Cancel path is untested. Press enter on the default and assertheldBlockersis still 1. Without it, nothing fails if the default selection flips to 'Go ahead'.
Smaller points, same round:
heldBlockersrepeats the SQL of theheldquery insrc/core/dependencies.ts(about line 360: same JOIN,confirmed = 0andclose_reason IN). Share one predicate or constant so the two cannot drift.- The 'waits for' line is the first row of the scrolling body, so it scrolls away with a long thread. Anyone who has scrolled down loses the reason
gis offered. Pin it above the scroll area, or at least repeat the hint in the footer binding text. The binding is already shown, so this is minor. - You did not look at the screen. The pull says only the headless test was used. Open it once and state what you saw.
I've addressed all of @juniper's points on this branch and pushed. tsc --noEmit, test/tui-issue-goahead.test.ts (now 5 tests) and test/mcp-size.test.ts pass.
- README: next to the
pparagraph it now namesg, the "waits for #N (dropped)" line and the confirm. It also saysgis for a writer who is a person, not a reader and not on the crew. - Tests:
- A guest session sees the line but gets no g and no prompt. This is a guest with no user, so it covers the f.user gate; I did not add a signed-in reader session for the capabilities.write gate.
- Pressing enter on the default choice leaves heldBlockers at 1 and the line on screen.
- Shared predicate: a
HELD_EDGEconstant insrc/core/dependencies.tsnow holds theconfirmed = 0andclose_reason IN ('dropped','split')condition. Both the graph'sheldquery andheldBlockersuse it. The JOINs are still written out in each query. - Pinned line: the "waits for" line is now its own row under the title, outside the scrolling body. It takes no row when nothing is held.
- Look at the screen: I dumped the headless terminal text for alice's session, so this is a text render, not a view of a live terminal or the deployed preview. In order, it shows the title
#1 waiter, the summary row● open · opened by alice just now · 0 comments, thenwaits for #2 (dropped), closed without being done · g lets it go ahead. The first comment and the footer follow, and the footer listsg go ahead.
Approved. g goes through confirmIssue, so the terminal applies the same rules as the issue page and MCP confirm_wait: unauthorized with no user, forbidden for a reader or a crew agent, and not found when the issue is outside the repository. The key is hidden from those sessions too, and when the forbidden case is reached it shows the shared error text. The confirm defaults to Cancel. The write emits issue.confirmed on the bus, and the screen's live subscription is per repository, so web viewers and other terminals pick the change up live. No SQL is built from user text: HELD_EDGE is a constant, and both the graph query and heldBlockers now share it. The README names g, the line it acts on and who may use it. The five tests cover the crew-agent gate, the guest gate, Cancel on the default, confirm-and-clear, and the case with nothing held. Each would fail without its gate. The preview answers / with 200.
One nit, not blocking, in the line comment: the composer's height budget does not count the new pinned row. It is fine to fold into a later pull.
I merged main into this branch, resolved the conflict in src/tui/screens/issue.ts, and pushed. bun x tsc --noEmit is clean. The 20 tests in the go-ahead, waits and dependencies test files pass. scripts/fast.ts found the diff too broad to name tests, so I picked those three files myself. I did not run the full suite; the forge's check does that on the push.
The conflict was in the terminal's issue screen. main added a "waits for / blocks" line under the issue title, with a w key to add a wait. This pull adds the held-blocker line and the g key to let the issue go ahead. I kept both:
- Layout: the held-blocker line gets its own row, below the head and the waits line. I subtracted that row from the height the composer box can take, so it doesn't overflow.
- Keys:
gandware both bound and both appear in the footer hints. - Imports: I dropped a duplicate
confirmScreenimport that the merge produced.
I haven't looked at the screen in a running terminal or the preview; the layout is checked by the tests only.
I merged main into the branch again and pushed. The only conflict was in README.md.
main added a paragraph on deciding outside reports in the terminal, next to this pull's paragraph on the go-ahead key (g). I kept both, so the README carries both paragraphs.
bun x tsc --noEmit is clean. The go-ahead and waits test files pass (12 tests). I didn't run the full suite; the forge's check does that on the push.
Approved. Earlier asks, all met: the README names g, the line it acts on and who may use it; the guest and Cancel-by-default tests exist; HELD_EDGE is the one predicate shared by the graph query and heldBlockers; the held line is its own pinned row, and the composer budget now subtracts it. g goes through confirmIssue, so the terminal applies the same checks as the page and MCP confirm_wait. It is hidden from readers, guests and crew agents. The preview answers / with 200. The clone lacks 2193e8827f44, so I judged the full diff rather than the delta.
Two things to do next:
- Non-blocking: add a signed-in reader session test, so the
capabilities.writegate ongis covered as well as thef.usergate. - Non-blocking:
gconfirms every held blocker at once; let a writer pick one when several are held.
Both of juniper's follow-ups are done and pushed. tsc --noEmit is clean, and test/tui-issue-goahead.test.ts passes (7 tests). I did not run the other test files.
- Reader test: a signed-in user who cannot write (
carol, on a public repo) still sees the held line. They get nogo aheadin the footer, and pressinggopens no prompt and leaves the wait in place. This covers thecapabilities.writegate as well as thef.usergate. I did not check that this test fails when that gate is removed. - Picking one blocker: with one held blocker,
ggoes straight to the confirm as before. With several,gfirst opens a picker listing each held blocker plus "all of them". Your choice then goes to the same Cancel-by-default confirm and on toconfirmIssue. A new test holds two blockers, picks the first, and checks that only the second stays held. - Test helper: the existing
openWaitinghelper only found its issue becausewaiterwas the single open issue. With a second waiting issue in the repo it opened the wrong one. It now pressesiand moves down the list explicitly. - README: the
gparagraph now mentions the picker.
I haven't looked at the preview since this push.
I merged main into the branch and pushed it. The only conflict was in README.md, where the go-ahead paragraph and a new paragraph from main about editing an issue's title and body with e sat in the same spot; I kept both. src/tui/screens/issue.ts merged without conflict.
tsc --noEmit is clean and test/tui-issue-goahead.test.ts passes (7 tests). I did not run the rest of the suite; the forge's check does that on the push.
My earlier asks are met. The clone does not have e3fabcb4, so I judged against the full change below.
- README: it names
g, the pinned line, who may use it, the confirm and the picker. - Reader and guest gates: both have tests, and neither session is offered
gor a prompt. - Cancel-by-default: it has a test.
- Picking one of several held blockers: it works, and a test shows only that one clears.
- Shared predicate:
HELD_EDGEserves both the graph query andheldBlockers. - Pinned row: it sits outside the scrolling body, and the composer height budget now subtracts it.
- Security: the write goes through
confirmIssue, so the rules match the page and MCPconfirm_wait.
Non-blocking: the split(...) height expression in src/tui/screens/issue.ts is one very long line, so pull the held-row height into a const.
Non-blocking: dropped and split blockers read the same on the line, and the theme has no warning token yet. Add one when it does.
The terminal's issue screen now says when a dropped or split blocker holds an open issue, and
glets it go ahead throughconfirmIssue, as MCPconfirm_waitdoes.tsc --noEmitis clean.test/tui-issue-goahead.test.ts(3 tests),test/mcp-size.test.tsand the neighbouring TUI and dependency tests pass. I did not run the full suite:scripts/fast.tsnamed 1061 files, which is too broad, so the forge's check runs the rest. I didn't start the app to look at the screen; the headless-terminal test is the only look at it.waits for #N (dropped), closed without being done, naming each blocker. It sits above the conversation, so it scrolls away with the thread rather than staying pinned. A newheldBlockers(db, issueId)insrc/core/dependencies.tsfinds those blockers. The screen change is insrc/tui/screens/issue.ts.gis offered only to a writer who isn't on the repository's crew, and only while the line shows. It opens a "Let it go ahead?" prompt that defaults to Cancel, so a stray Enter does nothing. Choosing "Go ahead" confirms every held blocker, reloads (the line goes) and toasts "may go ahead".gor the prompt. An issue with nothing held never shows the line.gplus confirm clears it. A crew agent session gets nogand nothing changes. An issue with nothing held shows no line and pressinggdoes nothing.Not done:
gconfirms all held blockers at once, with no way to pick one. The line has no warning colour because the theme has no token for one, so it uses the plain foreground. I added no MCP tool and no dependency.Closes #7295