Commit Graph
3585 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 cd0463ea4f fix(annual): name the overlay modifier is-veiled, not has-veil
A `has-` class made `has` a project class family, so the class contract
started flagging the long-unstyled `has-title` in secondary-header.tsx.
The repo's modifiers are `is-…`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 20:25:42 +08:00
Claude 5b566af981 Merge annual report generation and entry overlay (#153, #154)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y

# Conflicts:
#	CHANGELOG.md
2026-11-01 20:20:47 +08:00
ClaudeandClaude Opus 5.5 ab0de9e842 feat(annual): annual report page with the start overlay (#154)
/reports/annual opens the annual report directly. A translucent overlay
shows the range, 「某人的这一年」, the three notes, the birth-time line
(self links to rectification), the short 现状 form, 「开始写年运」 and the
price line; then sections stream in as they are saved, and a year
already written opens without the overlay. 「我的报告」 gets the annual
card. Docs: design note with every default pending astrologer review,
DESIGN.md, VOICE.md, CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 20:15:45 +08:00
ClaudeandClaude Opus 5.5 4972fa40a6 feat(annual): annual report generation and annual.full billing (#153)
New report type annual_full on the personal report queue, like
synastry_full. POST /api/reports {reportType: annual_full} reserves
annual.full (20 credits by default, admin-editable), stores the range
and the optional situation, and queues the job; a year already written
for the same subject opens directly without a second charge. The worker
asks /api/annual/report_facts for the server cards, writes the sections
one at a time (person, overview, domains, windows, remaining, close)
with a program gate and one rewrite, saves the snapshot after every
section, then settles; a failure releases the reservation.
GET /api/annual/overview serves the overlay from the slim package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 20:15:45 +08:00
Claude 80dc28a49a Merge #160 rectification for other people into staging integration
Independent Staging Quality Gate / validate (push) Failing after 13m11s
Independent Staging Quality Gate / publish (push) Skipped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y

# Conflicts:
#	CHANGELOG.md
#	frontend/src/components/chart-page/chart-page-view.tsx
2026-11-01 17:32:14 +08:00
ClaudeandClaude Opus 5.5 7512d3d654 test(audit): the capability audit scans the /learn routes (issue #157)
The app route list is asserted exactly; /learn and /learn/[column]/[slug]
are new public routes from the knowledge base framework.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:31:25 +08:00
ClaudeandClaude Opus 5.5 46273a169e docs: rectification for other people (issue #160)
CHANGELOG, DESIGN, VOICE, onboarding red line 11 lifted, pre-work
ledger entry for this session's blocked checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:26:04 +08:00
ClaudeandClaude Opus 5.5 ee08562471 feat(rectification): rectify other people in the profile list (issue #160)
Product 2026-11-01: 1A 2A.
- Cases record whose chart (chart_profile_id, null = owner); add-only
  migration 20261101010000_rectification_chart_subject.sql, old cases stay
  the owner's.
- Adoption / confirmation / segment adoption / VedAstro refresh read and
  write that person's row through two helpers; the owner's profile and
  cases are untouched. Owner edits rebaseline only owner cases, person
  edits only that person's; a new declaration drops the adopted minute.
- Open cases are counted per person (entry summary v2, in-chat offer,
  resume lookup); open_agentic_rectification_case_v3 binds a new case and
  its conversation to the person.
- delete_chart_subject deletes the person's cases and their
  conversations first (no refund).
- /rectification follows the current person (switcher beside the title),
  shows name and relation; self-only limits removed (hook, chat offer,
  chart ascendant link, starter hint).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:26:04 +08:00
ClaudeandClaude Opus 5.5 1643bad25b feat(annual): report facts and claim cards; slim package (#153)
/api/annual/report_facts returns the annual report's only allowed facts:
natal base (functional roles, house lords, yogas as structure, domain
vargas and A10/A7/UL/DK), the year's phases with a lean from the natal
skeleton lords' functional roles, turning points, 4-6 candidate windows
from computed boundaries and exact contacts (independent systems only),
per-domain signals, conflicts and the technique audit with MEVG and Real
Case Calibration blocked. Open defaults sit in CONFIG / HOUSE_DOMAINS.
The package gains detail=slim for the entry overlay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:24:39 +08:00
Claude 850b6544ae Merge annual data package v1 (#152 ruling, phase 1 of #153)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y

# Conflicts:
#	CHANGELOG.md
2026-11-01 17:14:18 +08:00
ClaudeandClaude Opus 5.5 68e1ab175e Merge #157 knowledge base framework into staging integration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:14:09 +08:00
ClaudeandClaude Opus 5.5 340f0f2b85 feat(annual): annual data package v1 (#152 ruling, phase 1 of #153)
POST /api/annual with mode=package (or /api/annual/package) returns one
versioned package built from the existing producers: year charts with
ascendant/lord, Muntha, Panchadhikari year lord, annual strength, Sahams,
Tajika yogas, Tripataki, Mudda, native Patyayini, Tajika monthly charts;
natal Vimshottari MD/AD/PD and Narayana (legacy + Rath); slow-planet
ingresses, stations, retrograde loops and natal-point crossings; Tithi
Pravesha as an independent view. Report range, year-chart validity and each
period system's own year are separate, every boundary is an exact instant
with timezone, and every block carries computed/blocked/not_applicable with
a reason. The default /api/annual response is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:07:54 +08:00
ClaudeandClaude Opus 5.5 52f85a793f fix(annual): pass node_mode to the solar-return charts (BUG-1501)
calc_solar_return_chart hard-coded the mean node for the birth and annual
charts, so node_mode=true never reached the annual Rahu/Ketu. The default
stays mean; cmd_solar_return and cmd_tajika now pass the request's mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 17:07:54 +08:00
ClaudeandClaude Opus 5.5 72854ba9f3 feat(learn): 印度占星知识 /learn with Markdown articles (issue #157)
Public, statically generated knowledge pages from the approved prototype:
/learn lists 全部 plus seven columns with question titles and one-line
summaries (a sideways row on phones); /learn/<column>/<slug> renders the
question, the one-line answer, reviewer and date (or 「初稿 · 待占星师审校」),
the Markdown body, 「我们采用的口径」, 「在 Jyotisha 里看」, 「接着读」 and
参考出处.

Articles are frontend/content/learn/*.md with the frontmatter template from
the issue, read by a small parser and validated with zod; a bad file fails
the tests and next build with the file name and a reason. Drafts are
readable but noindex and stay out of sitemap.xml. robots.txt opens only
production. The web image copies frontend/content before the build.

Ships the one example article 「生时校正能做到多准?」 as an unsigned draft.
The chart page's ascendant line links it while the ascendant can still
change, through a 盘面要素 → 文章 table that only links existing articles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 14:28:44 +08:00
ClaudeandClaude Opus 5.5 348fedc6a8 fix(chart): ascendant dignity cell in 盘面数据 explains itself like the natal table
The new planet table wrote a bare 「—」 for the ascendant's dignity. It now
reuses AscendantStatusCell inside ChartSymbolHelp, so hover, focus or tap
shows 「上升点是命盘的起点,不是行星,不判断入旺或落陷」 as the natal table
has since 2026-10-25.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-01 14:12:02 +08:00
ClaudeandClaude Opus 5.5 5157f96df3 feat(chart): 盘面数据 card beside the board, linked both ways
Independent Staging Quality Gate / validate (push) Successful in 29m39s
Independent Staging Quality Gate / publish (push) Successful in 4m3s
The chart page's tables move into one fixed-height card beside the board
with nine tabs: 行星, 虚星, 特殊点, 映射, 八分点, 星力, 大运, 敌友, 瑜伽.
The point tabs and 八分点 are the board's layers, switched together from
either side. 星力, 大运, 敌友 and 瑜伽 mark, tint, link and fade bodies on
the natal board (lib/chart-board-focus.ts).

The planet table gains the ascendant row, nakshatra lord, pada and the
seven Chara karakas, now produced by /api/chart_points from
jaimini.calc_chara_karaka_7 (blocked on a tie). Every card keeps a fixed
height and scrolls inside; tables never wrap and can be dragged sideways.
Hint captions are gone, 八宫点 reads 八分点, and the deep reading keeps
time, energy and birth data only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-10-30 16:27:04 +08:00
ClaudeandClaude Opus 5.5 2df7645d2c feat(chart): rename the 无图层 layer option to 基础星盘
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-10-30 15:38:28 +08:00
Jesse_ChenandClaude 172178cdbd Merge origin/staging into D60 study (issue #149)
Independent Staging Quality Gate / validate (push) Successful in 20m20s
Independent Staging Quality Gate / publish (push) Successful in 4m21s
Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-29 16:44:50 +08:00
jesse-uxandGrok (agent loop) 3bc82acba6 research(d60): ship the G2/G5 script and report per-switch flips (issue #149)
The G2 precheck and the G5 noise floor had only a results file; the script
that produces them is now in scripts/research/d60_two_way_g2_g5.py, with
a test that reproduces the committed JSON byte for byte.

G5 is now reported per switch, with the ayanamsa offset in arcminutes.
Against the Raman baseline all three alternatives flip 77/77. Between the
alternatives themselves the number follows the offset: Lahiri to KP 21/77
(27.3%, 5.81'), KP to True Chitra 19/77 (24.7%, 5.02'), Lahiri to True
Chitra 2/77 (2.6%, 0.83'). The report says so and no longer claims that
any frame change flips every chart; the registered gate is baseline
relative and still triggers.

The report also states that G2's "not evaluable" comes from the registered
same-day answer policy, not from a measurement that D60 does not help.

Co-Authored-By: Grok (agent loop)
2026-10-29 16:32:54 +08:00
Jesse_ChenandClaude 09620c6e0a docs(tasks): D60 study second half, first rejection (agent loop, issue #149)
The G2-G5 results came without the script that produced them, so G5's
77/77 ayanamsa flip cannot be replayed. Commit the script, report G5 per
alternative ayanamsa, and say that G2's zero questions came from the
same-day scoring rule the planner chose.

Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-29 16:14:25 +08:00
jesse-uxandGrok (agent loop) 028992257b research(d60): G2 not evaluable, G5 trips the noise floor (BUG-1497, issue #149)
The registered same-day answer policy needs an event dated on the birth day;
the v5 holdout has none in any of the 77 cases, so group B adds no question
and is identical to group A. G2 is therefore not evaluable by construction,
not a measured zero, and no placebo test has a lift to check.

G5 is measurable and decisive: switching the ayanamsa from Raman to Lahiri,
KP or True Chitra changes the ascendant D60 sign in 77 of 77 cases (100%,
threshold 20%). Under the registered stop rule any minute-level wording is
forbidden.

Recommendation: do not adopt. D60 stays reference-only and the external copy
does not claim seconds. BUG-1497 is closed_by_design; the mapping fix itself
is BUG-1500 and already merged.

Co-Authored-By: Grok (agent loop)
2026-10-29 15:48:08 +08:00
jesse-ux c163a74934 research(d60): preregister gates G2-G5 before scoring (issue #149)
Registered rules, thresholds, seeds and the same-day answer policy for the
D60 boundary probes. No scoring has run with this file in place.
2026-10-29 15:46:58 +08:00
Jesse_ChenandClaude 0b1bcf7e4d docs(testing): D60 mapping fix device checklist (issue #149)
Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-29 15:45:05 +08:00
jesse-uxandGrok (agent loop) 129313e175 fix(varga): count D60 from the sign itself for every sign (BUG-1500, issue #149)
Independent Staging Quality Gate / validate (push) Successful in 20m59s
Independent Staging Quality Gate / publish (push) Successful in 4m25s
The production D60 branch added one sign to 1-based even signs, with no
source, while the repository's own guide and the vedastro mapping count
from the sign itself. PyJHora agrees with the latter: 33/77 recorded times
before, 77/77 after.

- scripts/varga.py: D60 is (si+pi)%12 for odd and even signs; other
  mappings and the vedastro mode are untouched.
- tests/test_d60_varga_mapping.py: 12 signs x 60 parts against
  PyJHora, plus the even-sign first part.
- scripts/research/d60_two_way_run.py: the G1 reconciliation that found
  this, now in the repository with a test; G1 passes 77/77.
- scripts/varga.py is part of the extended frozen identity, so the sealed
  holdout and the reported-offset sweep were re-frozen per ERR-110. All
  20 and 900 trials match the upstream_sync9b records on every field and
  the metrics and summary are unchanged.

Co-Authored-By: Grok (agent loop)
2026-10-29 14:30:57 +08:00
jesse-ux a21c9ec163 merge: bring staging into the D60 research branch (issue #149) 2026-10-29 13:33:42 +08:00
Jesse_ChenandClaude 124ff8e0ba docs(tasks): D60 mapping fix brief, option 1 (agent loop, issue #149)
Product chose 1: fix production D60 (count from the sign itself for odd
and even signs) before continuing the two-way study. Renumber the
branch's D60 bug BUG-1498 -> BUG-1500 to clear the staging collision,
and settle the D60 boundary scoring rule as same-day events only.

Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-29 13:21:49 +08:00
Jesse_ChenandClaude Opus 5.5 68670b2819 Consult classification runs beside reserve and append (issue #162, BUG-1499)
Independent Staging Quality Gate / validate (push) Successful in 16m28s
Independent Staging Quality Gate / publish (push) Successful in 4m15s
Classification only needs the question, history, name and session model,
so it now starts in beforeReserve once moderation passes and is awaited
after the question is written. Billing is unchanged: smalltalk is still
reserved and refunded by complete_consultation_free, and an unused early
call (reserve refused) is capped at the classifier's 3 s fail-open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:54:49 +08:00
Jesse_ChenandClaude Opus 5.5 435c8e19f9 Answer step defaults to low reasoning effort (issue #134)
Independent Staging Quality Gate / validate (push) Successful in 24m29s
Independent Staging Quality Gate / publish (push) Successful in 4m17s
Product chose A after the A/B: low cut answer-step reasoning tokens ~45%
and answer time 34s -> 22s with no quality loss. Unset now means "low";
CONSULT_ANSWER_REASONING_EFFORT=off restores the pre-change request body,
and the old "unset keeps the body" guarantee moves to "off".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:00:22 +08:00
jesse-ux 98be2649ac research(d60): G1 stops on a production mapping mismatch (BUG-1497, BUG-1498, issue #149)
The D60 ascendant of the production classical_local mapping agrees with
PyJHora on 33 of 77 recorded times (42.9%). All 44 mismatches are 1-based
even signs and differ by exactly one sign; the repository's own vedastro
mode agrees with PyJHora on 77 of 77.

So G1 fails the 95% gate, but the cause is the production mapping rule in
scripts/varga.py, not a missing D60 signal. BUG-1498 records the
inconsistency as investigating. G2-G5 did not run and no scoring rule was
registered.

jyotishganit is not installed here and VedAstro was not called, so the
reconciliation is single-engine and says so.
2026-10-28 20:02:43 +08:00
jesseandClaude Opus 5.5 537beb2934 test: each test gets its own foreground VedAstro pool, drained at teardown (BUG-1498)
Independent Staging Quality Gate / validate (push) Successful in 16m7s
Independent Staging Quality Gate / publish (push) Successful in 4m22s
A task left running wrote its outcome into the next test's cache directory,
so the next test saw a remembered failure and never called the gateway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:39:28 +08:00
jesseandClaude Opus 5.5 2dea3c2994 docs(bug-history): BUG-1498 investigating — gate flake in daily starlanguage snapshot test
Independent Staging Quality Gate / validate (push) Failing after 9m6s
Independent Staging Quality Gate / publish (push) Skipped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:18:43 +08:00
jesseandClaude Opus 5.5 532a18ccac feat: person switcher says when and where, edits and deletes in place, and sits on the chat-side chart (issue #150)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:18:19 +08:00
jesseandClaude Opus 5.5 fd34df9b65 fix: rectification recap no longer repeats a date the event already carries (BUG-1496, issue #161)
Independent Staging Quality Gate / validate (push) Failing after 9m22s
Independent Staging Quality Gate / publish (push) Skipped
Staging showed 「记下了:2016-09 2016 年 9 月上大学。」. evidenceRecapLine only
recognised an unspaced 「2016年」 as the phrase's own date, so a spaced year or
an ISO / slash date got the label in front again. It now recognises
`\d{4}\s*年` and `\d{4}[-/.]\d{1,2}`; phrases without a date still get the
label. Regression test fails before the fix and passes after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:06:31 +08:00
jesse-ux 3bbf58e984 docs(d60): register BUG-1497 and record the two-way pre-work (issue #149)
Environment checks are done: swisseph 2.10.03, PyJHora importable with a
shashtyamsa chart, the v5 holdout present, and the four baseline test
files green (98 passed). jyotishganit is not installed, so G1 ends up with
PyJHora as the only external engine.

The B-group scoring rule cannot be implemented as written: the six-question
replay answers date-level boundary questions, while a D60 change happens
every couple of minutes inside one day. Two workable options are recorded
in PROGRESS and posted to the issue; nothing is scored before the rule is
preregistered.
2026-10-28 19:00:54 +08:00
jesse 88a03808a9 docs(tasks): D60 two-way comparison brief for local Grok (issue #149)
Nadi/D150 seconds were falsified in BUG-1240; this brief only tests D60 as a
discriminator: production V9 vs V9 + D60 segment boundaries on the 77-case v5
holdout, both directions (help and harm), preregistered gates G1-G5, plus a
20-case model-in-the-loop conversation comparison. Offline, no production or
frozen-file changes. Reserves BUG-1497.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 7f7321b77725c8798292f184fc038fcfaf8c11ff)
2026-10-28 18:55:56 +08:00
jesseandClaude Opus 5.5 7721aa9a2c feat: rectification opening names the time source; unchanged range is said (issue #148)
Independent Staging Quality Gate / validate (push) Successful in 17m18s
Independent Staging Quality Gate / publish (push) Failing after 15m2s
Product decisions 2026-10-28 (issuecomment-36121):
- The opening's window sentence says where the reader's time came from
  (出生记录时间 / 大概时间 / 你填的时间 / 时间段), still one sentence. When the
  source is known the server writes the opening; unknown and legacy get none.
- When a turn recorded events, the rescore completed and it is not the
  delivery turn, an exactly unchanged range gets
  「这件事在现在的范围里每个时刻都对得上,分不出前后。」. It never invites
  more events (BUG-1084).
- Not done, by decision: per-layer Lagna/nakshatra/dasha narration
  (BUG-606/1253), precision-gated layers (scoring), voluntary/involuntary
  career exits, "what would narrow it further" (BUG-1084).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:28:50 +08:00
jesseandClaude Opus 5.5 8e932959b5 feat: rectification screen — timeline-only minute, board on demand, result card (issues #146, #147)
- The working minute is written once, on the timeline; the board's title row
  no longer repeats it.
- 「看盘面」 sits in the header at every width; the board is closed by default
  and opens as a right column on desktop (bottom sheet on phones).

- A distinct result (D4) leads with 最可能的出生时间 + minute + Lagna; the range
  drops to the next line. Indistinct results keep the range headline (D3).
- The most likely column adopts with 「采用 HH:MM 并打开星盘」 and goes to /chart
  after the server saved it; other columns stay adoptable as 「改用这个」 under
  还不能排除. No confidence label. Record-conflict wording unchanged.
- 「我说错了,改一条」: confirmed events (from the case read's existing evidence
  list) prefill the composer; nothing is sent by the pick. No 「再补一件事」:
  the card must not invite more events (BUG-1084, issue #148 decision).
- The segment card keeps "which chart" (BUG-1151): no minute lead, same
  adopt label, same actions row.

Docs: DESIGN §10/§11/§12, VOICE, CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:23:04 +08:00
Jesse_ChenandClaude f80f3b75f8 Merge origin/staging into upstream sync 9 batch B (issue #159)
Independent Staging Quality Gate / validate (push) Successful in 18m34s
Independent Staging Quality Gate / publish (push) Successful in 5m14s
Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-28 17:23:59 +08:00
jesseandClaude Opus 5.5 cbfb37f7c8 test: list /rectification in the capability audit app routes (issue #145)
Independent Staging Quality Gate / validate (push) Successful in 20m54s
Independent Staging Quality Gate / publish (push) Successful in 5m43s
Staging gate run 2009 failed on test_capability_audit_scans_registry_and_local_sources:
the new app route app/(app)/rectification was not in the expected list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 17:23:17 +08:00
jesse-uxandGrok (agent loop) cbe665107f test(freeze-guard): keep the sync8 freeze paths in the forbidden list (issue #159)
The sync9b edit replaced the two sync8 entries in
IDENTITY_FORBIDDEN_PREFIXES instead of appending after them, so the guard
covered two records instead of four while still passing. Restore the
sync8 pair under its own comment and keep the sync9b pair after it.

The freshness test passes again (9) and the frontend confirmation-gate
test for the moved sealed report passes (8).

Co-Authored-By: Grok (agent loop)
2026-10-28 17:01:31 +08:00
jesseandClaude Opus 5.5 dfd3208979 feat: standalone rectification entry at /rectification (issue #145)
Independent Staging Quality Gate / validate (push) Failing after 13m25s
Independent Staging Quality Gate / publish (push) Skipped
- Sidebar 「生时校正」 under 星盘, behind a new account `rectification` flag.
- /rectification page: status card from entry-summary (not started / in
  progress with window and confirmed event count / adopted time), a short
  data check, then the home rectification surface (?rectify=1, or
  ?rectify=new to start over; ?c=<id> to continue or view). No price on
  the page.
- entry-summary gains session id, candidate range, confirmed evidence count
  and adopted times (add-only migration 20261028170000).
- The offer card under a consultation answer becomes one line and a link
  to /rectification; an explicit request in chat also goes there. No case
  is opened from a conversation any more.
- Starter home shows a rectification prompt for self charts with an
  estimated time; onboarding checklist gains 做一次生时校正 for them.
- Chart-page link points to /rectification. Shell registers its router so
  home hooks can navigate client-side without useRouter in Home().
- Docs: VOICE, DESIGN, CHANGELOG, device checklist.

Self profile only; other people are issue #160.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:50:55 +08:00
Jesse_ChenandClaude 8015e8efb7 docs(tasks): upstream sync 9 batch B first rejection (agent loop, issue #159)
The freshness test's IDENTITY_FORBIDDEN_PREFIXES list is append-only;
the branch replaced the two sync8 entries instead of adding the sync9b
ones after them, which weakens the identity guard. Restore them.

Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-28 16:47:37 +08:00
jesse-uxandGrok (agent loop) 5c5f333d4d fix(varga): port the five sarpa ranges and the 22nd drekkana house (BUG-1494, BUG-1495, issue #159)
Upstream 50847e57, ported semantically:

- Sarpa Drekkana now accepts the five classical ranges (Cancer 2/3,
  Scorpio 1/2, Pisces 3) and partitions on the raw longitude instead of
  the rounded display degrees.
- The 22nd Drekkana is the eighth house of D3 (+7), not +21 zodiacal
  ten-degree divisions.

scripts/varga.py is part of the extended frozen identity, so the sealed
holdout and the reported-offset sweep were re-frozen under ERR-110:
20/20 sealed trials and 900/900 sweep trials match the sync8 records on
every compared field, and the metrics, summary and widening geometry are
unchanged.

Tests: the upstream varga/ sarpa files are added under
tests/test_upstream_sync9b_*.py; the stale +21 assertion and the sarpa
definition string are updated with the original/new/reason columns in
PROGRESS.

Co-Authored-By: Grok (agent loop)
2026-10-28 16:25:45 +08:00
Jesse_ChenandClaude 2243220841 docs(tasks): upstream sync 9 batch B brief (agent loop, issue #159)
Product chose A on #159: change the frozen varga.py for the five Sarpa
drekkanas and the 22nd drekkana, and refreeze only on identical 20/900
rectification scores. Narayana AD strength (B2) is deferred: our code
has no strength-profile family for it to propagate.

Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-28 15:46:21 +08:00
Jesse_ChenandClaude Opus 5.5 12eb7018ec docs(testing): answer-step reasoning effort A/B results (issue #134, #135 data)
Independent Staging Quality Gate / validate (push) Successful in 22m59s
Independent Staging Quality Gate / publish (push) Successful in 4m55s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:28:35 +08:00
Jesse_ChenandClaude Opus 5.5 8d1cb4a53b Heavy routes run in worker processes, one per heavy slot (issue #133, BUG-1493)
The single ThreadingHTTPServer ran pure-Python v5 score / block_scan / report
reference under one GIL, so the gate's two slots shared a core. start_server
now starts a spawn pool (workers = heavy concurrency, PYTHONHASHSEED=0, engine
pre-imported); those three routes call the same compute method in a worker.
Over HTTP: score alone 4.74 s, two at once 5.01 / 4.58 s (1.06x; in-process
1.56x). Results equal except per-process fingerprints; report markdown equal.
~165 MB extra. A crashed pool answers inline and restarts; off with
JYOTISH_HEAVY_COMPUTE_PROCESSES=0; tests calling compute methods unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:28:05 +08:00
Jesse_ChenandClaude Opus 5.5 5fd79a5649 Chart surfaces start Vimshottari from the birth moment, as reports do (issue #137, BUG-1492)
/api/chart, /api/dasha and the analysis layer, daily guidance and the KP
monthly packet used compute_vimshottari_timeline, which hands
build_dasha_timeline only the birth date, so periods started at midnight;
cmd_dasha (reports) starts from the birth clock and lays antardashas from the
full parent with float days. scripts/chart_dasha/birth_moment.py reproduces
cmd_dasha; 60 standard charts: MD and AD 60/60 equal (old chart path 9/60),
51 charts move by at most one day. Frozen scoring files are untouched, so
rectification probes keep the day start (left for a product decision).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:27:35 +08:00
Jesse_ChenandClaude Opus 5.5 699e353887 Rectification turns no longer spend a model call reading the case (issue #136, BUG-1491)
Step 0 of every turn could only call rectification-read-case with the
default projection, a result the server can compute. The runner now runs the
agent's own read-case tool after the Skill is bound (same tool, receipts and
projection), passes the call and result to the model as the turn's opening,
and gives step 0 the full tool set. Synthetic chunks go through the same loop
(case.loaded, activity and Skill receipt once each) but not into step timings.
The synthetic call carries a short reasoning line: thinking-mode DeepSeek
rejects a prior tool call without reasoning_content (checked live). read-case
stays callable for resume / full_diagnostics. Agents without listTools keep
the step-0 read. The Skill package has no "read first" text; prompts updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:27:27 +08:00
Jesse_ChenandClaude Opus 5.5 a614895a2b Loader waits for a module another thread is still importing (issue #132, BUG-1482 reopened)
Independent Staging Quality Gate / validate (push) Successful in 16m40s
Independent Staging Quality Gate / publish (push) Successful in 4m32s
Gate run 5888 failed: the synastry full dossier computes two full readings
on a thread pool, and the second thread got jyotish_engine from sys.modules
while the first was still executing it (no cmd_full_reading yet). Reuse now
goes through importlib.import_module, which waits on the module lock.

Four threads loading one module in a fresh interpreter: before
[False, True, True, True], after all True three times. Dossier scenario
before 4/4 AttributeError, after 6/6 ok; synastry-full-report.test.ts 17/17.
Ledger ERR-117: local npm baseline hid it (system python3 lacks swisseph).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:47:30 +08:00
Jesse_ChenandClaude cd6ad9d27a Merge origin/staging into upstream sync 9 (issue #141)
Independent Staging Quality Gate / validate (push) Failing after 14m40s
Independent Staging Quality Gate / publish (push) Skipped
Staging took BUG-1472..1482 while this branch was in review, so the
branch's eight entries move to BUG-1483..1490. Docs and one test
comment only; the branch's commit messages keep the old numbers.

Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
2026-10-28 12:45:29 +08:00