- The question queued during a reply lives in the session store, keyed by
chat and by the reply it waits for. A mounted Home sends it to that chat
once the reply completes, or puts it back in that chat's composer; nothing
is sent from another page with a stale Home closure.
- The full-chat notice's 开新对话 records a carry-over in the store and
returns to Home if needed; the mounted Home opens the new chat with the
question, linked to the full chat.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
- requestError and replyOutcome move from Home state into the session store;
a Home remount keeps them, a new session-list provider drops them.
- A stop or an uncommitted reservation hands its question back through the
store (composerRestore); use-composer-restore puts it into that chat's
composer whenever the chat is open, on the Home mounted now or later.
- While a stop is still being confirmed the question stays with the stopped
chat, so switching rows no longer loses it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
- Sidebar rows always open; a reply in flight locks only their menu and drag.
新建对话 is no longer locked by generation.
- The in-flight run's refs live in lib/consultation-run-refs.ts instead of
Home's useRefs; a Home remount keeps the store's run fields while a run is
live, so the Home that mounts on return attaches to the same stream instead
of starting a second recovery that the first closure then cleared.
- Completion drops the tab's pending-consultation record for that request.
- One reply at a time is unchanged (client send guard and queue).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
Every report type already queued in personal_report_jobs, one at a time per
server. The worker now runs PERSONAL_REPORT_WORKER_CONCURRENCY lanes (default
2); the second takes only annual and synastry reports so they never wait
behind long personal reports. claim_personal_report_job gains an optional
report-type filter; personal_report_queue_view (owner-only, security definer)
gives the wait, shown as a single line on the annual, personal and synastry
waiting screens. Also keeps the privacy whitelist line numbers in
personal-report-api.test.ts unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
The writer now reads houses as parts of life, turning points as plain sky
sentences and months instead of dates; a one-page guide with passages from
the approved sample replaces the ban list, and each section sees what the
earlier ones said. Areas are one paragraph plus a 记住 line; window cards
show topic and action with a folded plain 为什么.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
The 八分法 table is width 100% with fixed columns and full-width 32px cells (a
640px minimum keeps the drag on phones). The 瑜伽 tab lists all eight classical
yogas as a two-column grid: formed ones first and still a pick on the board,
the rest muted with their classical condition, in place of one sentence and a
collapsed 「未满足 N 条」.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
- 年运: the page no longer opens the finished report of the same range; only a
run still being written opens by itself. The server reuses only that in-flight
run; a finished year no longer blocks a new one, which is charged once like
any report. The start card says 「这一年已经写过一份,再写一份会另扣 N 点」
with a link to the last one; history still opens from 过往的报告.
- 星盘类型: from 768px the picker is a centred dialog (560px, full radius);
phones keep the bottom sheet. The body and the select / close logic are shared.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
The remaining phases and the windows render as one timeline: phases carry
the program's lean, each window is pinned to its phase, passed ones fold.
Window fields are capped so cards fit without an inner scroll; reports
written earlier keep the old layout. Writer rules and the gate keep dasha
and functional-role words, the counting method and the material itself
out of the body.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
Lean v2 is a weighted sum (AD 2, Narayana AD 2, PD 1; a tie follows the
Vimshottari AD) with only 偏顺 / 偏紧 / 平稳. Phases with both sides keep a
counterweight limit. Window, domain-window, year-end and remember evidence
carry the lean; the gate rejects mixed wording and a window lean that
contradicts the program.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
The sheet is now a top-to-bottom column with the footer pinned: 导出报告 and
the file type, a full-width 中文 / English segment, two equal radio cards for
整篇 / 自选 (outline and dot only, per issue #90), and in 自选 a title filter
with 全选 / 清空 above a tighter list with sticky group heads. The group names
and the summary follow the chosen edition (Chapters / Charts / Tables, 「95
chapters · 21 charts · 8 tables」); the sheet's own controls stay in the app's
language. Rows in the scrolling body no longer shrink.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
Product picked A / B / A on the canvas.
- 我的报告 (A): the full natal report is the one large card with a solid
生成报告; 年运 is a single row link under it. A report row's hover and focus
band now spans the link and its ⋯ menu, so a row no longer looks split.
- 年运 start (B): 生日年度 / 公历年 / 未来十二个月 are three single-choice
cards with a dot, a one-line hint, and the picked card's dates.
- Reader (A): SecondaryHeader gains `back` (‹ 我的报告 /) and the language
switch and 导出 move into it (ReportActions placement="header"); the second
bar is gone, the text is no longer in a card on screen (print unchanged),
the reading column is 720px and the contents rail opens only the current
chapter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
The report center passed onCreated={() => void load()}, so a successful create
only re-read the list below: no move, no notice, a faint 「正在创建…」 at most.
The button now holds the page curtain while it submits and opens the created
report, whose page shows the writing progress; an error drops the curtain and
says why. The 年运 page took the content's height inside the start-aligned
page grid, so its veil stopped short of the window bottom; it now fills the cell.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
Direction B for 「为什么不能直接进入生时纠正对话」. The open request, the case
read, the source lookup and the surface chunk now start at the click that
leads to the rectification chat (the /rectification page's 开始 / 继续上次 /
新建一次 / 看结果, and a 生时校正 row in the sidebar off the home), while the
app navigates. The home's openRectificationCase takes that in-flight open
(same target, once, within 30 s) instead of asking again; errors are handled
exactly as before. The offer card inside a conversation still asks itself.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
The /rectification page's 开始 / 继续 go to `/?rectify=…`; the home painted its
blank starter (「正在打开生时校正…」 in the composer) until the case opened
over the network, and a `?c=` rectification session showed the home the same
way until its surface opened. The rectification hook now knows a queued open
from the first render until it settles, and while a case is opening the home
holds the page curtain at once (new `immediate` hold, no 140 ms show delay) and
renders nothing. A failed open drops the hold and shows its error as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
Direction A from the layout canvas. The visible 北印度盘 title row goes (the
name stays for screen readers); row one keeps the chart type strip; row two
puts the caption (D1 · ascendant · degree) on the left and the 图层 menu plus
a compact 北 / 南 switch on the right. The caption loses its tinted 44px strip,
the degree never yields to the dasha chips (they shrink, then hide under
600px), and the drawing may grow to 720px. The skeleton follows the same two
rows; skeleton motion is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
Three contracts cut page.tsx's Enter handler at "\n\n if (!hydrated",
which became "const booting = …" when the home started holding the shell's
page curtain. Two failed in the staging gate (run #2196); the IME contract
passed only because indexOf returned -1 and sliced to the end of the file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
The renumber (093da446) changed comments in shadbala.py and both replay
scripts, so the frozen identity moved. On top of staging 849343cd:
FREEZE / REPORT constants first, --freeze, then replay:
astrologer_166d_2026_11_05; contract rotated with previous =
astrologer_166c_2026_11_05 (kept byte-for-byte).
Versus astrologer_166c_2026_11_05 and astrologer_166b_2026_11_04: sealed 20
and reported offset 900 all identical, metrics and summary identical,
historical changed_trial_count 10 / 731. Still scoring-15; no tuning.
BUG-1622 records the second re-freeze.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
Another session shipped a different BUG-1613 (loading curtain) to staging.
Mapping in order: 1613->1622, 1614->1623, 1615->1624, 1616->1625,
1617->1626, in BUG_HISTORY headings and bodies, CHANGELOG, ledger, research
notes, code comments, rule text, test notes and the holdout contract text.
Text only. shadbala.py and the two replay scripts are in the frozen identity,
so an ERR-110 re-freeze follows in the next commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
The quick gate's tests/test_python_hygiene_budget.py caps root scripts at 441
("locally written files must not increase"); the new module made it 442.
Moved to the subpackage scripts/arudha_reference/pvr_dual_lord.py; CLI
import tries both import styles; tests, BUG-1617 and the status table updated.
No frozen file touched; behaviour unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
shadbala.py (frozen identity) changed in 5ffef30a: labels, comments and the
shared mercury_malefic_companions() helper, no value change. Scoring identity
stays rectification-v5-matrix-scoring-15; no ALGORITHM_VERSION bump.
FREEZE / REPORT constants first, --freeze, then replay (after all code
commits of this branch, 09fd3a42): astrologer_166c_2026_11_05; contract
rotated with previous = astrologer_166b_2026_11_04 (kept byte-for-byte).
Versus astrologer_166b_2026_11_04, trial by trial:
- sealed 20: all identical; metrics identical (top-1 0.40, top-3 0.45, mean
minute error 6.95); historical changed_trial_count still 10.
- reported offset 900: all identical; summary identical (top-1 hits at
+-15/30/60 4/3/0, top-3 31/34/30, delivery coverage at +-15 219, mean top-1
minute error 20.52); historical changed_trial_count still 731.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
Astrologer 2026-11-05 (#166 comment 39249, item 1). No calculation change.
- jyotish_engine.VARGA_MOOLATRIKONA_BASIS = in_varga_degree_band_pending_review:
a D9 Moolatrikona is decided by the in-varga degree inside the D1 band;
whether / how Moolatrikona applies in vargas is pending. Written on each
d9_navamsa_expanded row (moolatrikona_basis) and on the consultation D9
summary (not copied to the evidence card).
- "V.P. Jain example" corrected to "PyJHora test transcription"
(pvr_tests.py::shadbala_VPJainBook_tests, no edition or page) in the data
audit notes and the competitive analysis (ERR-081 recurrence).
- astrologer_questions.md: status table of the seven 2026-11-05 items.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
- New ChartDrawLoader (direction B from the loader canvas): outer square,
diagonals, inner diamond drawn in turn, the lagna house lights, repeat.
Still under prefers-reduced-motion.
- PageCurtain moves into the app shell: in the server HTML, full window over
sidebar and page, held by usePageCurtain. Cold load shows it from the first
paint; in-app navigation shows it only after 140 ms (pages already in memory
never flash it), keeps it at least 650 ms, fades in 360 ms; one hold lets go
after 12 s. The main.app-loading DOM contract is kept for the first-paint
fallback and stale-client recovery on every page.
- Held by: home (with the natal panel), chart (first entry only), people,
reports list, opening a report, ephemeris, annual, rectification entry,
synastry picker. Home's own curtain (boot-curtain.tsx) is removed.
- The in-page waits that remain (dasha layer, people dropdown, birth editor,
birth-time assessment, report and synastry writing) use the same motion at
small size. Skeletons keep their motion: switching person, system or layer
on the chart still shows them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
The career rewording did not clear the blind-eval bar (severe 43 -> 36, CI
includes 0; claims moved to 「不在台面上」). CAREER_FIELD_ASK_RULE, the AL
checklist line and their test go back to 928aa5c6. BUG-1620 is marked for
staging, BUG-1621 stays investigating (next: a server card line).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
- The cold-boot loader now covers the whole window (sidebar, chat, natal
panel) and fades off the finished page instead of cutting to it.
- The natal panel's code and chart load behind the curtain and count in the
reveal gate (same 4 s prepare budget); the home HTML sends the chart read
in its first round, and ChatChartFrame takes the preloaded module in its
first render.
- Before the viewport is measured the shell frame is "pending" and sized by
media query plus the remembered width (sync <head> script), not by its
content, so the sidebar no longer starts ~184px wide and jumps.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
Every node process that imported skill-package-registry left a
jyotisha-skill-runtime-* directory in the OS temp dir (9,933 on the shared
host, most of them empty), which helped exhaust inodes (ERR-117).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
The page swapped the saved partial snapshot for the skeleton as soon as the
report turned failed. Render the snapshot whenever it exists; unwritten
sections say so instead of shimmering. Log the error class before the
section failure is folded into model_unavailable.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
CommonMark will not close `**` after punctuation when a CJK character
follows (`**…这两件事。**火星`), nor open it after a letter before
punctuation (`说**「…」**`); with two such spans in a paragraph it pairs the
wrong runs. New in-repo remark plugin `remarkCjkStrong` (no new dependency)
runs after remark-gfm in the chat, learn and personal-report views: it
re-pairs leftover `**` runs in reading order into strong nodes, spanning
links and inline code but never a line break, `*` or another strong. Lone
`**`, escaped asterisks, inline code and code blocks are untouched. One
linear pass per parent that still holds a `**`.
Tests: 11 cases through the real chat renderer, including 20 real backtest
answers (public figures) that render with no literal `**`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
The user reported the 「添加一个人」 dialog could not be clicked or typed into.
Reproduced in headless Chrome with real CDP input: elementFromPoint over the
name field returned the last birth-time-source radio. RadioGroupItem enlarges
its hit area with `after:absolute after:-inset-*`; globals.css forced that radio
to `position: static` and the card was unpositioned, so every radio's ::after
spanned the fixed dialog and 「完全不知道」 took every click (from 728ead88, #110).
Not a BUG-968 recurrence: the dialog is portalled to body and nothing is inert.
- Card and radio positioned; the sr-only legend no longer stretches 100%
(horizontal scrollbar); the body is the legend's containing block (hidden
vertical overflow that could push the header away).
- Hover is a quiet wash inside @media (hover: hover); focus shows a ring; only
the selected card has the action border + soft fill (ayanamsa and time source
hovers used the selected colours).
- Prototype (https://claude.ai/artifact/4herLiTdD3fmYoMB62bnBE, approved
2026-11-05) in ChartProfileForm, shared by the people dialog, the chart
page's birth editor and (time block) onboarding: fixed header with its own
close and fixed footer with a 「还差:…」 hint; groups 基本信息 / 出生日期与地点
/ 出生时间; 「如何称呼 TA」 for others; ayanamsa folded into a <details>
「高级设置」; bottom sheet at <=640px. Class prefix person-form-dialog
(.profile-dialog is a retired sheet name a test keeps out).
Verified: headless Chrome at 1440 / 390 on all three surfaces (every control
hit-tests to itself, typing works, scrollWidth == clientWidth, header/footer
fixed). New tests/add-person-dialog-20261105.test.tsx; profile-gender test
order updated with 原值/新值/原因. Full npm test failures identical to staging
3d10a5bc (28, env / DB), tsc clean, ESLint 0 errors, pytest quick gate passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8