The outer focus ring overflowed the message bubble and stacked on the existing selected border. Draw keyboard focus inset and skip auto-focusing the first option.
Co-authored-by: Cursor <cursoragent@cursor.com>
Agent set-focus was writing or dropping choice schema, so probes never scored. Force server-owned options, fail closed when focus list RPC errors, and require the probe year in spokenPrompt.
Co-authored-by: Cursor <cursoragent@cursor.com>
Focuses now carry asked_turn_id so GET rebuilds stem and options on the
same turn. Agent writes spokenPrompt; the live question slot is gone.
Co-authored-by: Cursor <cursoragent@cursor.com>
Task 4 evidence: local gates, Gitea 2308/2309, health gitCommit 7faf8555. Live personal_full and writer/token still need a logged-in 委托方.
Co-authored-by: Cursor <cursoragent@cursor.com>
The extractor only read an obsolete varga object shape, never issued Transit receipts, and the consultation response omitted Chara Karakas, so career/marriage/timing/wealth all blocked. Supply the live engine shape, fail-closed receipts, and jaimini.chara_karakas without relaxing the evidence plan.
Co-authored-by: Cursor <cursoragent@cursor.com>
Move the current-question ref off render and persist the collect stem from snapshot/send callbacks so ESLint no longer fails the staging gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep collect text on bubbleMessage but pass displayedMessage.state so the entry contract matches again.
Co-authored-by: Cursor <cursoragent@cursor.com>
The live question slot still rendered the collect prompt below the action icons when the streamed body was only a greeting. Join the GET prompt into that bubble and stop drawing a sibling collect slot.
Co-authored-by: Cursor <cursoragent@cursor.com>
The live question slot disappeared on refresh because it was never written to assistant_message. Attach the current collect_spoken prompt to that turn before finalize so chat history keeps it.
Co-authored-by: Cursor <cursoragent@cursor.com>
BUG-486 demotion dropped wealth and education cards when the snapshot only had machine receipts, which failed Gitea validate. Keep write-theme cards only when varga_full is present.
Co-authored-by: Cursor <cursoragent@cursor.com>
Engine keys like D2_Hora never became structured charts, so wealth write
themes failed the document contract. Canonicalize document vargas, demote
missing charts to blocked, and classify the parse failure.
Co-authored-by: Cursor <cursoragent@cursor.com>
Persist the interview slot before the opening turn, keep the stem in the question slot, and hide that slot while a run is busy so the same ask does not appear twice.
Co-authored-by: Cursor <cursoragent@cursor.com>
Walkthrough polish: fail-closed empty D9 prompts, stop asserting the next question is on screen, vary same-domain collect copy, switch to reverse-verify after adopt, and let coverage route interview without blocking can_adopt.
Co-authored-by: Cursor <cursoragent@cursor.com>
The loading screen now owns every wait: starter questions, today's
starlanguage and the rectification entry summary are fetched in a prepare
phase before reveal (4s budget, static fallbacks), the rectification chunk is
warmed, recent sessions are prefetched, and no component spinner remains
after the page appears. BUG-479.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
The rectification session rendered its own textarea (no length ceiling,
no count), its own rAF scroll follow with a sticky-scroll helper, and its
own jump chip styled differently from the main chat's inline Tailwind
button, while the main chat re-ran scrollTo on every streamed token and
added a smooth scroll on settle. ChatComposer now accepts a controlled
value so the rectification surface reuses it without touching the main
draft store; useConversationScrollAnchor owns the follow through a
ResizeObserver, one frame per content change, for both surfaces; a
single JumpToLatestButton replaces both chips; the 720px transcript
override is gone. DESIGN.md records the shared composer, the jump
control, the reading width and the two shadow tokens.
BUG-477 BUG-478
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
The rectification surface had its own activity pipeline: a trace panel
with a 20px canvas orb clipped inside a 14px marker, a list that never
collapsed, a second receipt disclosure under every reply, an inline
failure banner and a staged label while regenerating. Its trace and
receipt are now projected onto ConsultationTimelineRow so both surfaces
render one ConsultationRunTimeline with one live marker and one settled
summary; receipt methods become source chips on the last completed row.
The unreachable sections-report/step-tree path, the trace panel, the
receipt component and the thinking-orbs dependency are removed. The
server-side drop of rectification thinking deltas is untouched.
BUG-476
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
The streaming and settled versions of the trailing assistant reply were
two components, so settling unmounted one and mounted the other and the
entrance tween replayed over text the reader was already on. One
LatestAssistantEntry now owns that row under a single key, and the
history list excludes it. The CSS entrance keyframe that doubled the
GSAP tween is gone and the tween matches the documented 160ms. The step
timeline no longer remounts on settle: it is a button-controlled
disclosure with a 180ms grid-rows transition, the reader's own toggle
wins over the live default, and an in-flight request with no events yet
shows a queued row instead of an empty shell.
BUG-474 BUG-475
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
Every NDJSON event used to commit its own React update and re-parse the
whole partial answer through react-markdown, so long replies grew
quadratically slower. Stream events now land in a frame buffer that
flushes at most once per animation frame, releases answer and thinking
text at a steady pace with a twelve-frame catch-up, and settles
synchronously on completion, failure and abort. Streaming markdown is
split at the last completed block so only the tail is re-parsed each
frame. Applied to both the consultation hook and the rectification chat.
BUG-473
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
Choice legends and spoken collect prompts were hidden after BUG-461, and occupation still blocked canAdopt once dated coverage was done. Restore visible stems and stop polling extra collects when adopt is allowed.
Co-authored-by: Cursor <cursoragent@cursor.com>
eslint-plugin-react-hooks now analyzes the smaller Home, so render-time ref writes and sync effect setState were failing the staging gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reviewed: tsc + consult 295 + rectification 747 + python suites green;
guard functions and window/general instructions verified unchanged.
Conflict: BUG entry renumbered 467→468 (467 taken by report-extraction).
Review fix: test_consultation_birth_accuracy.py added to CORE_PYTEST_TARGETS
(pytest-style file outside the rectification glob would never hit the auto gate).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
PROGRESS carries the engine contract snapshot (including the fields the
task brief assumed exist but the consultation API does not return), the
claim card before/after text, the per-section prompt growth table, the
knowledge pack inventory, and the actual quality-gate output.
BLOCKED records four things: no model credentials and no PostgreSQL here,
so the live writer comparison could not be produced; the per-section
prompt p50 landing at 2.83x raw (2.28x cost-weighted), which is over the
brief's 2x line and needs a decision rather than an evidence cut; and the
fact that /api/consultation_workflow serves the reduced prompt pack, so
the server narrative seeds the brief pointed at do not exist yet.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr
Natal answers were opening on parameter tables, and rectification turns were one-sentence legal copy. Centralize user-facing strings, keep representative-minute and question-slot red lines, and stop duplicating the opening collect prompt as a second assistant message.
Co-authored-by: Cursor <cursoragent@cursor.com>
Hospital records and adopted rectification times were still fed to the model as not_auto_rectified because the chart request omitted declared_accuracy/time_source and mastra hardcoded the boundary. Map profile truth into the engine request, keep rectified for accepted/confirmed active times only, and leave window/general guards unchanged.
Co-authored-by: Cursor <cursoragent@cursor.com>
Local fallbacks were creating fake saves and resurrecting deleted rows.
Pin and archive now live on chat_sessions so they follow the account.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refresh, back, and login return were dropping the open conversation because selection lived only in React state.
Co-authored-by: Cursor <cursoragent@cursor.com>
List GET no longer ships transcripts; consult appends questions after reserve and ignores client history so dual-tab last-write-wins cannot erase messages.
Co-authored-by: Cursor <cursoragent@cursor.com>
deliveryCapability no longer ties adoption to minute separation or holdout;
those stay on the exact-minute confirmation gate so users can save a range.
Co-authored-by: Cursor <cursoragent@cursor.com>
Spoken collect no longer renders a second visual prompt; choice legends stay screen-reader only and live cards share the assistant inset. Exhaustion collect avoids colliding with the opening question id, and a successful billed turn no longer surfaces run_failed after the exit gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
The registry packagePath points at versions/<version>/, but the root
SKILL.md copy makes it easy to hash the package root instead. Hashing
the root pulls the entire versions/ subtree into the digest and still
returns a value, so the mistake surfaces only as a failing gate later.
Records BUG-459 and corrects the task brief's D-2 table, which listed
the root SKILL.md as the hash target.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
When coverage still blocks adopt and no renderable discriminator remains, narrate the numeric range and persist a spoken collect instead of promising a time card that cannot be clicked. Recompute probe information gain on active candidates and drop zero-split probes explicitly.
Co-authored-by: Cursor <cursoragent@cursor.com>
Choice path already wrote spokenFollowupForUser into the body; free-text
dropped that stem and only filled empty answers, so a new collect_spoken
focus stayed invisible after “记下了”.
Co-authored-by: Cursor <cursoragent@cursor.com>
Dark muted surfaces missed WCAG AA; action and tertiary tokens plus a 32-pair contract close that. Hit targets, remaining-count, and Enter-to-send follow the interaction audit without changing visual sizes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Only sign-bound varga_style questions may omit a concrete period. Remaining-layer existence and quality probes now drop as yearless_ungrounded_contrast instead of scoring by group order.
Co-authored-by: Cursor <cursoragent@cursor.com>
Choice cards were showing type-table tokens as options, dating long-term style questions, and stacking the stem on the first option because legend is outside the fieldset grid.
Co-authored-by: Cursor <cursoragent@cursor.com>
The standalone collect prompt bar reused the choice-card chrome and
duplicated the question. Visibility now comes from the spoken reply,
with an empty-body fallback that posts the persisted focus prompt.
Co-authored-by: Cursor <cursoragent@cursor.com>
Occupation answers were stored as career, so coverage never closed, yearless
cards never fired, and the decision layer suppressed an engine-allowed range.
Normalize occupation-collect writes, allow yearless cards once training is
open, offer a range when no distinguish card remains, and align the public
house table to the representative minute.
Co-authored-by: Cursor <cursoragent@cursor.com>
Spoken collect prompts lived only in GET current_question. The chat never
parsed that field, Agent projections returned null after evidence writes,
and active_focus followups collapsed the questionId. Render the parsed
prompt, keep choiceReady on real cards, and give collect focuses a stable
domain-scoped id.
Co-authored-by: Cursor <cursoragent@cursor.com>
The choice and collect fast paths applied the answer then returned,
so a dated event in the same utterance never reached the evidence
ledger. Idle persist also prechecked follow-up with a hardcoded
collect_evidence outcome instead of the dossier decision.
Co-authored-by: Cursor <cursoragent@cursor.com>