🍊😺 obot Audit view redesign 2026-07-25 · design prototypes
Audit view Β· design prototypes

Thirty-three decisions,
one screen

The audit page reads well and decides badly. Three working prototypes turn the same findings into a table you can clear in a sitting β€” each takes a different position on where the reasoning goes when the rows get short.

Driven by the real ledger the nightly audit committed on 2026-07-25 β€” 33 live findings, 1 muted, 22 rules Β· decisions are held in the browser tab and nothing is sent to GitHub Β· companion to requirement #109 and PR #110, which is on hold pending this

Decided 2026-07-25 by @jwildfire

Option B ships, and a click dispatches immediately β€” the two answers that unblock PR #110. D3–D6 went to the recommendation in each case. The table below records all six. One consequence: the prototypes stage decisions and print the request; the shipped view will not β€” every βœ“ fires a run as it is clicked, and a rule band still sends one request carrying all of its ids.

What is wrong with the page today

Not the content β€” the format. Every finding is a card carrying its own copy of the rule's reasoning, so the page is written for a first read and paid for on every read after that.

Height of the queue
live page7,646 px β€” 9.3 screens
prototype1,682 px β€” 2.0 screens
Vertical space per finding
live page125 px card
prototype31 px row
Findings you can see at once
live page4
prototype16

Measured in Chrome at 1480 Γ— 812 on the deployed page and on Option A with the same 33 findings. The live page also carries 2,883 words and 77 buttons before you have decided anything.

The deeper problem is repetition. Ten of the thirteen rules that fired propose the same change for every finding they produce β€” eight identical "Assign @jwildfire", three identical "Set board Status to Released". The page asks the question 33 times when there are really 13 questions and a handful of exceptions.

What all three prototypes share

The forks below are about where the why lives. Everything else is settled and identical across the three.

decideconfwhich issuetitlewhat changeskind
medium roadmap#17 Requirement: rebuild safety.agent as a thin overlay… Resolve each open sub-issue: close the finished ones… judgment
decideβœ“ applies Β· βœ— mutes for 60 days
confrank as dots and a word, never colour alone
which issuethe subject, linked to GitHub
titlewhat the issue is, truncated
what changesthe proposal in the audit's own words
kinda listed operation, or a bounded agent
β–Έthe why: rule, evidence, exact operation or prompt

Three options

They differ on one question: when a row is 31 pixels tall, where does the reasoning go?

Option A

Ledger

One table for the whole queue, rule bands inside it, and details opening in place under the row they belong to.

best at
seeing the entire queue at once and deciding without moving
costs
an open detail pushes the rows below it down; reading several in a row is jumpy
try
the safe sweep, then βœ“ on the ASSIGNEE-MISSING band
Open Option A β†’
Option B Β· chosen

Rail

The same table, but it never changes shape. The selected row fills a rail on the right β€” arrow down the list and the reasoning follows you.

best at
the 15 judgment calls, where you must read a paragraph before deciding
costs
25rem of width, one finding at a time, and it collapses on a laptop screen
try
press j repeatedly and read down the queue
Open Option B β†’
Option C

Sweep

The rule is the unit of work. Its reasoning is stated once, the batch decision is the primary button, and the rows underneath exist for exceptions.

best at
turning 33 decisions into 13, in the order the rules fired
costs
no view of the whole queue; 13 page states instead of one
try
Accept all 3, then next rule β–Έ, four times
Open Option C β†’

What I recommended

Kept for the record. D1 went to B on its own rather than as a toggle on A.

Option A, with B's rail as a toggle rather than a rival. A and B are the same build β€” the same table, the same bands, the same sidebar β€” differing only in whether detail renders under the row or beside it. That is a preference, not an architecture, so it should be a control on the page and not a decision made once for you. Default to the rail on a wide screen, because 15 of 33 findings are judgment calls that need a paragraph read before they are decidable, and fall back to inline expansion below 76rem where the rail does not fit.

Take one idea from C immediately. When every finding under a rule proposes the identical change β€” ten of thirteen rules today β€” the band should say so once: all 8 Β· Assign @jwildfire. That single line is where most of the remaining reading disappears, and it turns the band's βœ“ from a bulk action into an informed one.

Do not ship C first. Its wizard is genuinely faster on a queue like tonight's, but it hides the queue: you cannot see that 13 high-confidence findings are one click away, and a rule you never step to is a rule you never decide. Worth revisiting once the compact view has been lived with for a week β€” it is a mode, not a replacement.

The six decisions, settled

Asked and answered on 2026-07-25. Every one went to the recommendation.

#QuestionDecidedWhy
D1Which view ships on /audit/?Option B Β· RailThe table never changes shape and the reasoning follows the selection β€” the 15 judgment calls are the ones that cost time
D2Dispatch per click, or stage?Per clickA decision leaves the browser when it is made; the tray and its payload preview come out. A rule band is still one request, because the payload carries a list of ids
D3May βœ— at the rule band mute a whole rule?Yes, confirm above 31–3 fires straight away; 4 or more names the count and the mute date first. Accept-all never confirms β€” an accept is visible the next morning, a mute is invisible for 60 days
D4Where does #109's activity log live?A fold under the tableRead after deciding, not during, so it never competes with the queue for vertical space
D5Default sort and groupingGrouped by rule, worst firstThe prototype default, kept
D6What happens to the long-form view?Rule reference onlyThe per-finding cards go; the 22-rule table and the quiet-rules list stay, because an empty audit and a broken one must never look alike
D7What the page shows between the click and the outcomeRow pill + one run panelThe row reads sending β†’ queued β†’ running β†’ βœ“ applied; a panel under the toolbar holds the run link and the outcome re-read from decisions.json β€” the page reports what the lane recorded, not what the click asked for

What this means for PR #110

The backend survives intact: repository_dispatch, the re-validation against a fresh audit, the ledger, the run polling. What changes is only the surface calling it: the card list becomes Option B’s table and rail, the accept and reject buttons move onto the row and the rule band, and the run reporting the PR already built stays as it is (D7). The connect-once token flow is untouched. D2 kept per-click dispatch, so the tray and its payload preview β€” the one behaviour these prototypes have that the shipped view will not β€” come out; a rule band sends a single request carrying all of its finding ids, which the lane already accepts.

What is not in the prototypes