Commit Graph

385 Commits

Author SHA1 Message Date
Jesse_Chen 661a0dab14 fix(rectification): stop the opening body from repeating the collect prompt
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
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>
2026-09-02 14:53:10 +08:00
Jesse_Chen aab3ad4b84 fix(rectification): keep choice stems visible and align overlay adopt with the engine
Independent Staging Quality Gate / validate (push) Successful in 7m44s
Independent Staging Quality Gate / publish (push) Successful in 1m48s
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>
2026-09-02 13:11:22 +08:00
Jesse_Chen 482796fc52 fix(chat): reveal the home page once after a two-phase bootstrap
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
2026-09-02 04:39:04 +00:00
Jesse_Chen f542c02490 refactor(chat): share composer, scroll follow and jump control across both chat surfaces
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
2026-09-02 04:29:01 +00:00
Jesse_Chen 6356d7b549 refactor(chat): render rectification activity through the shared step timeline
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
2026-09-02 04:29:01 +00:00
Jesse_Chen aff9d19343 fix(chat): keep the latest reply mounted through settlement and animate the timeline collapse
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
2026-09-02 04:29:01 +00:00
Jesse_Chen 1a3e14e726 fix(rectification): show question stems and unblock adopt after occupation
Independent Staging Quality Gate / validate (push) Successful in 13m40s
Independent Staging Quality Gate / publish (push) Successful in 9m59s
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>
2026-09-02 11:09:56 +08:00
Jesse_Chen 058e5db9b5 fix(chat): make Home pass react-hooks lint after the split
Independent Staging Quality Gate / validate (push) Successful in 17m39s
Independent Staging Quality Gate / publish (push) Successful in 7m11s
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>
2026-09-02 07:01:36 +08:00
Jesse_Chen bf6989eccf refactor(chat): extract profile onboarding and rectification surface hooks
Close the home-page split by moving account/onboarding and rectification glue out of page.tsx without relocating React state, keeping the route static and hook order intact.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 05:56:58 +08:00
Jesse_Chen 80e7736163 Merge PR #48: humane agent voice with boundary semantics intact
Independent Staging Quality Gate / validate (push) Failing after 11m3s
Independent Staging Quality Gate / publish (push) Has been skipped
Reviewed: tsc + rectification/voice 757 + consult 289 green; E-1 predicate
verified structural (no body-text matching); boundary phrases preserved in
delivery turns. Conflict: BUG entry renumbered 467→469.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-09-01 20:49:06 +00:00
Jesse_Chen 77ca0182dc Merge PR #49: pass birth-time accuracy truth into consultation engine
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
2026-09-01 20:48:27 +00:00
Jesse_Chen 551d6317ae refactor(chat): extract consultation and session hooks after contract repairs
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Keep archive as a PATCH of archived_at rather than DELETE, pass entry_mode through onboarding, and let popstate to the default chat reuse selectSession. Then move send/stop/recovery and session management out of page.tsx so the home surface stays within the batch-two line budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 04:34:14 +08:00
Jesse_Chen ed9497e76a fix(voice): speak first, then keep Level 2 skeleton and boundary semantics
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>
2026-09-02 02:27:50 +08:00
Jesse_Chen 56daf6be49 fix(consult): pass birth-time accuracy instead of treating every chart as unrectified
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>
2026-09-02 01:21:40 +08:00
Jesse_Chen 54269fcfcc refactor(chat): extract home helpers, chart library, and starter surfaces
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
page.tsx still owns the chat main chain, but the first product surfaces now
live in their own modules so later splits can land without editing the 4k-line
Home. Source-lock tests follow the moved tokens; the orphan user-data contract
is aligned and added to the quick gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:58:02 +08:00
Jesse_Chen ce6a8a7e72 fix(chat): make cloud the only truth for charts, synastry, and pin/archive
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
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>
2026-09-01 21:38:21 +08:00
Jesse_Chen 924f420202 fix(chat): keep the current session in the URL as ?c=
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Refresh, back, and login return were dropping the open conversation because selection lived only in React state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 20:42:21 +08:00
Jesse_Chen b6989c3eea fix(chat): make the server the only writer of session messages
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
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>
2026-09-01 19:51:19 +08:00
Jesse_Chen 75fc456d7e fix(rectification): drop duplicate collect cards and false run_failed
Independent Staging Quality Gate / validate (push) Successful in 10m23s
Independent Staging Quality Gate / publish (push) Failing after 8m59s
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>
2026-09-01 15:19:00 +08:00
Jesse_Chen e404b6f42b fix(rectification): guarantee nonterminal turn exits
Independent Staging Quality Gate / validate (push) Successful in 13m25s
Independent Staging Quality Gate / publish (push) Successful in 9m26s
2026-09-01 13:35:51 +08:00
Jesse_Chen 47b4b06bfb fix(rectification): surface pricing failures and persist opening question
Independent Staging Quality Gate / validate (push) Successful in 12m42s
Independent Staging Quality Gate / publish (push) Successful in 22m34s
2026-08-31 15:16:23 +08:00
Jesse_Chen 53450f5bf3 Merge remote-tracking branch 'origin/staging' into codex/billing-pricing-20260830
Independent Staging Quality Gate / validate (push) Failing after 8m27s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-31 10:00:36 +08:00
Jesse_Chen 3a762e1fca feat(billing): record prompt cache usage 2026-08-31 09:59:53 +08:00
Jesse_Chen 6cbf1f22e2 fix(rectification): separate question slots from model prose 2026-08-31 05:50:28 +08:00
Jesse_Chen 79304c31fc fix(rectification): keep model confirmations separate from question slots 2026-08-31 04:50:39 +08:00
Jesse_Chen a499c3444e feat(admin): add read-only pricing simulator 2026-08-31 04:30:40 +08:00
Jesse_Chen 6e13949d3b feat(billing): resolve chat and rectification pricing by feature 2026-08-31 04:29:45 +08:00
Jesse_Chen a73d996f65 feat(billing): charge personal reports with durable settlement 2026-08-31 04:08:20 +08:00
Jesse_Chen aaaa5fb73c feat(billing): add feature pricing configuration 2026-08-31 03:37:44 +08:00
Jesse_Chen da4c03a857 feat(billing): add usage cost aggregation report 2026-08-31 03:06:15 +08:00
Jesse_Chen ff5998f184 fix(rectification): render adoption carrier on deterministic choice path
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
2026-08-31 02:15:12 +08:00
Jesse_Chen 79bfa73da3 fix(rectification): prevent silent collect focus stalls
Independent Staging Quality Gate / validate (push) Successful in 20m38s
Independent Staging Quality Gate / publish (push) Successful in 24m14s
2026-08-30 23:08:10 +08:00
Jesse_Chen 0ae3e2d796 feat(reports): generate personal reports by section
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
2026-08-30 22:59:17 +08:00
Jesse_Chen a96df75473 fix(frontend): stop the personal report rendering white on white in dark mode
Independent Staging Quality Gate / validate (push) Successful in 10m50s
Independent Staging Quality Gate / publish (push) Has been cancelled
.personal-report-reader declared --report-paper, --report-rule and
--report-accent on itself. A custom property resolves from the nearest
element that declares it, so an element-local declaration beats :root
regardless of media queries or source order — the dark override added
with the theme was dead the moment it was written.

The inks did follow the theme, because they live on :root. So dark mode
put --color-ink (#f2f0ea) on paper that stayed #f8f5ee: 1.05:1 for
headings and 1.22:1 for body. The report was effectively invisible.

Printing had the same defect from the other side: the print block forces
white backgrounds but never reset the inks, so printing from a dark
screen produced a blank page. It now pins the palette back to light —
paper is always paper.

Every report ink now clears AA on report paper in both themes, and the
new contract test forbids re-declaring the report palette anywhere but
:root, which is the trap that caused this.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
2026-08-30 11:29:58 +00:00
Jesse_Chen 85b14b13ae fix(rectification): close non-converging range offer without an exit
Independent Staging Quality Gate / validate (push) Successful in 11m3s
Independent Staging Quality Gate / publish (push) Successful in 8m48s
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>
2026-08-30 18:35:16 +08:00
Jesse_Chen 79f65ac8b0 fix(frontend): restore staging quality gate contracts
Independent Staging Quality Gate / validate (push) Successful in 10m34s
Independent Staging Quality Gate / publish (push) Successful in 10m11s
2026-08-30 17:01:01 +08:00
Jesse_Chen a671986a1d fix(frontend): complete settings MVP structure
Independent Staging Quality Gate / validate (push) Failing after 10m21s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-30 16:32:58 +08:00
Jesse_Chen f5e6d51646 feat(frontend): bind sessions to chart profiles 2026-08-30 15:55:45 +08:00
Jesse_Chen 5c1d095f69 feat(frontend): use offline global birth place hierarchy 2026-08-30 15:55:45 +08:00
Jesse_Chen f9a00dc568 fix(frontend): preserve owner profile when switching charts 2026-08-30 15:55:45 +08:00
Jesse_Chen 796e4cf8cf feat(frontend): clarify chart profile management 2026-08-30 15:55:45 +08:00
Jesse_Chen f4fb39e0f3 feat(frontend): separate profile and chart settings 2026-08-30 15:55:45 +08:00
Jesse_Chen 52477306cc fix(rectification): server-append spoken collect stems after free-text turns
Independent Staging Quality Gate / validate (push) Successful in 10m43s
Independent Staging Quality Gate / publish (push) Successful in 9m8s
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>
2026-08-30 15:49:20 +08:00
Jesse_Chen e8fa1ce4ea fix(frontend): raise dark contrast, expand hit areas, and surface input limits
Independent Staging Quality Gate / validate (push) Successful in 9m19s
Independent Staging Quality Gate / publish (push) Successful in 9m54s
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>
2026-08-30 11:19:50 +08:00
Jesse_Chen 95f5851261 fix(rectification): rewrite D9/D10 style options and stem spacing
Independent Staging Quality Gate / validate (push) Successful in 9m28s
Independent Staging Quality Gate / publish (push) Successful in 7m26s
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>
2026-08-30 10:01:32 +08:00
Jesse_Chen ea0fbd4406 fix(rectification): ask spoken collect questions in the agent body
Independent Staging Quality Gate / validate (push) Successful in 9m32s
Independent Staging Quality Gate / publish (push) Successful in 6m53s
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>
2026-08-30 09:39:47 +08:00
Jesse_Chen 02d4c91626 fix(rectification): stop occupation coverage from locking questions and the range exit
Independent Staging Quality Gate / validate (push) Successful in 11m40s
Independent Staging Quality Gate / publish (push) Successful in 9m36s
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>
2026-08-30 03:05:28 +08:00
Jesse_Chen f5c02924c9 fix(rectification): show spoken collect questions in the chat UI
Independent Staging Quality Gate / validate (push) Successful in 10m32s
Independent Staging Quality Gate / publish (push) Successful in 8m46s
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>
2026-08-30 00:51:14 +08:00
Jesse_Chen 3a0319694e fix(rectification): keep same-sentence dated events after structured answers
Independent Staging Quality Gate / validate (push) Successful in 13m7s
Independent Staging Quality Gate / publish (push) Successful in 29m19s
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>
2026-08-29 23:18:07 +08:00
Jesse_Chen 078c1cdc0d fix(rectification): keep collection denials from stalling the interview
Independent Staging Quality Gate / validate (push) Successful in 23m37s
Independent Staging Quality Gate / publish (push) Has been cancelled
A spoken no neither scored nor declined coverage, so relatives never closed and free-text turns left current_question null. Prefer a same-domain yearless scoring card before an unscoreable collect, resolve explicit collect denials as declined, and persist the next followup after an idle agent turn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 22:37:32 +08:00