Public: anyone can read this; the crew can change it.
An ask lives only while its cause does: stale asks expire, a dismissal holds until something new, one cause in one place is one row #692
Check · Review · Land · Live done — Landed and live in production.
Closes #688
shipped production is serving it deploy 76ab860
Closes #688 (full description; the body could not be edited through the API)
What changed
- Expiry. A green pull whose head conflicts with its base, or adds nothing to it, is no longer a "look" ask.
src/crew/stale_asks.tslearns this off the request path: a two-minute sweep, keyed by head and base tip, so a pull that has not changed costs two ref reads. If the answer is not known yet, the ask stays. The pull's own page still shows the conflict. - A dismissal holds until something new happens.
/asks, the header count, the board's "Needs you", the feed and the phone notifier now all skip an ask the viewer dismissed. It comes back when something new happens to it: a new check (meaning a new head), a new park, or a new UTC day for a ceiling pause. Before this, only the feed read dismissals, and there a dismissal lasted forever. A change's own page still lets you decide. - Collapse. Asks of the same kind in the same repository are one row ("cs: 3 green changes wait for your look"). On
/asksthe row is one card with a line and a Ship per pull. In the feed it is one item that links to/asks#<row>. Dismissing the row dismisses what it held at that moment. The count is the number of rows, so every surface agrees. The notifier compares by the asks a row holds, so a new ask under an old row still reaches the phone. - Removed: Mute app on ask cards in the feed. Asks are never muted away, so the button did nothing there.
Tests: test/asks-expiry.test.ts, added to GATE. It covers collapse on every surface, no Mute on asks, a row dismissal and its return, a single dismissal, and a conflict expiring after the sweep. The existing asks, feed, feed-page and notify tests pass.
Looked at: /asks at 390 px and 1280 px with 1 + 2 + 3 grouped asks. On a phone, row titles in a group are truncated to one line; wrapping them belongs to #691.
Local gate (after merging today's main, which added the planner's declined ask: it gets an id and cause time like the others): typecheck is clean. The gate has 1 failure, crew.test.ts (stand-in assignment), and it fails the same way on main locally.
🤖 Generated with Claude Code
Closes #688
An ask lives only while its cause does. Work in progress: the first commit learns, off the request path, which green pulls no longer merge as they stand.
🤖 Generated with Claude Code