feat(one-chat): Phase C — markdown adoption, gate-only routing, honest counts, retirement#586
Merged
Conversation
…s, honest step count, gate-only routing
Decision 1: ChatAssistantMessage gains additive proseFormat="plain"|"markdown"
(default plain — flagship/receipt callers unchanged). Markdown prose renders
through the shared ai-elements streamdown renderer (MessageResponse →
streamdown-renderer.tsx, consumed not edited) with no [N] cite interactivity.
The adapter's fit gate stops refusing block-level markdown (fence/heading/
table/list/link) and instead adopts with proseFormat="markdown"; still
refused: think tags, {{cite:}}/{{entity:}}/@@entity: tokens, gallery markers,
bare [N] references.
Decision 2: additive onDelete/onReadAloud props render as MessageActions with
stroke-SVG ActionGlyphs (no emoji); the panel passes its existing
handleDelete/handleReadAloud through PanelCanonicalAnswer.
Decision 3: Reasoning trigger count is now honest — trace-backed turns keep
packet.trace.length (buildResearchStages template-matches and can ground
fewer stages than trace rows, so pure stages-length would have changed
flagship output); trace-less turns fall back to researchStages.length; zero
renders no count at all instead of "0 steps".
Decision 4 (part 1): preferCanonicalAnswer opt-in prop removed — the fit gate
alone routes every turn (compact sidebar included). Routing-predicate mirrors
(getNormalizedToolName / isFusionSearchToolName / isMemoryPlanningToolName)
collapsed into adapters/convexToUIParts.ts, imported by both the bubble and
the adoption gate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… ported actions
Rewrites every contract that pinned re-routed behavior to pin the canonical
markup with the same intent (never delete a guard without replacing it):
- adoption is default (no opt-in prop), compact sidebar adopts too
- markdown-rich turns adopt with proseFormat="markdown" via the streamdown
prose row; bare-[N] markdown still refused (no fabricated cite binding)
- ordered text-part fallback feeds the canonical packet prose
- plain tools re-house in ONE canonical Tool disclosure with honest result
previews (falsy-but-present outputs surface; empty output invents nothing)
- sources re-house in the canonical Sources collapsible without badges
- model provenance surfaces exactly once via the honest receipt line
- assistant-authored JS still never executes (canonical markdown row)
- read-aloud/delete port into the canonical toolbar; "0 steps" never renders
Refusal contracts unchanged: streaming, hierarchy, fusion, memory, media,
domain parts, token answers ({{cite:}}/@@entity:), bare [N], user turns.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… harness shows markdown-adopted turn Doc records the Phase C removal ledger (what died and why, what was deliberately kept because refused shapes still reach it) and the binding markdown-prose decision. Dev-only harness now renders BOTH a plain and a markdown adopted turn through the real adapter chain, with the ported read-aloud/delete toolbar actions, for screenshot evidence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…+ evidence Root cause (caught by LOOKING at the harness screenshot, not the green tests): isStructuredAnswer's plain-packet heuristic treats >=2 pipe lines as a structured table, so a markdown TABLE re-inflated the raw .rd-answer- structured mono block and the adopted turn rendered as escaped text. The markdown branch now takes precedence; flagship plain callers (proseFormat default) hit the unchanged structured check. Regression pinned in the adoption contract. Harness gains the app's .sr-only utility so MessageAction labels don't leak visually outside the app stylesheet. Evidence screenshots in .oneshot-evidence/ (plain + markdown adopted turns, collapsed + expanded). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… CSS caveat) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
HomenShum
enabled auto-merge (squash)
July 18, 2026 21:01
PR size advisoryThis PR adds 622 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:
This is advisory — it does not block the merge. |
✅ Dogfood Visual QA Gate: PASSED
ArtifactsDownload the Generated by Dogfood QA Gate |
|
Demo: walkthrough of the surfaces this PR changed is available as a workflow artifact ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Final phase of
docs/design/ONE_CHAT_INTERFACE.md— the unification is complete (A #583 · B #584 · C this PR):proseFormat="markdown"renders via the previously-zero-consumer streamdown renderer; the fit gate stops refusing fences/headings/tables/lists/links. Flagship default-plain path untouched. Still refused honestly: streaming, hierarchy, domain parts,{{cite:}}/@@entity:tokens, bare[N](no cite binding), user turns.preferCanonicalAnswerdeleted;describeCanonicalAnswerFitalone routes. Unreachable duplicates retired with per-item unreachability justifications in the doc's removal ledger; reachable legacy paths (refused shapes) deliberately kept.The look-at-it step caught a real P1 green tests missed: markdown tables tripped
isStructuredAnswer's pipe heuristic → escaped raw text. Root-caused (branch precedence), fixed, regression-pinned, re-shot.Verification (orchestrator-independent)
tsc0 · build clean · 505 tests green (baseline 499 before edits, +6, 0 new failures; 148-suite redesign guards untouched)docs/design/ui-contract/20260718-one-chat-phase-c/(harness captures; CSS-fidelity caveat honestly recorded — polish pass upgrades harness before final presentation photos)🤖 Generated with Claude Code