Skip to content

feat(redesign): one chat interface — flagship answer is chat-shaped, unified#583

Merged
HomenShum merged 8 commits into
mainfrom
feat/one-chat-interface
Jul 18, 2026
Merged

feat(redesign): one chat interface — flagship answer is chat-shaped, unified#583
HomenShum merged 8 commits into
mainfrom
feat/one-chat-interface

Conversation

@HomenShum

Copy link
Copy Markdown
Owner

Summary

Founder overrule executed: the flagship answer is chat-shaped, not a memo document. ONE ChatAssistantMessage component now renders in BOTH the live ChatSurface and the ReproducibleChatPage replay — the two-stack drift problem is structurally dead.

  • Prose leads — no "Short answer" / "Why useful" eyebrows; shortAnswer + whyItMatters flow as one body.
  • Risks + next-action are quiet inline notes (gated on non-empty).
  • Reasoning (research stages + trace + runtime board) and Sources (evidence rows + 5 verification badges) collapse into the message, closed by default, ember tick on each header.
  • json/table keep the .rd-answer-structured mono block; compact shapes stay compact via a named computeIsCompactResponse helper.
  • Two previously-dead props (onPin, onCompare) activated into live "Promote claim" / "A/B compare" MessageActions.

Adversarial verification (4 skeptics vs the real diff)

  • citation/probe — NO_REGRESSION: renderInlineWithCites moved byte-for-byte; replay page gained citation interactivity.
  • dead-props — NO_REGRESSION: onBranch genuinely dead (correctly dropped); onPin/onCompare upgraded from dead to live.
  • honesty gates — NO_REGRESSION: all 5 verification badges preserved, compact gate promoted to a named exported helper, guard test strengthened.
  • a11y/motion/icons — one CONFIRMED_REGRESSION (emoji action icons), fixed in this branch with stroke-SVG ActionGlyph + a guard test that blocks emoji returning.

Accepted tradeoff (documented): citation hover no longer highlights the evidence row while Sources is collapsed — tooltip still shows quote+source, and clicking a cite auto-opens Sources. Correct for a chat-shaped surface.

Verification

  • tsc 0 errors · redesign + convex suites 148 passed · vite build clean · 21 surface-contract tests pass
  • Before/after evidence: docs/design/ui-contract/20260718-one-chat-interface/ (memo→chat, same fixture, + mobile/light/expanded)

🤖 Generated with Claude Code

HShuM and others added 8 commits July 18, 2026 01:08
Founder decision: the flagship answer is chat-shaped. Prose leads,
structure collapses into the message (Reasoning/Tool/Sources primitives,
closed by default), and both renderers converge on one ChatAssistantMessage
component so they structurally cannot drift. The memo's content guarantees
survive; its document costume does not. Phased: A flagship + replay,
B FastAgentPanel adoption, C duplicate-internal retirement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase A of docs/design/ONE_CHAT_INTERFACE.md. New single component that both
ChatSurface and ReproducibleChatPage will render, so the two renderers cannot
drift. Prose leads; Reasoning/Tool/Sources collapse into the message closed by
default; MessageActions surfaces copy/thumbs/promote/compare/share.

- <Message from=assistant> + <MessageContent> frame (ai-elements)
- Row1 compact mono receipt (tier - N sources - latency - cost)
- Row2 prose: shortAnswer + whyItMatters, renderInlineWithCites preserved
  (hover<->evidence binding, probe handler, json/table .rd-answer-structured)
- Row3 risks callout + nextAction sentence w/ buttons (gated on non-empty)
- Row4 collapsibles: Reasoning (run-thread checklist + trace + RuntimeBoard),
  Tool (ChatToolCall re-housed, ToolCallBoundary kept), Sources (evidence rows
  w/ verification badges + [N] binding)
- computeIsCompactResponse named helper so guards can pin compact shape
- [data-redesign]-scoped CSS restyles ai-elements to terracotta/Manrope DNA;
  ember tick on disclosure triggers via existing .rd-answer-arrive rule

Not yet wired into either renderer (next commits).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…l AnswerPacket

Wire the live surface onto the single anatomy. User turns wrap in
<Message from=user>; the thinking turn is housed in the same <Message
from=assistant> frame (keeps the ember run-thread). The answer turn is now
<ChatAssistantMessage> instead of the local AnswerPacket. Removed ~620 lines of
duplicated internals (AnswerPacket, RuntimeBoard, renderInlineWithCites,
ProbeBanner, WorkingNotes, sourceTrustBadge, format helpers, FeedbackButton/
Thumb, LiveTime, ToolCallBoundary, buildResearchStages) — all now imported from
the component. onPin/onCompare/onReact (previously dead props) are now live via
MessageActions. tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ssage

Delete the replay page's parallel section markup (short-answer/why/evidence/
risks/nextAction/trace) + evidenceTrustBadge + evidenceWithCites. The immutable
receipt now mounts <ChatAssistantMessage variant=receipt>, mapping the cached
row's latency/cost into the receipt line. The live surface and the replay page
structurally cannot drift. tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The prose-led answer anatomy moved into ChatAssistantMessage, so the guards that
asserted its markup follow the code to its new home — same honesty intent:

- ChatResponseShape: pins the non-empty gating (whyItMatters/risks/nextAction/
  evidence), computeIsCompactResponse, the json/table mono block, rd-answer-copy
  + white-space:pre-wrap, and that BOTH renderers import ChatAssistantMessage
  with no local memo eyebrows.
- AgentWorkspaceHonesty: sourceUrlFromText, 'How we got this answer',
  'telemetry/cost not recorded', probe-banner 'Awaiting a verified result' now
  asserted on ChatAssistantMessage.
- OneSurface / ChatTypography / ChatRunLifecycle: trace disclosure, rd-answer-copy
  prose, and the RuntimeMetric receipt strip re-pointed to the component.

npx vitest run src/features/redesign convex/domains/redesign -> 147 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Playwright captures of /redesign/chat?qaState=answer (sampleAnswer fixture):
- answer-desktop-dark.png / answer-desktop-light.png (1440x900)
- answer-mobile-dark.png (390x844)
- answer-desktop-dark-expanded.png (Reasoning + Sources expanded)

Confirms the prose-led anatomy: receipt line, flowing shortAnswer+whyItMatters
with no memo eyebrows, quiet risks callout, nextAction + buttons, collapsed
Reasoning/Tool/Sources with ember-ticked triggers, MessageActions toolbar.
Interaction probe: evidence rows render on expand, run-thread + trace present,
no <nav>, one-surface-workspace testid present, exactly one textarea.
shoot.mjs / interact.mjs are the capture scripts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ersarial finding

An adversarial verify pass over the one-chat refactor (4 skeptics vs the
real diff) confirmed exactly one regression: the new MessageActions bar
shipped 📌/⇄/↗ color-emoji glyphs, which ignore the [data-redesign] theme
and clash with every other icon (same rule the starter chips follow).
Replaced with a currentColor stroke-SVG ActionGlyph (promote/compare/share)
and added a guard test asserting the component uses no emoji + has
ActionGlyph, so it cannot regress. The skeptics cleared everything else:
citation/probe binding byte-for-byte preserved, the "dead props" genuinely
dead (onPin/onCompare actually activated into live buttons), honesty gates
strengthened not weakened.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sealed before/after pair (memo document -> chat message, same fixture) +
mobile/light/expanded after shots with schema-valid manifest. Removed the
implementation agent's .oneshot-evidence/ scratch (throwaway capture
scripts + pre-emoji-fix screenshots).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@HomenShum
HomenShum enabled auto-merge (squash) July 18, 2026 11:15
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nodebench-ai Ready Ready Preview, Comment Jul 18, 2026 11:16am

Request Review

@github-actions

Copy link
Copy Markdown

PR size advisory

This PR adds 1527 lines of substantive change. CONTRIBUTING.md defines a soft limit of ~400 LOC.

If the PR is genuinely cohesive (e.g. an architecture map, a generated migration, a deletion of a dead module), no action is needed. Otherwise consider:

  • splitting into 2-3 PRs along independent concerns
  • pre-discussing the architecture change in a GitHub Discussion before merge

This is advisory — it does not block the merge.

@github-actions

Copy link
Copy Markdown

✅ Dogfood Visual QA Gate: PASSED

Check Status
Screenshots 7 captured (pass)
Walkthrough 9 chapters (pass)
Key Frames 9 extracted (pass)
Scribe Steps 8 how-to steps (pass)
Build success
Artifacts

Download the dogfood-evidence-5e097ea artifact from the Actions tab for full screenshots, frames, and walkthrough video.


Generated by Dogfood QA Gate

@HomenShum
HomenShum merged commit d445b4e into main Jul 18, 2026
17 checks passed
@HomenShum
HomenShum deleted the feat/one-chat-interface branch July 18, 2026 11:20
@github-actions

Copy link
Copy Markdown

Demo: walkthrough of the surfaces this PR changed is available as a workflow artifact (pr-demo-583) at https://github.com/HomenShum/NodeBenchAI/actions/runs/29642397474

HomenShum added a commit that referenced this pull request Jul 18, 2026
…ne-chat era (#587)

Every deletion backed by a zero-consumers grep proof from a read-only
hunt (Phase-C files excluded — that agent owns them):

- ChatSurface: dead branchFromTurn→onBranch chain (prop threaded through
  StreamingAnswer, rendered nothing since #583), orphaned traceToToolCalls,
  four dead import groups (isStructuredAnswer, ContextMenu*, Tooltip*,
  ResearchStage types) left by the 847-line Phase A cut.
- src/features/agents/components/ai/ wrapper layer removed entirely
  (AiMessage/AiConversation/AiPromptInput + barrel + story): zero runtime
  importers — FastAgentPanel wires primitives directly and completed
  answers render the canonical ChatAssistantMessage. designSystem registry
  + test now govern the canonical component's home, with an explicit
  not.toContain so the dead path cannot silently return.
- ReproducibleChatPage: latency/cost formatting deduplicated — banner
  keeps page identity (tier · model · date); the canonical receipt line
  is the single telemetry source.

Kept deliberately: guard-pinned rd-shell--chat-no-inspector contract
marker; backend/frontend sourceUrl twins (by-design pair).

Co-authored-by: hshum <hshum@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants