Public: anyone can read this; the crew can change it.
Bulk asks: select many, preview, act once, undo — on the page, the API and the MCP #735
Check · Review · Land · Live done — Landed and live in production.
Closes #690
shipped production is serving it for issue #690 — its issue is already done deploy 3a0f5c8
Closes #690. Stacked on #719, which is stacked on #692; review those first. This pull's own changes are the last two commits.
What changed
- One shape, reused. A bulk action on asks is a fleet operation (#465).
actions/fleet.tsgains a plan over rows named by id (previewFleetIds/applyFleetIds), next to its plan over a query. Both go through the sameplanOver, the same per-row admin check and refusal, the same receipt and the same undo.actions/asks_bulk.tsturns ask ids into the issues and pulls they are about. Asks that no longer ask, ceilings and planner declines are listed as skipped, never dropped. - New fleet verbs in
fleet/verbs.ts:
- ship: the asks' own merge, with the conflict handed to the pull's agent. It is not undone.
- dismiss: personal. It is the actor's own cause-aware dismissal, and only the actor can undo it.
- replan: assigns the repository's planner. Refused on a public repository, where a crew assignment lets any reader steer the run (#619), and refused for pulls.
- close already existed.
assign became a named constant so replan can reuse its checks.
- Page:
/asksgets a box per ask, "select all" on a collapsed row, and one action bar.POST /asks/bulkshows the preview (each row before → after, what is refused or skipped and why, whether it can be undone). Doing it shows the receipt with an Undo. - API:
POST /api/v1/asks/bulk {action, items, preview}. A preview is the default and needs only ro; acting needs rw.POST /api/v1/asks/bulk/:id/undoreverses only an asks operation; any other fleet receipt still needs the admin route. MCP: a newasks_acttool, which previews by default. - Not built: "mute this kind for this repository". Asks are never muted away (#688). A row dismissal already holds until something new happens, and stopping a repository's asks altogether is its autonomy setting.
Tests: new test/asks-bulk.test.ts (in GATE). The refusals come first:
- an outsider or plain reader acts on nothing
- a preview changes nothing; ro cannot act
- nobody else can undo; a second undo gets 409
- the asks' undo refuses a non-asks fleet operation
- an agent token cannot act
Then: a mixed batch acts on the allowed rows only, ship cannot be undone, replan is refused on a public repository and works on a private one, the page flow (preview → do → undo) works, and MCP previews. The fleet-ops and mcp tests pass.
Verified: typecheck is clean. The full gate (taken under the lock) has 1 failure, crew.test.ts stand-in assignment, which also fails on main. Looks taken at 390 and 1280 px of the selection, the preview and the receipt.
🤖 Generated with Claude Code
Update: the bulk steps now stay on one screen. Ticking asks and pressing Preview puts the plan on top of /asks, with the picked asks still ticked. "Do it" lands back on /asks with the receipt and its Undo on top (/asks?op=<id>), and Undo lands there too. The separate preview page is gone: asks_bulk_page.ts was folded into asks_page.ts. Also merged the current #719, which includes main. Looks taken at 390 and 1280 px. Full gate under the lock has 1 failure, crew.test.ts stand-in assignment, which also fails on main.
Closes #690
Stacked on #719 (which is stacked on #692). Review those first.
Work in progress: select many asks, preview, act once, undo — on the page, the API and the MCP, as a fleet operation (#465).
🤖 Generated with Claude Code