Event scoring was measured at chance level on the 77 Rodden-AA holdout
cases (BUG-1091). The new flow finds the dividing line nearest the reported
time, describes how the flipped divisional charts read on either side, asks
up to five self-assessment questions, and saves the user's own choice
(provenance user_choice) with the domains to read in both versions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
The Python source contract still looked for the two useRef lines in page.tsx;
BUG-1642 moved them to module-level refs so a run outlives Home. Same types
and initial values, new location. This turned the staging gate red on
8c08ed74.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
- 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
The staging DB gate replays 20260814040000 on top of the new migration;
with claim_personal_report_job overloaded by a defaulted fourth argument,
a three-argument call became ambiguous. The lane now calls
claim_personal_report_job_for_types and the original stays untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
- 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
A ten-year career question got a timing section that stopped at the running
Vimshottari mahadasha and the running Narayana sign, so the answer padded the
decade with "no period available" sentences and could not compare the systems.
- API: dasha_sub_periods.next_mahadasha (next MD cut by the same
dasha_analyzer.build_antardasha); frozen engine files untouched.
- Card: every card carries the next MD and next Narayana sign; a question
that looks N years ahead also gets timing.horizon, the next MD's
antardashas, later MDs inside the horizon and two to four Narayana signs
with years, all copied from the engine.
- Goldens: only the new engine field grafted in (rest byte-identical).
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
Round 1 blind eval: answers narrated the sorting rule back
(「这两处一致,所以这一层可以算明显」) and sentences reading out counts went
28 -> 59 / 36. The clause now says a point goes under obvious only when
another placement backs it, and the sorting is not explained to the user.
VISIBLE VOICE stays at 2,182 characters.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
A staging career answer to a question naming D1 houses, D10, A10 and AmK
wrote every item as 「代表事业的那颗星」, half-excluded a field despite
「不凭星盘排除某个职业」, put over-certain points under 明显倾向 and read out
「两处受冲」. VISIBLE VOICE now says: items the user named are written as
named, with chart, sign, house and planet, a few plain words on meaning,
once each; the user's own framing wins (no sentence ruling a kind of work
or setting in or out when asked not to exclude; obvious only with two or
more agreeing placements). 受冲 joins the term-table words that are not
named, and the judgment table's count is not reported to the user. Voice
2,182 -> 2,174 (the pressure clause defers to the card lines; two copyable
comfort quotes and an optional numbering note go).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
The remaining 27 / 72 severe career answers turned the 10th lord's or
AmK's house into work content through the house life-area gloss (6th ->
handling problems, 8th -> taking on hard cases, 2nd -> talking and money)
and planet nature into working style (Mercury -> speaking and writing, D10
Saturn -> rules and process). The card's career `boundary` line now names
AmK and says the life-area gloss is not work content and planet nature is
not working style; the "how far" clause goes (the field-ask rule already
answers it with strength, resistance and timing). Line 135 -> 142.
A first version (a35f1847) also folded the rule's quoted 「不在台前」 list
and CAREER_SIGNIFICATOR_STRENGTH_RULE into the line; the blind eval had
severe 34 -> 52 / 72 with front-stage denials back, so the rule and
checklist stay as on staging.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
The remaining 27 / 72 severe career answers turned the 10th lord's house
into work content through the house life-area gloss (6th -> handling
problems, 8th -> taking on hard cases, 2nd -> talking and money), planet
nature into working style (Mercury -> speaking and writing, D10 Saturn ->
rules and process) and strength or SAV into scale. The card's career
`boundary` line now says what kind of work, how it is done and how big it
is are not on the chart, that the 10th / 10th lord / AmK / A10 / AL
placements only give where the career gets support, where it costs effort
and when it moves, and that the life-area gloss is not work content and
planet nature is not working style; what the user said stands.
CAREER_SIGNIFICATOR_STRENGTH_RULE folds into it and the field-ask rule's
A10 / AL clause points at it. Instruction size: rule 293 -> 196, career
checklist 870 -> 705, card line 135 -> 210 (net -165).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
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
The product owner asked to drop the settled step entry under answers
(「没啥用」). The live 正在分析 timeline above an answer being written stays;
the footer toggle, its step panel and their styles are removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
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