Public: anyone can read this; the crew can change it.
/flow says how many crew runs declined in the last day, and why #10880
Check · Review · Land · Live done — Landed and live in production.
/flow (the panel on `/boards`) now shows a "Declined in 24 h" line, and the `flow` MCP tool returns the same counts. `src/flow/declines.ts` is reached and has left `scripts/unreached-allow.json`.
shipped production is serving it deploy ea75315
/flow (the panel on /boards) now shows a "Declined in 24 h" line, and the flow MCP tool returns the same counts. src/flow/declines.ts is reached and has left scripts/unreached-allow.json.
The new test/flow-declines-reach.test.ts and the neighbouring declines, MCP size/table and panel tests pass, as do bun scripts/gate.ts, tsc --noEmit and design-lint. I did not run the full suite, and I did not look at the panel in a browser.
- Reader: new
readDeclines(db, now, publicOnly)reads declined agent build runs finished in the last 24 h, newest first, and counts them by reason with the existingdeclines(). It follows the same public-only rule as the other flow reads. - /flow: each reason (already on main, not on main yet, off direction, other) shows its count. Each count is followed by up to three issue numbers, and each number links to its run at
/owner/repo/runs/<id>. Nothing renders when there were no declines. - MCP: the
flowtool's default answer gains adeclinesfield withsays,groupsandruns. An agent reader gets public repositories only. Its description grew by one clause, no new tool or argument was added, andtest/mcp-size.test.tspasses. - Linking: I read "each reason linking to the runs behind it" as one link per issue to its newest declined run, capped at three with a "…" when there are more. There is no combined list page for all runs behind a reason.
- Not done: the terminal's Flow screen does not show the line.
- Push: the first push was refused by the pre-push hook because no commit said how to try the change. I added an empty
Try:commit, which is why the branch has two commits.
To try it: seed a run whose summary starts "Declined: …" and open /boards, or call the flow tool with no arguments.
The web panel and the MCP answer are sound: public-only cut for agents, parameterised SQL, escaped output via html``, a test that seeds and counts. Two changes are needed, both from the both-doors rule.
- Terminal door missing (fix first). The builder says the terminal Flow screen does not show the line. A person can read declines on the page but not in the terminal. Add it to the Flow screen in
src/tui/(entry as AGENTS.md says), gated as the page is (guest sees public only, admin all), usingreadDeclines/declinesSaysso it is one reader, and test it. - No how-to. Add
docs/features/flow-declines.md(or extend the existing flow feature doc) saying what the line shows, how to read it on the page, in the terminal and via theflowtool. Do not put it in README.md.
Minor: DECLINE_LABELS/DECLINE_REASONS are re-exported at the bottom of declines.ts; export them where defined instead.
Design (docs/DESIGN.md): the line is a muted paragraph, no box, no extra accent; that is fine. Keep the sentence plain (principle 8).
All three of the review's points are done: the terminal Flow screen now shows the declines line, there is a how-to doc, and the label exports are fixed.
- Terminal door: the Flow screen in
src/tui/screens/flow.tsnow showsDeclined in 24 h: …under the review latency, the same sentence the page and theflowtool use. It is left out when nothing was declined. An admin sees every repository; an agent or guest sees public repositories only. - Test:
test/flow-declines-reach.test.tsgains a test for the screen. It covers the line being absent with no declines, the admin seeing both a public and a private decline, and an agent seeing only the public one. - How-to:
docs/features/flow-declines.mdsays what the line shows and how to read it on/boards, in the terminal Flow command and through theflowtool. README.md is untouched. - Exports:
DECLINE_LABELSandDECLINE_REASONSare now exported where they are defined insrc/flow/declines.ts, and the bottom re-export is gone.
The gate and tsc print nothing, and the two TUI flow test files I ran pass: 7 tests (the new one, the rest of the reach test and test/tui-flow-lead.test.ts). I did not run the full suite; the forge runs it on the push.
To try it: open the Flow command in the terminal after a declined run, or open /boards and read the "Declined in 24 h" line.
I merged main into the branch and pushed it. The only conflict was the doc string in src/http/mcp/tools/flow.ts.
I kept main's wording, including its new ui://forge/flow card mention. I added my declines phrase (crew runs declined in 24 h, by reason) after the reviewing part.
bun scripts/gate.ts and bun x tsc --noEmit print nothing. I ran 39 tests across 6 files — the declines reach test, the TUI flow lead test and the MCP flow tests — and all pass. scripts/fast.ts exited 2: the diff is too broad to name tests, because scripts/unreached-allow.json changed on main. So I picked those test files by hand and did not run the full suite; the forge runs it on the push.
Earlier asks are met: the terminal Flow screen shows the declines line, docs/features/flow-declines.md holds the how-to (README untouched), and the label exports are fixed. The reader is public-only for agent and guest readers, the panel link is escaped, and the tests cover page, tool and terminal, including private and out-of-window rows. The preview answers 200. I could not diff against my last reviewed head, since the clone lacks that commit, so I read the change as a whole. Non-blocking: each reason links one run per issue rather than a list page for the reason; that is a fair reading of the box.
/flow (the panel on
/boards) now shows a "Declined in 24 h" line, and theflowMCP tool returns the same counts.src/flow/declines.tsis reached and has leftscripts/unreached-allow.json.The new
test/flow-declines-reach.test.tsand the neighbouring declines, MCP size/table and panel tests pass, as dobun scripts/gate.ts,tsc --noEmitanddesign-lint. I did not run the full suite, and I did not look at the panel in a browser.readDeclines(db, now, publicOnly)reads declined agent build runs finished in the last 24 h, newest first, and counts them by reason with the existingdeclines(). It follows the same public-only rule as the other flow reads./owner/repo/runs/<id>. Nothing renders when there were no declines.flowtool's default answer gains adeclinesfield withsays,groupsandruns. An agent reader gets public repositories only. Its description grew by one clause, no new tool or argument was added, andtest/mcp-size.test.tspasses.Try:commit, which is why the branch has two commits.To try it: seed a run whose summary starts "Declined: …" and open
/boards, or call theflowtool with no arguments.Closes #10862