Commit Graph
199 Commits
Author SHA1 Message Date
Jesse_ChenandClaude Opus 5.5 12e315a9bb feat(reply-quality): 👎 keeps a snapshot of the turn; admin 对话质量记录
A 👎 now saves, server side, the rated turn plus the context window the
model read for it (reconstructed from the stored session with the same
consultationHistoryWindow the consult route uses), model and run facts.
👍 is only counted. Switching to 👍 or clearing deletes the snapshot.
Bodies are blanked after 90 days; the row cascades on session delete
and on account deletion.

- Optional 不满意原因 panel under the answer after a 👎 (five reasons,
  200-char note, "会把这一轮对话发给我们排查").
- Admin 对话质量记录: 👍/👎 stats by day and model, list without text,
  audited snapshot open, 处理状态 + note (support.quality.read/write).
- Privacy draft: what a 👎 keeps, why, 90 days, deletion.
- Migration 20260930050000 is add-only; set_reply_rating() replaced with
  the same signature.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 09:42:11 +08:00
Jesse_ChenandClaude Opus 5.5 4f3d8d7c62 feat(compliance): content moderation on model input and output — local lexicon, Aliyun adapter, free completion, admin log
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 09:42:11 +08:00
Jesse_ChenandClaude Opus 5.5 96adbce3a9 feat(account): self-service deletion with a 7-day cooling-off period
Request signs out everywhere and freezes paid routes (423 + DB triggers);
signing in within 7 days shows the pending gate with 撤销注销. A periodic
idempotent worker purges personal content afterwards and keeps finance
rows against a tombstoned identity. Read-only admin list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 09:42:11 +08:00
Jesse_ChenandClaude Opus 5.5 3c8123d912 feat(support): in-app feedback & complaints with admin handling; persist reply ratings
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 09:42:11 +08:00
Jesse_ChenandClaude Opus 5.5 8f58eccecf feat(legal): terms and privacy pages, login consent recorded per version, re-consent gate (draft text, placeholders)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 09:42:11 +08:00
Jesse_ChenandClaude Opus 5.5 4461648feb feat(home): daily line from a fixed sentence library; prefetch it so landing on home never swaps text (BUG-1109, BUG-1110)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 01:26:06 +08:00
Jesse_ChenandClaude Opus 5.5 921992a492 fix(home,chart,ephemeris): drop the unfinished-rectification hint, full chart-type captions, orbit instead of 还没拿到, constellation icon (BUG-1111..1114)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 01:11:47 +08:00
Jesse_ChenandClaude Opus 5.5 7950ae93d3 feat(reports): redesign the export sheet — edition, whole or chosen chapters, size on the button
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 00:44:28 +08:00
Jesse_ChenandClaude Opus 5.5 94fbf37674 fix(reports): one opening screen, one-row phone bar, roomier export sheet, keep the chapter across editions (BUG-1106..1108)
Independent Staging Quality Gate / publish (push) Canceled after 0s
Independent Staging Quality Gate / validate (push) Canceled after 9m19s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-30 00:38:17 +08:00
Jesse_ChenandClaude Opus 5.5 fee9ddc8a1 fix(home): prefetch the warm snapshot from secondary pages so the first 新建对话 skips the loading ring (BUG-1104)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 20:28:59 +08:00
Jesse_ChenandClaude Opus 5.5 c59e362521 fix(chart,reports): chart card hugs the drawing, symbol help as a bubble, sky button shows at once, report card spacing and copy (BUG-1100..1103)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 20:19:32 +08:00
Jesse_ChenandClaude Opus 5.5 ed3b223b1c docs(reports): English edition — design, voice, glossary, changelog, progress, device checklist; golden pair test
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 19:26:00 +08:00
Jesse_ChenandClaude Opus 5.5 d85ab9a2d2 feat(reports): generate card, jump to end, labelled export, TOC levels, table bands, export size; drop 字段 jargon (BUG-1092..1094)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 19:04:45 +08:00
jesse-uxandClaude Code 64aa0ec20c feat(chart): polish chart presentation and symbol explanations
Independent Staging Quality Gate / publish (push) Canceled after 0s
Independent Staging Quality Gate / validate (push) Canceled after 1m27s
Hide engine branding, gate supported divisional columns, align house cells, and add accessible symbol help. Reduce desktop chart width and stabilize the waiting slot.

Validated with 78 browser checks and 87 focused frontend tests. Full suite retains 29 identical baseline loader failures; no new failures.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-29 19:03:28 +08:00
Jesse_ChenandClaude Opus 5.5 ea21743b09 fix(rectification): stop spoken collect once the training gate opens (BUG-1084..1087)
Once the discriminator training gate is open, only choice cards are asked
and the range card goes out when they are exhausted; targeted lines, their
re-ask and guided windows no longer hold the card or invite more events.
Delivery body says how many choice questions were used instead of the event
fit percent; narration names an excluded cluster instead of "range
unchanged"; a delivered turn no longer carries a collect question.

Offline replay (v4, 3 radii x 2 directions): truth in range 20/20 in every
cell; guided-window injections give the same width in truth and opposite
directions, so red line 1 was revised by product to truth-in-range only.
Skill 10.0.31 -> 10.0.32 (10.0.31 kept as deprecated for pinned cases).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-29 10:06:57 +08:00
Jesse_ChenandClaude Opus 5.5 9686dfb945 feat(onboarding): no hint toast after the first-chart star convergence
Independent Staging Quality Gate / validate (push) Failing after 10m40s
Independent Staging Quality Gate / publish (push) Skipped
Product 2026-09-29: drop 「这片天空在星盘页可以保存。」. The chart page entry is now replay + share.
Verified: tsc 0, lint 0 errors, npm test 4335/4280/24 (same 24 Docker/DB/deploy names),
quick gate (gate params) passed, / Static, first-screen JS gzip 651,512 -> 651,143.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 09:24:00 +08:00
Jesse_ChenandClaude Opus 5.5 447a19b561 feat(report): drop the report sky cover; docs, checklist and progress for M1–M5 (M5+M3)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 08:41:27 +08:00
Jesse_ChenandClaude Opus 5.5 60b5542b7d feat(birth-sky): the chart page replays the convergence, holds on the poster, shares top right (M4)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 08:41:27 +08:00
Jesse_ChenandClaude Opus 5.5 c61095b1eb fix(chart): the secondary page column may shrink, so the chart fits a phone (M1, BUG-1083)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 08:41:27 +08:00
Jesse_ChenandClaude Opus 5.5 cfed06822f feat(reports): drop the report centre intro; docs for self edit and account menu (S3+S4)
「我的报告」 starts at 报告记录: the supporting paragraph and the overview
line are gone. CHANGELOG, DESIGN, the real-device checklist and PROGRESS
for TASK-self-edit-avatar-menu-20260928.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:50:22 +08:00
Jesse_ChenandClaude Opus 5.5 c15def0c50 feat(sidebar): the avatar opens the account menu on every page (S2)
Off / the footer was a plain link home. It is now the same Menu.Root
everywhere; off / its dialog entries link to /?account=<dialog>, which
Home opens once its account is ready and drops from the URL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:43:43 +08:00
Jesse_ChenandClaude Opus 5.5 8415fdca72 fix(people): 本人 can edit their own birth data in 星盘档案 (S1, BUG-1081)
The owner had no edit entry anywhere once /people replaced the settings
chart pane. 本人 now gets 编辑 with the same form; the save goes through
PATCH /api/account via a shared lib/self-profile-save.ts that the home
onboarding also uses. The dead saveProfile is removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:43:43 +08:00
Jesse_ChenandClaude Opus 5.5 dec36bce01 feat(birth-sky): poster-only dialog, date/time/city caption, slower reveal, paywall on first refused send (P1–P5, BUG-1080)
TASK-birth-sky-polish-20260928.
- P1: chart page dialog shows only the picture on a dimmed stage, 「保存图片」 below, icon × in the corner.
- P2: BFF returns one server-built `caption` (「1994年5月18日 07:40 · 杭州」); printed under the fact line in all three places; adopted time adds 「 · 校正后」.
- P3: convergence 3 s + words 2.5 s + fade 1 s; settled frame still equals the exported cover.
- P4: redeem paywall no longer opens when the starter home appears; first send refused for credits opens it, later ones open billing; convergence dialog portalled to <body>. BUG-1080 investigating (Chrome repro rules out the overlay covering the convergence).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:03:46 +08:00
Jesse_ChenandClaude Opus 5.5 731c3b364b feat(onboarding): first-chart reveal becomes a star convergence, no buttons (F4)
TASK-birth-sky-followup-20260928 F4:
- pure timeline / seeded scatter / interpolation in lib/birth-sky/converge.ts;
  drawBirthSky takes an optional frame (positions interpolated, alphas
  multiplied) so the settled frame is the exported cover call for call
- lazy full-screen <dialog> overlay driven by requestAnimationFrame at
  viewport x DPR; tap / click / Esc end it; reduced motion only fades
- data, serif and overlay chunk must all arrive inside the 3 s budget,
  otherwise skipped silently; page.tsx wiring unchanged
- one sonner hint after it ends; dialog reveal variant (继续, is-reveal) removed
- DESIGN §17, VOICE, CHANGELOG, checklist, PROGRESS with verification

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-28 22:07:01 +08:00
Jesse_ChenandClaude Opus 5.5 a9a917d50c feat(report): birth-sky report cover bound to the report's birth fingerprint (F1–F3)
Product decision A (TASK-birth-sky-followup-20260928):
- every generation path writes subject.birthFingerprint (stored-row
  fingerprint, same function as the chart page's profileFingerprint);
  never into the evidence bundle the model reads
- GET /api/reports/:id compares on the server and returns only
  report.coverSubject (subject id or null); legacy reports never get one
- report page shows the night cover above the body, paper cover alone on
  the first printed A4 page; silent on any failure, no waiting state
- TS / JSON schema / Python contract accept the optional field
- BLOCKED T5 struck through; DESIGN §17, CHANGELOG, checklist, PROGRESS

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-28 21:47:44 +08:00
Jesse_ChenandClaude Opus 5.5 14ef18ac24 feat(onboarding): one-time 「那一刻的天空」 reveal after the first own chart (T6)
After saveOnboardingPlace succeeds (and the next step is already set), the
new useBirthSkyReveal hook fetches /api/birth-sky?subject=self and paints
the cover; if that finishes within 3 s the chart page's dialog fades in
(600 ms, none under reduced motion) with 「继续」. Timeout or failure is
silent, no retry; closing touches only the reveal's own state. Home() gains
no useState/useRef; page.tsx only wires. Family profiles and profile edits
never trigger it.

Also caps the dialog image by viewport height (the percentage max-height did
not resolve inside the flex/grid cell), and completes PROGRESS, DESIGN §17,
CHANGELOG and the real-device checklist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 20:47:35 +08:00
Jesse_ChenandClaude Opus 5.5 028aef2737 docs(report): birth-sky report cover blocked — no birth binding on reports (T5)
Report rows, report documents, jobs, sections and appendices carry no
birth-data fingerprint (request_fingerprint excludes birth data;
calculation_hash is an engine result hash or the markdown sha256). Per the
brief the cover is not shown rather than drawn from the current profile.
reportView, the report page and print styles are unchanged. BLOCKED.md lists
the evidence and two options for the product owner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 20:28:22 +08:00
Jesse_ChenandClaude Opus 5.5 d277cbd8ad feat(chart): 「那一刻的天空」封面 — engine, BFF, canvas painter, chart header entry
T1 scripts/birth_sky.py: real alt/az of the seven visible grahas (swe.calc_ut +
swe.azalt, geometric altitude, azimuth converted from swe's south origin to
north-east) and Yale BSC5 stars V<=4.0 (IAU 1976 precession); phase
day / twilight_morning / twilight_evening / night. Thin POST /api/birth_sky
registration in do_POST (no new handler method, no __new__).

T2 GET /api/birth-sky?subject=: birth truth read server side through
loadSubjectBirth + prepareChartViewProfile; zod contract; no billing, no
writes, no birth data in the response.

T3/T4 lib/birth-sky: sentence table, pure Canvas 2D drawBirthSky (night /
paper palettes from DESIGN tokens, east on the left, serif headline with
1.5 s font wait), PNG export via navigator.share or Blob + a.download.
Chart page prefetches and paints the cover once the chart is ok; the header
button appears only when the PNG is ready. Dialog is a lazy chunk.

T7 DESIGN §17, VOICE, CONTEXT glossary, CHANGELOG, real-device checklist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 20:27:40 +08:00
Jesse_ChenandClaude Opus 5.5 6c421219a1 feat(ui): headings use self-hosted Jyotisha Serif SC, body stays sans (T2-T5)
- --font-display leads with "Jyotisha Serif SC", then exactly the body
  sans stack; no system 宋体 or generic serif (BUG-737 guards kept).
- serif-sc.css imported from site-styles.ts beside globals.css (root
  layout also serves admin); swap, no preload.
- Long-form report title (.personal-report-md-article h1) takes the
  heading face; deliberate sans headings pinned by a new contract test.
- font-stack-loadable-contract: loadable now includes self-hosted
  @font-face with existing files; "no CJK serif" replaced by
  "leads with Jyotisha Serif SC, never a system 宋体" (brief T3).
- DESIGN §3, BUG-737 note, CHANGELOG, device checklist, PROGRESS.

TASK-serif-headings-20260928 T2-T5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 19:48:43 +08:00
Jesse_ChenandClaude Opus 5.5 fa58df16eb docs(ui): BUG-1079 progress, design, bug history, changelog, device checklist, contrast harness
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 17:42:23 +08:00
Jesse_ChenandClaude Opus 5.5 36fae8fabf fix(reports): header 「生成报告」 joins the report disabled-button rule (BUG-1078)
The generate button renders in SecondaryPageShell's actions slot, outside the
report roots, so while submitting it still got the global 45% fade. A
report-owned `report-center-generate` class brings it into the disabled rule;
SecondaryPageShell and button.tsx unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:54:53 +08:00
Jesse_ChenandClaude Opus 5.5 873fac8a5b feat(settings,reports): six ayanamsa options; report-scope solid button colours (T6/T7, BUG-1078)
T6: offer True Citra and Fagan-Bradley beside Raman/Lahiri/KP/True Pushya,
engine-supported values only; widen profiles_ayanamsa_check by an additive
migration; ephemeris note names; path tests so no new value falls back to
Raman.

T7: the unlayered `button { color: inherit; }` beats Tailwind's
text-primary-foreground, so solid report buttons showed page ink (light
(light 4.85:1, dark 5.77:1), grey disabled without fade, neutral selected
preset. button.tsx and theme tokens unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:54:53 +08:00
Jesse_ChenandClaude Opus 5.5 856dab6c55 docs(chart): progress, BUG-1076/1077, design, glossary, changelog, device checklist for chart types (T8 chart part)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:52:40 +08:00
Jesse_ChenandClaude Fable 5.1 891e9c62da fix(consult): paced settle is opt-in for the consultation reply; one rejection path for HTTP bodies and stream events (T2/T3 follow-up)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:28:37 +08:00
Jesse_ChenandClaude Fable 5.1 3f8b817261 feat(consult): type out streamed text at a capped pace and write the tail out on settle instead of one frame (T3, BUG-1075)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:14:46 +08:00
Jesse_ChenandClaude Fable 5.1 86d99115c6 feat(consult): show the queued row from the send frame; only smalltalk replies are quiet (T1, BUG-1074)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:09:41 +08:00
Jesse_ChenandClaude Fable 5.1 2b435f11d0 docs(consult): records for answer-the-question — BUG-1070~1073, VOICE/DESIGN, changelog, device checklist, progress
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 23:31:44 +08:00
Jesse_ChenandClaude Opus 5.5 d79dada970 feat(ui): optional gender radio in the people form and 个人资料 (T2)
One ProfileGenderField (女 / 男 / 不填, 44px, one hint line) in the
people-archive edit form (saved with the form, 不填 → null) and in
设置 → 个人资料 for the owner (saves on its own PATCH; birth-data saves never
send gender). The detail card shows 性别 (未填 when empty). Not asked in
onboarding. DESIGN/VOICE updated; 390/1280 screenshots with fictional data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 18:30:58 +08:00
Jesse_ChenandClaude Opus 5.5 8097adca8f docs: evidence card v2 records (PROGRESS, checklist, CHANGELOG, BUG-1060)
TASK-consult-evidence-card-v2-20260927 T5. PROGRESS with the native-module
table, the final per-card table, before / after sizes (3 public AA charts x
12 questions, all single-domain turns <= 12,000), red-line tests, failure-name
comparison and three-column edits; real-device checklist; CHANGELOG; task
index row set to 待验收; VOICE / DESIGN name the new lookup labels (no UI
change); BUG-1060 investigating (Double Transit D9 house target reads the D9
lagna; not fixed here, red line 1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 17:01:11 +08:00
Jesse_ChenandClaude Opus 5.5 84eb23152a feat(rectification): remove the rectification regenerate button and endpoint (BUG-1056)
T2 of TASK-rectification-grounding-20260927 (product decision P1).
The rectification 「重试(重新生成)」 was a blind agent.generate rewrite that
persisted unchecked text (invented range / fit rate reproduced). Removed:
the regenerate route, regenerate-turn.ts, the regeneration agent and its
read-only tool set, the client regenerate action/state and the
regenerating/canRegenerate props. ChatMessageActions renders the regenerate
button only when onRegenerate is passed; ordinary consultation is unchanged.
The DB function regenerate_agentic_rectification_turn is kept (AGENTS §7.6,
retire in a later round). DESIGN.md / VOICE.md updated; source-contract
tests follow with 原值/新值/原因 notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 03:28:27 +08:00
Jesse_ChenandClaude Opus 5.5 cb3ee55837 feat(consult): one read-only evidence lookup per turn; settle open clauses at tool calls (BUG-1059)
read-consultation-evidence returns one closed-enum section (a formal varga,
research/extended vargas, a Western layer, yogas, Ashtakavarga, Shadbala,
transits, Chara Dasha, arudha, karakas, KP, gulika, kakshya, mahadashas,
thematic evidence) from this request's finished calculation, never
recalculates, answers unavailable on a cache miss and refuses a second call.
The receipt records the step and the write row shows 「正在多看一眼:…」.
A lookup after answer text went out keeps the released text whole: a verbatim
restart is dropped as it arrives (40-char confirmation), a continuation is
kept, and settlement still reads the step that wrote the answer; the lookup
runs on the answer clock without resetting it. A length continuation carries
the lookup result with the card. BUG-1059: the visible-text transformer's open
clause is settled at each tool call, so unpunctuated narration no longer
leaks into the answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 02:54:11 +08:00
Jesse_ChenandClaude Opus 5.5 eef0cb7486 fix(consult): write the answer in the step that saw the chart (BUG-1053)
The natal loop's step after run-jyotish-consultation saw the evidence, but
its text was drained and a second, blind compose stream (history + question
only, empty findings) wrote the user-visible answer. Remove compose,
interpret and the drain; keep the loop's own final-step text.

- stepScopedAnswer: per-step holding; text of a step that calls a tool is
  dropped, so narration around tool calls never reaches the answer
- writing shape (opener + four headings) moves into the user turn
- length continuation receives the calculation result; Pass 4 whole-answer
  reject retries through retryForAnswer with the rewrite hint
- createConsultationRunClock: tools keep the 110s tool phase; the loop is
  handed to the 70s answer clock when the calculation result arrives
- settlement judges the step that wrote the answer (BUG-1051 kept)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 01:01:38 +08:00
Jesse_ChenandClaude Opus 5.5 d2551437c4 fix(home): land on the blank starter home after login and on bare / (BUG-1052)
Product decision 2026-09-27 (D1-D4), overriding the BUG-1038 login-return
stash and the "latest session" default landing:

- A full load of / without ?c= (login, typed address, bookmark, refresh of
  bare /) lands on the current person's blank starter home; an existing
  empty draft of that person is reused, otherwise one is created locally.
- ?c= and ?new=1 are unchanged; a refresh inside a conversation keeps its ?c=.
- The login-return stash is removed: redirectToLogin and sidebar links no
  longer write it, bootstrap no longer reads it and clears a leftover value
  once. replace-selected, the lookup origin/other-subject branch and the warm
  resumeRectification dependency go with it.
- A background answer being recovered no longer takes over the blank home
  (same rule BUG-1015 set for ?new=1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 00:51:51 +08:00
Jesse_ChenandClaude Opus 5.5 8fc1a5bded fix(rectification): plain-word opening with examples in the stem, plain de-duplicated step receipt (BUG-1049, BUG-1050)
- BUG-1049 (recurrence of BUG-504): the opening stem carries six examples and
  an example answer again and is server-owned on the zero-evidence opening;
  the body is two plain sentences (no 大运/盘面/代表分钟/精确到秒, no year, no
  question). Stem de-dup compares whole sentences / near-equality instead of a
  12-char prefix, which had deleted the body's examples sentence since
  aa7ccb30 (BUG-604) + dd8f35f7 (BUG-648).
- BUG-1050: plain step labels; a finished step label shows once and
  「已完成 N 步」counts shown rows; failed rows read 「…未完成」 from the
  in-progress wording.
- Skill 10.0.30 -> 10.0.31 (OpeningPolicy); 10.0.30 kept as deprecated.
- VOICE / DESIGN / CHANGELOG / BUG_HISTORY / PROGRESS / real-device checklist
  and screenshots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 22:04:56 +08:00
Jesse_ChenandClaude Opus 5.5 3a66c39f48 refactor(rectification): split the chat component into hooks, parameter functions and blocks
Move-only (TASK-rectification-code-split-20260926 T1/T4). No behavior, API,
copy, DB, Skill or scoring change.

- rectification-agentic-chat.tsx: 2043 -> 737 lines; component body
  1625 -> 630; useState 35 -> 12, useRef 16 -> 9, effects 9 -> 5,
  useCallback 12 -> 6.
- Snapshot sync -> hooks/use-rectification-case-snapshot.ts; board layout
  and live label clock -> two small hooks.
- send / submitStructuredChoice / acceptCandidate bodies ->
  lib/rectification-chat-{turn,choice,accept}-run.ts parameter functions
  (bodies verbatim, deps destructured to the same names); copy/regenerate,
  question repair, pure transcript and snapshot helpers and the per-render
  view derivation -> lib/rectification-chat-*.ts (no React hooks).
- Question-gap blocks and the read-only range line ->
  components/rectification-question-gap-notices.tsx.
- Dependency arrays kept exactly as before (lint warnings +3, listed in
  PROGRESS); no dep added to appease the linter.
- Tests: whole-source contracts read tests/rectification-chat-surface.ts
  (container + split files, like home-surface.ts); slices of moved code now
  call the extracted functions or render the extracted block, each with a
  原值/新值/原因 comment. New tests/rectification-growth-contract.test.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 19:23:52 +08:00
Jesse_ChenandClaude Opus 5.5 d0bfc1fc3d feat(rectification): anonymous aggregate telemetry + admin summary page
One row per rectification Case, written once when the range card is first
delivered (GET /api/rectification/cases/[caseId], fire-and-forget after the
response is built). Numbers and closed enums only: no user / case / session
id, birth data, names, text or timestamps finer than the ISO week. Dedupe via
a separate case_id ledger that cascades with the Case (and account deletion).

Migration 20260926010000 is additive: two RLS tables with no runtime table
grants, SECURITY DEFINER write (service_role), purge (service_role) and
aggregate-only summary (admin_runtime) functions; 180-day retention.

Admin: 「校正统计」 page + GET /api/admin/rectification-telemetry
(admin.customers.read), aggregates only, no per-row view or export.

TASK-rectification-telemetry-20260926. test:db not run locally (no Docker).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 15:36:29 +08:00
Jesse_ChenandClaude Opus 5.5 7203d94e9c fix(rectification): 区分不开时不显示「最可能」副标题(验收补改)
Independent Staging Quality Gate / validate (push) Successful in 11m49s
Independent Staging Quality Gate / publish (push) Successful in 3m44s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 14:45:11 +08:00
Jesse_ChenandClaude Opus 5.5 4e6e8d87ef feat(rectification): 少问几道就出卡,交付卡以范围为主(D1–D4)
- D1 引导窗口题每个校正最多 2 道(前端 GUIDED_WINDOW_CASE_LIMIT;引擎
  GUIDED_COLLECT_LIMIT 未动:event_probes.py 属冻结评分身份,改它需重新冻结)
- D2 七条定向线与跳过线重问问完即出卡,没问到的引导窗口不再挡卡,出卡后也不再挂窗口题
- D3 卡头加副标题「最可能 HH:MM」
- D4 前两列相差 ≥5 个百分点才显示相对可能性,否则一句「这几个时刻目前区分不开……」
- 离线回放 scripts/research/fewer_probes_card_replay.py:真值不降、宽度中位 ±1 分钟、提问 11.4→7.8
- Skill 10.0.29 → 10.0.30;DESIGN / VOICE / CHANGELOG / PROGRESS / 真机清单

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 14:27:12 +08:00
Jesse_ChenandClaude Opus 5.5 ab0f01a9cf fix(rectification): stream-first typed turns, 10 s classifier cap, stage progress, run timings (BUG-1047)
- D2: each intent-classifier attempt is capped at 10 s (same session model,
  thinking untouched); a hang takes the existing retry -> classifier_unavailable
  path. Success is timed too (RectificationClassifierDiagnostic).
- D3: a typed message builds the NDJSON stream first; the first line is
  turn.progress "received", then the classifier and deterministic replies run
  inside the stream. Preflight rejections become turn.rejected (old status,
  code, message) and the client handles them like the old HTTP rejection.
  Stage lines 收到,正在对照你的档案… / 正在记下这件事… / 正在重新对照盘面… /
  正在准备下一个问题… are driven by existing tool events and engine calls, are
  transient (live row only) and never persisted. VOICE / DESIGN updated.
- D4: RectificationRunDiagnostic records per-step start/end, provider token
  usage incl. reasoning tokens, classifier timing and per-engine-call
  durations (AsyncLocalStorage scope per turn); RectificationTurnDiagnostic
  for deterministic turns. No user text, birth data or model text.
- D5: /v5/versions memo (30 s, complete identities only, per transport); the
  exit gate skips its second persistNextInterviewIfIdle when the run's own
  call found the next focus already active (provably identical).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 11:45:47 +08:00
Jesse_ChenandClaude Opus 5.5 e4c1c7a342 fix(rectification): one stem per turn, one card per focus (BUG-1045/1046)
BUG-1045 (recurrence of BUG-585 via BUG-969): the snapshot merge now drops
the attached stem from the streamed "ack + stem" text with the same
stripQuestionSentences the GET route uses; server text unchanged.

BUG-1046: a failed choice submit (409 / network) or typed send withdraws
the local answered mark, remounts the card, re-reads the Case and shows
"这次没提交上,请再点一次。"; the persisted question hangs on the latest
settled assistant message with other copies of the same focus removed
(standalone block only when nothing can carry it); willContinue and the
send() settle merge unseen assistant turns (same gap as BUG-685).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-26 10:49:25 +08:00