doneSuggestion does not render today“Countersigned copy attached. Nothing further needed from your side.”
“Perfect — §4 as agreed. Invoice goes out Monday.”
“Countersigned copy attached. Nothing further needed from your side.”
“Perfect — §4 as agreed. Invoice goes out Monday.”
Redrawn from the shipped code and a live simulator capture — BoardView,
ZoneTileRow, MatterRowView, BoardPresentation.
No JavaScript. Theme and lane are radio inputs read by :has(). The rows are
static markup. The published mock-ups sit behind a strict CSP and inline script has been blocked
in practice — a board whose rows only exist once a script runs renders empty, which is the one
failure a board mock-up must not have.
Three lanes. Zone.Kind is needsYou · waiting · done; the third
tile is titled Done and counts “0 closed”. Colour lives in the glyph only.
While the inbox is still being read the strip sits between the console and the
rows, and it does not change when you switch lane — BoardView keeps it
outside the lane swap because ingest fills every lane, so the line is true on all three and
re-running it per tile tap would only make it flicker. Two forms, both from
BoardTailCopy: with a known remainder, “Still reading your inbox — 4,568 emails
to go.”; without one, “…more matters may land.” The counts on the tiles keep rising
underneath it.
Done proposal — the suggestion. The proposal already exists
(MatterLifecycleProposal) but only on the Matter page, so today you must open a
matter to learn the agent thinks it is finished. The Board should point, not decide.
Recommended: one strip per lane — “3 look finished · Review →” — plus a sage rail
in the gutter of the rows it means, so a scan can see WHICH. Tapping it runs a focused pass
over just those, using the card that already exists, with its own words: Looks finished,
Not yet, Mark done. No new vocabulary, and one piece of chrome for N proposals
rather than N decorations.
Rejected: a third line on the row. The two-line rule allows exactly one exception, and
📎 Owed earns it by marking a step the agent cannot do. A Done proposal is
the opposite — something it can do, pending your nod — so it must not claim the same licence.
Rejected: a ✓ in the title line, which is what this mock-up drew first. Two faults.
A tick beside a title reads as completed, and these matters are only proposed —
on the same screen the Done tile says “0 closed”, so the mark contradicted the console beside
it. And MatterRowView gives the title lineLimit(1) with a
Spacer before the age, so a glyph in that line takes width from the title: “Instill
AI — Gartner settlement” truncated in this lane and not in Needs-you, making one matter read as
two. The rail costs no width and asserts no state.
Three proposals at once — the pass. Nothing today puts them together:
MatterLifecycleProposal is per-matter, the card renders from
page?.doneProposal (singular) inside MatterDetailView, and the only
endpoint resolves one — matters/{id}/lifecycle-proposals/{pid}/resolve. So the
strip’s “Review →” needs a destination, and a cross-matter list endpoint to feed the count.
Proposed: the Focus deck, seeded with the proposed-done matters. The machinery ships
— FocusSession already has commitDone() and
undoLastCommit() “for a verdict the server refused”, and the deck already reserves
↑ for done, to the point that DossierCard refuses a scrollable body because
“scrolling could commit ↑ done”. One card per proposal: the reason, and the messages it rests
on. The proposal type exists “because the ADR forbids proposing Done on silence alone”,
so the pass shows that evidence rather than a bare verdict.
Rejected: a list of three with a Mark all done button — it lets you accept three
conclusions without reading the evidence for any, which spends the very thing the proposal is
built on. Three cards is a ten-second pass.
One reason, many matters — so the evidence is the content.
reviewReason is a constant: REVIEW_REASON in
settled-matter-proposal-runner.ts is one sentence reused on every proposal —
“Every Thread in this Matter has been judged and none is outstanding — nothing is waiting on
you, and nothing is waiting on anybody else.” Three proposals therefore carry three identical
sentences, and the only thing that tells them apart is evidenceMessageIds. That
turns citing the messages from a nicety into the whole informational content of the card —
which is why the card here renders them and the shipped doneSuggestion should
too. Without them a pass of three is the same sentence three times.
Both views are therefore laid out the same way and say the same words: Why this matter
(the matter’s own summary, page.whyThisMatter, identical in both), then
Looks finished owning the reason, then the messages, then Not yet · Mark
done. Only the container differs — inline in the case-file, dealt in the deck. An earlier
draft of this mock-up put the proposal’s reason under the “Why this matter” heading, which made
one label mean two different things across the two screens.
Two edges: a proposal can be resolved from its case-file mid-pass, so the deck must skip an
already-resolved card rather than error; and the deck deals in the board’s row order, or the
rails and the pass disagree about which three.
The dock is an island. A floating pill carrying Board · Reading · More, with search as its own circular button beside it — not a full-width bar pinned to the edge.
Two text lines, one exception — title + age, decision clamped to two, and
📎 Owed: third only when an attachment is owed. Avatars are rounded squares, and a
row with no resolvable person shows an empty tile rather than invented initials.