Cover 1 / 1 ←→ step   1-0 jump   P play   H hide

ASB · Settings and Dashboard redesign · round 2, for Brian's approval

Every screen has one job, every list has a detail, and every control has one home

Round 2 answers Brian's six points on round 1, plus the ten changes the adversarial review asked for. No code has changed. This file is the explainer and the clickable mockup in one. Branch design/settings-redesign, src/ read-only.

How to read this. Scroll, or step with the arrow keys: each explainer section is one step, then each mockup scene is one step. 1 to 0 jump, P plays through, H hides the presenter bar. In the mockup every control does something; nothing is a dead button. Pick a comment pin anywhere: it lands back on the same tab, pane and record.

1 Brian's six points, and where each is answered

Each row names the change, the section that explains it, and a button that puts the mockup on the screen that shows it.

#Brian saidWhat round 2 doesAnswered in
1About must have a link to read the changelog.About gets a What's new card built from origin/feat/about-changelog (the running version open, older ones folded), and a Read the full changelog link that opens the bundled CHANGELOG.md in the viewer. The update notice links there too.
2Dashboard, Tree must be two panes like Windows Explorer.Tree on the left, the selected project on the right. Expanding and selecting are two gestures. Full keyboard navigation, a resizable divider, and a pinned row when the selection is filtered out. Tested at Brian's scale: 166 projects, 7 levels.
3Dashboard tabs have no detail pages; Usage is completely empty.Every tab is a list plus one shared detail component, Today included (as a sheet). Usage gets Spend over time, tokens by type, by model, by routine and by command, a budget, and Hours, each with a drill-down. The empty Usage tab had a real cause, named below.
4Organise Dashboard (and System) and Settings by what the user wants to achieve.Nine goals, one home each. Settings nav grouped by goal: Get set up, Let the AI do my work, Keep my data safe, This app. Settings holds the control; System holds the status. Meetings get one home. Follow-ups fold into Work.
5Where does the Output menu go?A chat-level side panel, opened from the Outputs button in the chat header or Ctrl+Shift+O. Today, Recent outputs reads the same index. Not a Dashboard tab, not a Settings pane.
6The mockup must carry the artifact-comments adapter.window.ArtifactComments with state, restore, isCurrent, search, label and pause, over the app's area, tab, pane, selection, segment and data set. The publisher adds the comments script; this file carries none.

2 Why Usage looked completely empty

Dashboard Usage tab before, with the error toast

One unguarded field blanks the whole Dashboard

The toast in the screenshot reads Cannot read properties of undefined (reading 'sessions7d'). renderUsage() (main.js 22950) and the Today momentum card (main.js 21624) read summary.sessionStats.sessions7d with no guard. When the field is missing, the read throws, and every tab renders nothing.

The same capture shows "vundefined is available" (main.js 1777). Both come from the screenshot stub, which returned an incomplete summary. So the Today, Usage and update-banner screenshots are invalid as evidence and are marked that way in the Before toggle.

Fix, as an acceptance test on PR 6: each card renders inside its own guard. A throw in one card blanks that card only, with an inline "Couldn't load" and Retry. Then before/ is re-shot against a complete stub or the real app.

2b What changed since round 1, and what the review changed in PROPOSAL_v2

Kept from round 1
Page anatomy, the chip vocabulary, theme-safe colour roles, the connect dialog stepper, Connected tools rows and tiles, the copy rules, the fixed modal. Ids never change: every move is a DOM move, so the jsdom suites and tools/app_source.mjs keep resolving.
Reversed from round 1
"Tabs stay as they are": the tabs stay, the panels change shape. "GitHub sync and Chat backup stay on System as action cards": they stay as status rows with Run now; their set-up moves to Settings, Files and backup. The read-only Chat history row in Files becomes the control.
#Review finding, and the fix in this mockup
1No ledger write commands exist (only ledger_find, ledger_list). Every Work and Inbox action seeds the chat; the assistant writes behind its gates. A chase is stamped only once sent.
2Follow-ups has a drawer, Draft the chases, Show closed too and #fuScope. Work carries all four and reuses the drawer.
3Usage emptiness diagnosed (section 2); render isolation is a PR 6 test; before/ re-shoot required.
4No "$84 this month" chip; Today shows no cost. Cost labelled API-equivalent. Budget only with a per-token provider, by calendar month.
5Meetings get one home. Settings nav grouped by goal. A goal-to-surface check per goal (section 3).
6First-week data set: a "Get your first result" card, empty states that say how they fill, plain labels, optional setup out of the badge.
7Outputs index covers script writes and published links, persistent and incremental, scoped to the active workspace. PR 11 risk is High. Default scope is decision 3.
8Today opens a detail sheet. Counts derive from lists. Real tree kinds. A heavy data set at Brian's scale.
9"Read the full changelog" link. The branch already folds older releases and does not touch setup_tools.css; it is 18 commits behind and rewrites CHANGELOG.md, so it is rebased first. Sixteen PRs, numbered 0 to 15.
10Adapter compares every saved field; tree state stores one node, not a list; search restores the start; no hand-written script tag.

3 Information architecture from user goals

A control lives where its goal starts, not where its code shipped. Solid line: the one home. Dashed line: an allowed entry point that opens the home.

G0Get a first result (first week)Today, starter card G1See what needs me nowToday; Inbox is an entry G2Work promises, chase replies, decideWork (Follow-ups folds in) G3See the shape of all my workTree, two panes G4Find what the AI producedOutputs panel, chat header G5Capture, write up, review a meetingMeetings view, one home G6Know what the AI costs meUsage; status bar is per session G7Make the AI able to do my workSettings group; checklist is the spine G8Keep my data safe, the app healthyControl in Settings, status on System Dashboard: read daily, act on one record Today digest, opens a detail sheet Inbox notes the sweep filed Work owe, waiting, decisions to make Tree two panes your work above, this app below Usage spend, hours System schedules and health, status only Chat: the chat in front of you Outputs panel This chat / All chats Status bar this session's tokens and cost Top-level views: do now, on a clock Meetings 1 capture, 2 write up, 3 review Settings: set once Get set up Setup checklist, Account Let the AI do my work Models, Agents, Tools, Phone Keep my data safe Files and backup This app Appearance, Sounds, About

Goal to surface, checked one goal at a time

G0Get a first resultOpen the app, Today shows three starter actions, the first one seeds a brief, the file lands in Outputs.One home: Today.
G1See what needs me nowDashboard badge, Today, Needs you. Each row opens its detail as a sheet. Optional setup never counts.One home: Today.
G2Work promises, chase, decideWork lists You owe, Waiting on others, Decisions to make. The detail seeds the chat for every change.One home: Work. Follow-ups view folds in.
G3See the shape of my workTree, select a project, read it on the right, Show in Work filters the records.One home: Tree.
G4Find what the AI producedOutputs button or Ctrl+Shift+O, This chat or All chats, click a row for the viewer, Go to chat.One home: Outputs panel.
G5Capture, write up, reviewMeetings view: 1 Record, 2 Write it up, 3 Review the note. No second list on the Dashboard.One home: Meetings view.
G6Know what it costsUsage, Spend: per day, per model, per routine, budget when billed per token. The status bar keeps this session only.One home: Usage.
G7Make the AI able to workSetup checklist, Fix, lands on the exact card: a tool tile, a provider, an agent, phone access.One home: Settings, Let the AI do my work.
G8Keep data safe, app healthySet up backups and sync in Files and backup; check them on System with Run now; updates and help in About.Control: Settings. Status: System.

Settings holds the control, System holds the status

ThingSettings (control)Dashboard, System (status)
Folder backupFiles and backup: schedule, Back up nowRow with last run, next run, Run now
Chat history backupFiles and backup: switch, repo, Restore from backup and Undo last restore (session_backup_pull, session_backup_undo, which had no home)Row with last run, full error, Run now; Set up deep-links to Settings
GitHub syncFiles and backup: repo, branchRow with last sync, Run now, and conflict dismissal (sync_dismiss_conflict, which had no home)
AccountAccount: sign in, membershipRow: registered, WhatsApp verified, Re-verify
AI providersModels: providers, default, monthly ceiling (per-token providers only)Row: each provider, key, last good call
Setup checklistThe first-run subset of System health, same checks, required items only in the badgeEvery check, always

4 Where every existing control goes

Ids do not change; every move is a DOM move. Filter by an id, a pane or a word.

Today (pane, control, id)TomorrowNote

5 Where Outputs goes

Mocked on 26 Sep (docs/mockups/outputs_panel_mockup.html) and never built. Round 2 places it and specifies the index it needs.

Placement
A chat-level side panel, from the Outputs button right of the chat name and Ctrl+Shift+O. It stays open while the agent works and shows NEW as files land. It is the existing viewer with a list in front, so one panel has two modes. Dashboard, Today, Recent outputs reads the same index; its See all opens the panel on All chats. Not a Dashboard tab: that loses the chat context and the stay-open behaviour.
The index it needs (critique 7)
A persistent, incremental index per workspace, not a scan on every open (token_usage already truncates at 4000 files). Fed by Write, Edit and NotebookEdit events, plus a workspace mtime diff per turn for files a Bash script wrote (make-pdf, exports), plus the URL a publish step returns (Drive, merit-artifacts.pages.dev), plus the tool names non-Claude runtimes use. "All chats" means the active workspace, which can differ from a session's own (workspace_root_for).

Default scope is a decision (decision 3): the 26 Sep mockup defaulted to All chats; round 2 recommends This chat from the chat header, because "what did this chat write" is the common question.

6The clickable mockup

One app window. Pick a scene, or just click around. Data switches between a typical week, a first-week member and Brian's real scale. Billing switches how the AI is paid for. Cards shows each Dashboard card loading or failing on its own. Before shows the screenshot of the same screen today.

Data
Billing
Cards
AI Second Brain 1.2.0

7 The comments adapter

A pin made on Dashboard, Work, WAIT-0118 must land there for the next reviewer, not on whatever is on screen. This file defines window.ArtifactComments per .agent/skills/artifact-comments/docs/adapter.md.

state() explainer pin: {x:1}. App pin: the fields that decide what the app shows, and only those: {d: data set, a: area, b: before, t: tab, s: selection, g: Usage segment, pay, us, um, p: Settings pane, cd: connect step, c: chat, o: Outputs mode, sc: scope, os: file, oq, ot, oc, wn, wq, wo, wc: Work filters, tf, tq: Tree filters, mf: Meetings filter, ov: viewer overlay, tn: the tree row clicked, when it is not the selection}. Well under 600 characters. restore(s) stops Play, rebuilds the app from s, expands the ancestors of s and tn, resolves on the next frame. isCurrent compares every saved field, so a pin on Spend never shows on Hours, or on another scope, data set or drill-down. A tn pin also needs its row on screen. search(t) walks about 400 states (every scene, tab, pane, record, day, model, routine, file), with the tree fully expanded; restores the starting state when nothing matches. label(el) the nearest data-ac-label, for example "Dashboard › Work › detail › WAIT-0118". pause() stops Play.
Publishing. Name the ARTIFACTS entry ASB settings redesign v2, which slugifies to asb-settings-redesign-v2. The publisher injects the comments script with that slug and skips injection when a tag is already present, so this file carries no script tag: a hand-written slug that differs from the published one would split the threads. Fixture ids (WAIT-0118, logamjaya-contract, apple, 2026-10-03, claude-sonnet-5, daily-update) stay fixed across revisions, so a pin survives a restyle.

8 Rollout: sixteen PRs, numbered 0 to 15

#PRRiskDone when
0Rebase, then merge feat/about-changelog. 18 commits behind the design branch; rewrites CHANGELOG.md (379 lines changed). It already folds older releases and does not touch setup_tools.css.Lowabout_pane_test.mjs green after the rebase
1Tokens, buttons, chips, Routines placeholder (round 1)LowRound 1
2Fixed modal, nav grouped by goal, "Phone access" labelLowFour goal headings render; reopen-on-last-pane test green
3Pane anatomy, About cards (Updates, What's new card plus "Read the full changelog", Help, Diagnostics)Low-mediumThe link opens CHANGELOG.md in the viewer
4Copy pass, plain labels (Decisions to make, Overdue reply, project)LowNo "breached", "SLA" or "node" in user-facing copy
5Move controls: backup, chat history (with restore and undo), GitHub sync into Files and backup; Spending cardMediumEvery id in section 4 resolves
6Dashboard shell: dash-detail, per-card guard, loading, empty and error; retire #dashLoading and the toast; re-shoot before/MediumFault injection: a throw in one card blanks that card only
7Tree two panes, keyboard, resizer; ledger_list gains node; work_tree_node_filesMediumKeyboard table passes; usable at 166 nodes, 7 levels
8Work and Inbox details via ledger_find and the ledger_link.js drawer; actions seed the chat; Meetings view gains Review; Dashboard Meetings tab retiresMediumNo app-side ledger write exists; a chase is stamped only after it is sent
9Usage: Spend, Hours, Budget, by model, by routine and command, drill-downsMediumUnpriced models never show $0.00; budget is a calendar month
10System details, nudges, notices, Dashboard badgeMediumBadge equals Needs you rows; optional setup excluded
11Outputs panel and the persistent indexHighScript writes and published links appear; Today and the panel agree
12Connected tools layout (round 1 PR 7)Medium-highRound 1
13WhatsApp sheet and custom MCP sheet (round 1 PR 8)Medium-highRound 1
14Connect dialog stepper, agents merge (round 1 PR 9)HighRound 1
15Follow-ups redirect (decision 1)LowThe tab lands on Work with the drawer, Draft the chases, Show closed too and the scope line

Backend additions, listed once: ledger_list accepts node (the only ledger change; no write commands); work_tree_node_files(id); a persistent outputs index; routine_usage() and routine_runs(jobId); token_usage_day(day) and a calendar-month window; a monthlyCeilingUsd setting; walk_listing returns its error instead of [].

9 Decisions for Brian

Four calls. The recommended option is first in each, and the mockup is built on it.

1. Fold the Follow-ups view into Dashboard, Work?

Follow-ups reads the same three ledgers as Work. It has a row drawer (ledger_link.js), a Draft the chases button, a Show closed too toggle and a line naming the workspace that answered. Work in this mockup carries all four and reuses the same drawer.

RecommendedFold it. The Follow-ups tab redirects to Work for one release, then retires (PR 15).
Keep both views. Two read-outs of the same records stay, with two places to fix every bug.

2. Where do meetings live?

Round 1 split capture (Meetings view) from review (Dashboard, Meetings). The review called that the "scattered" you named.

RecommendedOne home in the Meetings view: 1 capture, 2 write up, 3 review. The Dashboard Meetings tab retires; Today keeps one pointer row. Shown in this mockup.
One home in Dashboard, Meetings, with Record inside it; the top-level Meetings view retires. Recording then starts from a read-mostly surface.

3. Which scope does Outputs open on?

The 26 Sep mockup opened on All chats. Round 2 opens on This chat from the chat header.

RecommendedThis chat from the chat header and Ctrl+Shift+O; All chats from Today, Recent outputs, See all. The panel remembers the last scope per chat.
Always open on All chats, as on 26 Sep. Simpler, but the common question, "what did this chat write", needs a click every time.

4. Where does cost show?

PROPOSAL_v2 added a "$84 this month" chip and kept a cost on Today. That made six read-outs, and the chip said "this month" over a rolling 30 days.

RecommendedTwo places: the status bar for this session, Usage for the workspace. Costs labelled API-equivalent on a subscription; a calendar-month budget only with a per-token provider.
Keep a header chip as a shortcut to Usage, labelled "API-equivalent, 30 days", and drop nothing else.