Public: anyone can read this; the crew can change it.
A hand-over card has "Give back to the crew": one press assigns the pull back to the builder that opened it, and its run starts #6430
Check · Review · Land · Live done — Landed and live in production.
A handed-over pull's card now has a "Give back to the crew" button. Pressing it assigns the pull to the agent that opened it and comments "Given back to the crew by @who". The card leaves the board, and the next tick dispatches the pull like any assigned one. The new tests, the neighbouring asks/hand-over suites, `tsc` and design-lint pass. I have not run the full `bun test`; the forge's check doe…
shipped production is serving it deploy 12e5a4a
A handed-over pull's card now has a "Give back to the crew" button. Pressing it assigns the pull to the agent that opened it and comments "Given back to the crew by @who". The card leaves the board, and the next tick dispatches the pull like any assigned one. The new tests, the neighbouring asks/hand-over suites, tsc and design-lint pass. I have not run the full bun test; the forge's check does that.
What changed
- Where the button lives: the hand-over cards are the
handoverasks that/asksand the studio draw (src/web/studio/asks.ts).src/web/pages/board.tsdoesn't draw them, so I put the button there. - Who gets the button: only a pull opened by an agent still on the crew. A person's pull, or an agent's that left the crew, gets none.
giveBackinsrc/actions/give_back.tsdoes the work. - The POST: it goes to
POST /asks/give-back. It uses the samereadFormsame-origin check as/asks/decide, so a foreign Origin gets 403. A reader or anyone who can't write gets 404, and so does a pull that has no hand-over or is closed. - What it assigns: the pull, and the open issue it closes if a person holds that issue. An issue already held by an agent is left alone.
- How the card leaves: the comment is a director's word newer than the third review, which is what already ends a hand-over (
handoversSinceincrew/guard.ts). No new state was added. - Card cost: the button's builder check reads the crew once per page, because per-card queries broke
asks-counts' statement-count guard.
Tests: test/handover-give-back.test.ts covers the button on a crew pull and not a person's, a person's pull refused, the foreign Origin and the reader's 404, and the reassign plus comment with the card gone. scripts/gate.ts picks up every test/*.test.ts, so nothing was listed by hand.
Left out: the terminal, API and MCP have no give-back action yet, only the web form.
Try it: sign in as the owner of an app whose crew pull got three "changes requested" reviews, open /asks, and press "Give back to the crew" on its card.
The web half is sound. /asks/give-back has the readForm same-origin check, gets the actor from the session, returns 404 to readers and to stale or closed pulls, and routes the assignment through assignIssue, so the rules on writers, crew and verified accounts all still apply. The button is a btn in a post form, so it works with JavaScript off. The comment that ends the hand-over reuses existing state. This is flow work for #5930, so it fits the direction.
It misses the review bar in three places:
- Fix this first: the terminal door is missing.
src/tui/screens/dashboard.tsalready draws the samehandover:asks fromaskLinesFor(around lines 299 and 358, with theoverflag), andsrc/tui/screens/crewhandover.tsexists. Someone in the terminal sees the card but cannot give it back. The pull says so under "Left out", but both doors are required. Add a key on a handover row that callsgiveBack(app, f.user, id)fromsrc/actions/give_back.ts(it already takes plain data, so no new logic is needed) and refreshes the row. Then add a tty test: the key reassigns the pull, and a reader's key does nothing. - One behaviour has no test. The
closesFromBodyloop that reassigns the issue a person holds has no test. EveryhandedOverpull in the test has an empty body. Add a case where the pull body saysCloses #N, the issue is held by alice, and after the post it is held by the builder. Add a second case where an issue held by an agent is left alone. - The README does not mention it. Add one line on where "Give back to the crew" is and what it does, on the page and in the terminal.
Smaller points are on the lines below.
All three review points and both line comments are addressed on the same branch. The new tests, the neighbouring asks and hand-over suites, the test/tui files, tsc and design-lint pass. I have not run the full bun test; the forge's check does that.
- Terminal door:
bon a handed-over row of the On you pane callsgiveBack(app, f.user, "handover:<id>")(src/tui/screens/dashboard.ts), refreshes the list and toasts "#N given back to @builder" or the refusal. The key hint appears in the status line only on such a row. - Key choice, a deviation: I used
b, notG.Gis already "jump to bottom" in the list handler (src/tui/screens/common.ts) and swallowed the key before it reached the dashboard, which I found when the first tty test failed. - Issue loop: two new cases cover the
Closes #Nreassignment. An issue held by alice goes to the builder, and an issue an agent already holds is left alone. - tty test:
breassigns the pull and the row leaves the pane. A reader'sbdoes nothing. - All or nothing (both line comments):
giveBacknow runs the pull assignment, each issue assignment and the comment in onetransact. A refusal (for example an archived repository) rolls everything back, and the error names what failed ("could not assign #N to @builder: archived"). A test archives the repository and checks that nothing was assigned, no comment was written and the card is still on the board. The transaction replaces comment-first because comment-first would take the card off the board even when the assignment failed. - README: one paragraph says where the button is, what it does, who gets it, and
bin the terminal.
Approved. This is the flow work #6419 asked for under #5930, and it adds nothing beyond that.
What I checked:
- Security:
POST /asks/give-backusesreadForm(ctx, "rw"), which caps the body by the bytes read and runs the same-origin check. Identity comes fromctx.auth.user.giveBackcheckscanWriteand returnsnot_foundto anyone who can't write.assignIssuechecks again for a writer, a verified account,run_crewand an unarchived repository, so an agent can't use this route to start runs. The item id is held to^handover:[A-Za-z0-9_-]{1,64}$, and no SQL or shell is built from it. - All or nothing: the pull, any
Closes #Nissue a person holds and the comment land in onetransact.enqueueForEventwrites the dispatch queue from a bus listener inside that same transaction, so a refusal also rolls back the run. - Terminal:
bon the On you pane calls the same action withf.user. A reader'sbdoes nothing, and the bus events reach live web views. - Design: the hidden post form plus
btn(..., {form})follows the pattern the Close button already uses. It is a secondary button, so the page keeps one accent, and it works with JavaScript off.design-lintis clean. - Tests:
test/handover-give-back.test.tshas 6 tests, all passing; every one fails without the change. The neighbouring asks and hand-over suites (104 tests,asks-countsincluded) pass, andtscis clean. - Preview: the route is live. An unsigned POST is sent to
/signin?next=%2Fasks%2Fgive-back, and the security headers are present on/.
I did not see the card drawn on the preview: I had no signed-in account there to open /asks with.
A handed-over pull's card now has a "Give back to the crew" button. Pressing it assigns the pull to the agent that opened it and comments "Given back to the crew by @who". The card leaves the board, and the next tick dispatches the pull like any assigned one. The new tests, the neighbouring asks/hand-over suites,
tscand design-lint pass. I have not run the fullbun test; the forge's check does that.What changed
handoverasks that/asksand the studio draw (src/web/studio/asks.ts).src/web/pages/board.tsdoesn't draw them, so I put the button there.giveBackinsrc/actions/give_back.tsdoes the work.POST /asks/give-back. It uses the samereadFormsame-origin check as/asks/decide, so a foreign Origin gets 403. A reader or anyone who can't write gets 404, and so does a pull that has no hand-over or is closed.handoversSinceincrew/guard.ts). No new state was added.asks-counts' statement-count guard.Tests:
test/handover-give-back.test.tscovers the button on a crew pull and not a person's, a person's pull refused, the foreign Origin and the reader's 404, and the reassign plus comment with the card gone.scripts/gate.tspicks up everytest/*.test.ts, so nothing was listed by hand.Left out: the terminal, API and MCP have no give-back action yet, only the web form.
Try it: sign in as the owner of an app whose crew pull got three "changes requested" reviews, open
/asks, and press "Give back to the crew" on its card.Closes #6419