Commit Graph
153 Commits
Author SHA1 Message Date
Jesse_ChenandCursor f4619df273 fix(web): portal the natal board peek without effect setState
Quality gate lint failed on setHeaderSlot inside useLayoutEffect, so staging never published. Pass the header mount node from a callback ref instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 11:03:57 +08:00
Jesse_ChenandCursor 50e1a4aca5 fix(web): reload stale clients instead of spinning after a release
Homepage bootstrap never escaped the loading shell when a new web image changed chunk hashes. Stamp deploymentId, stop caching chat HTML, and hard-reload failed chunk loads once.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 10:29:43 +08:00
Jesse_ChenandCursor 8b8e5214f9 fix(web): keep onboarding and mobile natal board on one aligned overlay
Put the compact board trigger in the chat header, keep the sheet above the composer on iOS, and align onboarding messages with the intake card on the session column.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 23:54:20 +08:00
Jesse_ChenandCursor e07d1bada4 fix(rectification): show natal houses and lagna changes in a live right rail
The board was live data sitting under chat, so each new event looked like nothing changed. Keep candidate cards in the transcript and group 换升 by minute for the side panel.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 14:24:05 +08:00
Jesse_ChenandCursor a3196584d2 feat(rectification): add refinement packet without unique-minute claims
Surface D9/D10 change minutes, event-dasha match copy, dual-dasha conflict, and a post-adopt consult handoff so users can keep narrowing or start a reading from a representative time.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 07:47:10 +08:00
Jesse_ChenandCursor 7d667fecbf fix(consult): treat pinched answers as failed and restore reply actions
Incomplete Flash generations were billed as completed consultations. Fail
those runs, keep the partial text, and reuse the rectification like/copy/rerun
bar on ordinary chat replies.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 19:40:50 +08:00
Jesse_ChenandCursor c38f11dbd3 fix(api): bind daily and synastry charts to stored profiles
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Stop accepting client-supplied birth data on those paths, and cap session writes plus location lookups so a logged-in caller cannot farm compute.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 19:39:01 +08:00
Jesse_ChenandCursor 8db716ca36 fix(home): serve today's starlanguage from daily guidance
Independent Staging Quality Gate / validate (push) Failing after 8m9s
Independent Staging Quality Gate / publish (push) Has been skipped
The homepage was waiting on a full chart plus four extra engines, so the card timed out and showed the failure copy on every visit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-19 15:35:38 +08:00
Jesse_ChenandCursor 9d8b91ac02 fix(home): serve today's starlanguage from chart evidence instead of waiting on the Agent
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Homepage visits were failing closed whenever the 30s generation missed. Return an evidence-backed card immediately, polish in the background, and remember the day's card locally.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 20:49:39 +08:00
Jesse_ChenandCursor 188cff99ec fix(consult): replay an unstarted consultation after refresh
Independent Staging Quality Gate / validate (push) Successful in 7m57s
Independent Staging Quality Gate / publish (push) Has been cancelled
Sending cleared the draft and stored a request id before the server reserved usage, so a refresh left a sent question with no agent run.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 17:35:15 +08:00
Jesse_ChenandCursor 52f3c04b3b refactor(chat): remove the post-answer suggestion chips and the table that fed them
Measured use of the three chips above the composer was negligible. They
were also not what they appeared to be: the server looked up a fixed
triplet by session theme and passed it as metadata that overrode
anything the model produced, so the same ten hardcoded sets served every
user regardless of question or chart. That is a plausible reason nobody
pressed them.

Both copies of the per-theme table are gone, reply metadata narrows to
the session title, and the two parse entry points collapse into one now
that they return the same shape. The write schema still tolerates a
suggestions field so a client on the previous bundle does not lose its
message mid-deploy, and stored answers containing the legacy hidden
block are still stripped rather than shown raw.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:44:19 +08:00
Jesse_ChenandCursor a6d4473ef0 feat(onboarding): write a question for every consultation domain and stop generating an unread greeting
The home screen renders all ten domains from the consultation registry,
but the Agent only ever wrote three of them; the other seven were static
registry prompts dressed up as personalized starting points. The payload
now has to cover every domain in registry order, validated as a set
rather than per item, so a short or misordered answer is rejected whole
instead of silently leaving cards on static copy.

The greeting went the other way. Nothing has rendered it since the hero
note was removed, so it leaves the schema, the prompt, and the client
contract rather than costing tokens for text no one reads.

Ten questions take much longer to generate than three, so the route,
the server generation budget, and the client request deadline all grow
together, and the cache version bump forces existing payloads to be
regenerated once under the new shape.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:44:19 +08:00
Jesse_ChenandCursor fc811d2c39 refactor(home): drop the redundant hero note and move the birth-time boundary to the topics
The hero carried three lines saying the same thing: a salutation, a
question, and an Agent greeting that repeated both. Removing the third
line would also have removed the only place where accounts without a
usable birth minute are told that unsupported claims will be disclosed,
so that sentence moves to the topic section subheading, where the reader
is about to pick a question.

The starter loading copy claimed three starting points while the page
renders every domain in the registry, only three of which the Agent
writes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:44:19 +08:00
Jesse_ChenandCursor a12f57970b fix(home): request the daily card on the same condition that renders it
Independent Staging Quality Gate / validate (pull_request) Successful in 9m16s
Independent Staging Quality Gate / publish (pull_request) Has been skipped
Independent Staging Quality Gate / validate (push) Successful in 9m44s
Independent Staging Quality Gate / publish (push) Successful in 8m41s
The daily starlanguage card sat on "正在结合你的星盘写今天的星语。" forever for
every account whose birth time was usable. Its effect bailed out on
birthTimeDisplayState(profile), which returns a value precisely when the
birth time is candidate, accepted or confirmed, so the request went out
only for accounts that had nothing to read. The guard predates the Agent
rewrite and was masked by the written-in client fallback that rewrite
deleted. It now gates on personalChartAvailable, the same fact the card
uses to render personal content, and retries once before admitting that
today has no card.

The route stops letting one engine call take the whole card down
silently: /api/chart fails into a named reason like the other four
layers, and the engine and agent budgets leave room for a cold chart and
an observed 30s generation inside the 60s ceiling.

The home also had three greeting implementations. The hero heading drew
from a static pool while the time-aware greeting lived elsewhere and the
Agent's own greeting was overwritten client-side into a field nothing
rendered. createStartGreeting now exposes its salutation and question
halves, the hero uses both, and the served greeting reaches the hero note.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:00:53 +08:00
Jesse_ChenandCursor f6715ee4bf feat(home): write the daily card with the Agent and vary the starter heading
Independent Staging Quality Gate / validate (push) Failing after 11m34s
Independent Staging Quality Gate / publish (push) Has been skipped
The daily starlanguage card claimed to be personal but was a four-card
rotation picked by hashing the date and birth place, with the same pool
duplicated as a client fallback. It now collects chart, Vimshottari and
Narayana dasha, D9/D10 and today's transits, hands that evidence to a
dedicated Agent, and keeps the result per account per day in process. A
failed generation says so instead of printing generic advice.

The starter heading is drawn from a pool on each visit, and the
rectification card drops its fine print.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 22:27:49 +08:00
Jesse_ChenandCursor fd415e1d11 fix(account): answer profile writes with the derived birth-time truth
Independent Staging Quality Gate / validate (push) Failing after 10m56s
Independent Staging Quality Gate / publish (push) Has been skipped
A zero-uncertainty exact declaration is accepted server-side as the active
minute, but the account write only answered {ok:true}. Every save path then
kept the draft it submitted, so the first consultation after initialization
asked for unverified_birth_time against an accepted profile and was rejected
with mode_changed before billing.

The account route now returns the status and active minute it derived, and
every profile save adopts that result instead of its own local guess.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 22:13:03 +08:00
Jesse_ChenandCursor 6ce4e67186 fix(chat): rest the jump-to-latest button on the composer, not the padded scroller
Independent Staging Quality Gate / validate (push) Failing after 11m39s
Independent Staging Quality Gate / publish (push) Has been skipped
The button was a sticky child of the scroll container, which reserves
composer-sized bottom padding. Sticky boxes are clamped by their
containing block's content box, so the 12px offset never applied and the
button parked 160px above the composer, on top of the transcript.

Anchor it to the composer wrapper's own top edge instead, so the offset
no longer depends on the --composer-reserve constant.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 21:38:17 +08:00
Jesse_ChenandCursor 9dc2948ab6 feat(onboarding): pick the birth place by level instead of by search
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
The single search field asked people to type a place name and then judge
which of several near-identical results was theirs, which is the one thing
they cannot verify about their own birth record. Province, city and district
are now chosen from the dataset the app already ships, so there is nothing to
type and nothing to disambiguate.

Levels that offer no choice collapse: municipalities show one level, and
prefecture cities without districts stop at the city. A district can be left
as the city centre, which is accurate enough because the chart only needs
coordinates and a timezone.

The timezone is resolved once for the chosen place rather than on every
keystroke, through a dedicated route that both this picker and the Geoapify
path share.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 18:42:54 +08:00
Jesse_ChenandCursor e8d201dd9a perf(chat): isolate the composer, split heavy chunks, fix dead tokens
Independent Staging Quality Gate / validate (push) Successful in 13m15s
Independent Staging Quality Gate / publish (push) Successful in 10m9s
Second batch from the staging UX audit (BUG-248..253).

- css: expose the 32 palette tokens through @theme. Seven utilities
  including text-ink, text-danger and text-warning compiled to no CSS
  at all, so 30 call sites had been silently inert (BUG-248)
- chat: move the composer into its own component behind a draft store,
  so a keystroke no longer re-renders a 2723-line component, and
  persist the draft across reloads (BUG-249)
- chat: load gsap, react-markdown and thinking-orbs on demand. First
  Load JS for / drops 549.5 kB to 476.3 kB gzipped (BUG-250)
- chat: route the five in-app destinations through router.push, and
  keep the five auth redirects and the bootstrap retry as hard loads
  on purpose (BUG-251)
- a11y: announce reply completion, and move the live region out of the
  aria-busy subtree that was likely suppressing even the start
  announcement (BUG-252)
- docs: give the 27 collided bug ids unique numbers and repair their
  inbound references; require search rather than a full read of a
  3690-line file (BUG-253)

Verified: tsc, eslint, next build, and 1592 assertions across the 199
non-database test files.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 14:16:05 +08:00
Jesse_ChenandCursor 9c296f1e3f fix(ux): surface hidden notices, bound report waits, add root boundaries
Independent Staging Quality Gate / validate (push) Successful in 12m8s
Independent Staging Quality Gate / publish (push) Successful in 14m29s
Framework-level UX fixes found while auditing staging (BUG-216..220).

- chat: route 44 previously discarded composer notices to sonner with
  dedupe, so recovery, cancel and archive feedback is actually visible
  (BUG-216)
- chat: anchor stream auto-scroll to bottom proximity and add a
  jump-to-latest control, so reading history is no longer interrupted
  on every token (BUG-218)
- reports: replace the silent 120s poll cutoff with an explicit
  timed-out state, an 8m budget, stepped backoff and an elapsed
  counter (BUG-217)
- reports: pause polling while the tab is hidden, via a shared hook
- app: add root error, global-error and not-found boundaries (BUG-219)
- admin: add antd SSR style extraction and the React 19 render adapter,
  and move admin-only css out of the global stylesheet (BUG-220)
- membership: run bootstrap fetches concurrently and pause payment
  polling while hidden
- build: configure optimizePackageImports

Verified on top of 2d370f2e: tsc, eslint, next build, and the related
frontend contract suites.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 13:14:15 +08:00
Jesse_Chen bced1b9d57 fix(ui): keep mobile onboarding and login usable
Independent Staging Quality Gate / validate (push) Failing after 12m37s
Independent Staging Quality Gate / publish (push) Has been skipped
Hide the dead composer during birth-time intake, replace internal
copy with user-facing hints, and keep short-screen login, location
search, and session history reachable on phones.
2026-08-17 11:41:35 +08:00
Jesse_Chen 9d8570640d fix(frontend): recover rectification and consultation retries
Independent Staging Quality Gate / validate (push) Successful in 14m1s
Independent Staging Quality Gate / publish (push) Successful in 9m58s
2026-08-16 13:13:49 +08:00
Jesse_Chen 0d59d51814 fix: allow public daily guidance without birth minute
Independent Staging Quality Gate / validate (push) Successful in 14m4s
Independent Staging Quality Gate / publish (push) Successful in 9m22s
2026-08-15 23:55:57 +08:00
Jesse_Chen 1084dce770 fix: avoid repeated daily starlanguage refresh
Independent Staging Quality Gate / validate (push) Failing after 11m57s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-15 23:28:49 +08:00
Jesse_Chen 12b6398c7b fix: make starter questions user-centered
Independent Staging Quality Gate / validate (push) Failing after 12m39s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-15 21:52:02 +08:00
Jesse_Chen 6d192ad175 feat: add consultation and product domain registries 2026-08-15 06:04:23 +08:00
Jesse_Chen cf7598b337 refactor(frontend): remove generic AI-slop styling 2026-08-13 11:05:00 +08:00
Jesse_Chen 4deb5c2378 fix(rectification): start new case from homepage
Staging Backend Quality Gate / validate (pull_request) Successful in 24m42s
Staging Backend Quality Gate / publish (pull_request) Has been skipped
2026-08-12 21:21:26 +08:00
Jesse_Chen 220828d6f0 fix(rectification): hydrate persisted case turns
Staging Backend Quality Gate / validate (pull_request) Successful in 15m6s
Staging Backend Quality Gate / publish (pull_request) Has been skipped
2026-08-12 10:45:49 +08:00
Jesse b04dd1a9e0 merge: sync latest staging into rectification v9
# Conflicts:
#	docs/BUG_HISTORY.md
2026-08-11 18:08:42 +08:00
Jesse ca7484666f feat(rectification): stream agent execution and redesign entry routing
Replace the Direct Agentic textStream relay with a durable V9 agent runtime:

- agentic-rectification.ts: short boundary-only system prompt (no gate->scan
  ->score->diagnostics copy); pins skills/jyotish-birth-time-rectification;
  per-action bounded maxSteps (opening/read-only 6, evidence 8, rescore 12,
  accept/confirm 6) with a hard ceiling and repeated-tool-call detection.
- rectification-v9-tools.ts: ten Case-ref tools (read-case, propose/confirm/
  revise-evidence, compare-candidates, read-diagnostics, offer-candidates,
  accept-candidate, confirm-birth-time, close-case). Inputs are minimal refs
  only; RPC-backed evidence ledger, fingerprint cache reuse, receipts, and
  accepted!=confirmed semantics; confirm requires gate + grounded consent.
- /api/rectification/agent: caseId/sessionId/requestId/action/message; exact
  Case<->Session binding verified server-side; client history never overrides
  the durable dossier; pending turn -> completed/failed/retryable; consumes
  result.fullStream and emits allowlisted NDJSON only (reasoning/raw/provider
  metadata/tool payloads/birth data/scores never forwarded); first-turn real
  skill.started/skill.loaded gate with one controlled retry; billing bound to
  rectification:case:{caseId}.
- New forward migration 20260813010000_agentic_rectification_v9_agent_api.sql:
  case dossier/compute, turn finalize, fingerprint-cached candidate persist,
  case-scoped accept, consent-gated confirm, guarded transitions,
  needs_rebaseline profile guard, run_phases receipt table, and the
  rectification_runtime_version feature flag (v9 default, legacy read-only).
- Frontend: homepage/sidebar entry routing now uses the server Case open API
  (openRectificationFromHomepage/openRectificationSession/startNewRectification)
  with exact sessionId/caseId and server-owned shouldStartOpening; CTA driven
  by entry-summary; chat restores from persisted turns, candidate cards from
  the Candidate Snapshot API, activity from real NDJSON + persisted receipts;
  direct durable candidate-accept endpoint for the UI cards.
2026-08-11 17:17:56 +08:00
Jesse_Chen 46cdc3bbf4 feat(consultation): let the jyotish agent drive skills and tools 2026-08-11 16:22:02 +08:00
Jesse_Chen ce46aae5c8 fix: polish storefront account and membership state 2026-08-11 11:59:03 +08:00
Codex 65bcef3001 feat: add global asynchronous report center
Staging Backend Quality Gate / validate (push) Has been cancelled
Staging Backend Quality Gate / publish (push) Has been cancelled
2026-08-09 20:24:09 -07:00
Jesse_Chen a17ff258d8 fix: correct membership back flow and add onboarding paywall
Staging Backend Quality Gate / validate (push) Has been cancelled
Staging Backend Quality Gate / publish (push) Has been cancelled
2026-08-10 11:14:31 +08:00
Jesse_Chen 34395e902c fix(chat): follow active response at bottom
Staging Backend Quality Gate / validate (push) Successful in 11m13s
Staging Backend Quality Gate / publish (push) Has been cancelled
2026-08-09 01:19:39 +08:00
Jesse_Chen 17430a1f21 fix(reports): trust verified proxy origin
Staging Backend Quality Gate / validate (push) Successful in 12m13s
Staging Backend Quality Gate / publish (push) Has been cancelled
2026-08-09 00:54:55 +08:00
Jesse_Chen 32b683ebef fix(consult): preserve streaming across disconnects
Staging Backend Quality Gate / validate (push) Successful in 12m47s
Staging Backend Quality Gate / publish (push) Successful in 31m1s
2026-08-08 21:34:03 +08:00
Jesse 280d3e7a35 feat(membership): replace purchase modal with membership page 2026-08-07 18:24:16 +08:00
Jesse_Chen f3946eaa6f chore: retire legacy rectification runtime
Staging Backend Quality Gate / validate (push) Failing after 9m57s
Staging Backend Quality Gate / publish (push) Has been skipped
2026-08-07 12:55:32 +08:00
Jesse 49f6edd7fb feat(web): add persistent beam avatars
Staging Backend Quality Gate / validate (push) Successful in 13m34s
Staging Backend Quality Gate / publish (push) Has been cancelled
2026-08-07 12:07:57 +08:00
Jesse_Chen 7040fd998e feat(billing): add products subscriptions orders and usage 2026-08-06 20:15:08 +08:00
Jesse d89073d296 feat(report): add browser-rendered report and PDF print 2026-08-06 12:52:05 +08:00
Jesse_Chen 5957803de4 Merge GitHub upstream into Gitea primary 2026-08-05 11:13:34 +08:00
Jesse_Chen 58f6b5f821 refine web session and account UI 2026-08-04 21:59:59 +08:00
Jesse_Chen 79fe2d6c69 fix: gate rectification candidate adoption flow 2026-08-04 16:47:23 +08:00
Jesse_Chen 8f6f4f511b feat: allow users to accept rectification candidates 2026-08-04 11:39:33 +08:00
Jesse_Chen b9fe6a6be3 fix rectification session persistence 2026-08-04 00:38:16 +08:00
Jesse_Chen 0b1a40a5a5 fix(rectification): rehydrate persisted birth dates 2026-08-03 16:44:49 +08:00
Jesse_Chen 21a121a6a7 fix(rectification): accept persisted birth dates 2026-08-03 16:07:18 +08:00