유대선
프로젝트로
·사용성 회고·2

Work Console: we wrote 'no wall of agents' as a rule, then rendered one

Talkak's surface map made 'don't open as a wall of agents' a Product Rule, and the Work Console did become the default human entry — but the cards it renders still lead with node IDs, commit hashes, receipt IDs, and pane sources. The intent landed in docs faster than in the screen.

The wedge for Talkak was never the agents. It was supposed to be the work: a solo founder opens the app and sees "what needs me now?", not the orchestration machinery underneath. On 2026-06-19 I wrote that conviction down as a hard constraint in docs/product/ui-ux-surface-map-and-status-2026-06-19.md, under a heading literally named Product Rule:

Talkak should not open as a wall of agents, workers, JSON, panes, or registry records.

The doc goes further. It sets a default order — work the user understands first, approvals second, evidence third, internal operator machinery only when explicitly opened. It records that Work Console is now the default startup page (StartupView -> WorkConsoleHost), that Mission Control was demoted to "Advanced operations," and that job areas (Marketing, Customers, Screen Factory, WorkItems) lead the page. On paper, the agent wall is gone.

The screen disagrees.

Reading apps/desktop/src/home/WorkConsole.tsx (the file WorkConsoleHost.tsx renders), every card is built by cardFromNode, and its evidence array is:

node.node_id,
node.evidence?.hash ? `commit ${node.evidence.hash}` : "",
node.evidence?.repo_root ? `repo ${node.evidence.repo_root}` : "",
stringField(record, "uri"),
stringField(record, "transcript_path"),
stringField(record, "runner_bridge_receipt_id"),
stringField(record, "mission_control_verification_run_id"),

The CardList renderer then prints card.evidence.slice(0, 2).join(" · ") on every row, plus a meta line of card.source and card.actionLabel. So a typical "What needs me" card shows, right under its title: a raw node_id, a commit <hash> or a runner_bridge_receipt_id, then a source like "claude pane" and a button labeled "Open WorkItem." The agent-session cards from cardFromPane are worse — titled "Agent pane 3f7a is working," sourced "claude pane," carrying the transcript path. The page is organized by job at the top (the area-grid buttons are real, and Mission Control genuinely sits behind a <details>Advanced operations</details>), but the moment any actual work exists, the body fills with exactly the registry records the Product Rule forbids.

This is the honest gap: the rule lives in a document committed the same day (2148ee3, 7b634fc), and the rule is correct. But the rendering code — last touched in the same wave — still treats node IDs and receipt IDs as the primary sub-detail of every card, because that data was the easiest thing to surface from the graph model. Intent moved to the doc layer; execution stayed at the model layer. The doc even anticipates this in its own UX Rule 10 ("distinguish actual running demo captures from proposed/branch-only UI"), which is the right instinct, applied to screenshots but not yet to the IDs the live page prints.

What I'd actually fix: evidence should default to a human phrase ("from your Gmail thread," "verified by 4 passing tests") with the raw IDs collapsed behind a "details" affordance — the same <details> discipline already used for Mission Control, applied one level down to the card body. A rule that the build doesn't enforce is a comment, not a constraint. Writing it down was the cheap half; the expensive half is making the default render path incapable of showing a wall of agents, even when the data tempts it.