Commit Graph
2702 Commits
Author SHA1 Message Date
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 d670521f47 docs(tasks): Claude acceptance for serif headings
Independent Staging Quality Gate / validate (push) Successful in 14m16s
Independent Staging Quality Gate / publish (push) Successful in 3m46s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 19:54:05 +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 308f5502cb feat(fonts): self-hosted Jyotisha Serif SC heading slices (T1)
Renamed, sliced subset of Noto Serif SC SemiBold (OFL 1.1, noto-cjk
Serif2.003) covering the 6500 level-1 + level-2 characters of the
通用规范汉字表 plus Latin, punctuation and common symbols.

- scripts/fonts/build_serif_slices.py: fontTools subsetting into 30 woff2
  slices + serif-sc.css (@font-face, weight 500 700, font-display swap);
  byte-identical output for the same input.
- Frequency order (char_order.txt): repo corpus top 300, then Google
  Fonts SC frequency bands (nam-files, Apache-2.0), then corpus count;
  unranked characters sliced by contiguous code point.
- tests/test_serif_font_slices.py: coverage, no overlap, files exist,
  120 KB cap; added to the quick quality gate.

TASK-serif-headings-20260928 T1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 19:31:43 +08:00
Jesse_ChenandClaude Opus 5.5 ebcee58419 docs(tasks): serif headings via self-hosted Noto Serif SC slices; birth-sky cover follows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 18:49:15 +08:00
Jesse_ChenandClaude Opus 5.5 aa33399ae5 docs(tasks): birth-sky cover — chart page, report cover, first-chart reveal
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 18:06:10 +08:00
Jesse_ChenandClaude Opus 5.5 1d2af8ee18 docs(bugs): BUG-1079 deployed to staging dc640931
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 18:05:23 +08:00
Jesse_ChenandClaude Opus 5.5 dc640931b1 docs(ui): Claude acceptance for BUG-1079
Independent Staging Quality Gate / validate (push) Successful in 12m42s
Independent Staging Quality Gate / publish (push) Successful in 3m28s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 17:46:24 +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 12aac87bde fix(ui): one solid-button colour site-wide; solid disabled is grey, not faded (BUG-1079)
Drop the unlayered button { color: inherit } that beat every layered Tailwind
text utility; scope the raw-button disabled fade away from <Button>. Add the
--color-action-fill token pair (light #fbfaf7 on #a9583e 4.85:1, dark #f2f0ea
on #8f4a33 5.77:1) for <Button> default, .button-primary, composer send/stop
and the calendar's selected day. Remove the BUG-1078 report-only override.

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 7db58230ad docs(tasks): site-wide solid button contrast and disabled state (BUG-1079), with contrast harness
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 16:53:02 +08:00
Jesse_ChenandClaude Opus 5.5 b3b5f0e184 docs(bugs): BUG-1076/1077/1078 deployed to staging 6a4e312c
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 16:32:10 +08:00
Jesse_ChenandClaude Opus 5.5 6a4e312c2c docs(tasks): Claude acceptance for chart types + ayanamsa + report buttons
Independent Staging Quality Gate / validate (push) Successful in 17m40s
Independent Staging Quality Gate / publish (push) Successful in 3m43s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 16:06:46 +08:00
Jesse_ChenandClaude Opus 5.5 4189750c6a fix(api): technique explorer bhava_chalit sample carries the birth moment (BUG-1077 acceptance)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:55:50 +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 Opus 5.5 c35e0195e1 fix(chart): Sripati Bhava from the real sidereal MC; Bhava chart and tables (T5, BUG-1077)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:38:24 +08:00
Jesse_ChenandClaude Opus 5.5 3f6bcb081a feat(chart): Moon chart from D1 and transit chart for today in the natal houses (T4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:33:30 +08:00
Jesse_ChenandClaude Opus 5.5 2071dc7c18 feat(chart): chart-type strip + 星盘类型 sheet, D40/D45/D60, precision hint (T2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:26:36 +08:00
Jesse_ChenandClaude Opus 5.5 f5149d10ca chore(chart): drop the qizheng palace helper left by T1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:26:36 +08:00
Jesse_ChenandClaude Opus 5.5 ab6ee94e95 fix(chart): divisional tables show that chart's own rows, not D1 (T3, BUG-1076)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:21:30 +08:00
Jesse_ChenandClaude Opus 5.5 af27709de4 feat(chart): hide qizheng from the chart page; backend endpoint kept (T1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 15:17:34 +08:00
Jesse_ChenandClaude Opus 5.5 5dc977ef2c docs(tasks): chart types, per-chart tables, qizheng hidden, ayanamsa, report buttons
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-28 14:13:30 +08:00
Jesse_ChenandClaude Fable 5.1 2366da1ced docs(bugs): BUG-1074/1075 deployed to staging 79c5e566
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 10:00:42 +08:00
Jesse_ChenandClaude Fable 5.1 79c5e566ec docs(tasks): first-frame and pacing acceptance
Independent Staging Quality Gate / validate (push) Successful in 13m25s
Independent Staging Quality Gate / publish (push) Successful in 3m18s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:41:15 +08:00
Jesse_ChenandClaude Fable 5.1 20a54d176c docs(consult): BUG-1074/1075 records, changelog, device checklist, progress and BLOCKED for first-frame and pacing (T4)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:36:21 +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 0bc6659052 feat(consult): open the response stream before preparation, reservation and classification; rejections ride the stream (T2, BUG-1074)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 09:20:23 +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 584ad05c36 docs(tasks): open consult first-frame and pacing brief (blank before classification, snap release)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 08:48:34 +08:00
Jesse_ChenandClaude Fable 5.1 56ca8b266a docs: BUG-1070~1073 device checklist steps 1–4 passed on staging
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 00:19:58 +08:00
Jesse_ChenandClaude Fable 5.1 ce232d47de docs(bugs): BUG-1070~1073 deployed to staging 9d01757f
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-28 00:05:10 +08:00
Jesse_ChenandClaude Fable 5.1 9d01757f27 fix(consult): a stored smalltalk reply is not a prior answer; summary counts as one (acceptance fix for BUG-1071)
Independent Staging Quality Gate / validate (push) Successful in 14m58s
Independent Staging Quality Gate / publish (push) Successful in 3m40s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 23:43:57 +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 Fable 5.1 9a42333a55 feat(consult): answer the sentence asked — no motive guessing, follow-up turns answer directly, first turn says each thing once (BUG-1070~1073)
- Voice: contrast limited to chart structures; drop 「这句我按『……』理解了」; forbid motive/need sentences; yes/no answered first (BUG-1070)
- Follow-up turn (session already holds an answer): ≤200-char direct answer, no skeleton; decided from stored history, no intent regex; tool still runs each turn (BUG-1071)
- Thinking bar first section 「先回答你问的这件事」 (BUG-1072)
- First turn: opener without actions, body headings 盘里支持 / 时间怎么看 / 这周可以做的一件事 only, actions once, ≤900 chars (BUG-1073, D8)
- Checklist is a list to check, not paragraphs to write (T3)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 23:31:33 +08:00
Jesse_ChenandClaude Fable 5.1 2ce3c2165c docs(tasks): consult answer-the-question brief — first-turn fixture, R6 repetition, D8 pending product
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 23:05:18 +08:00
Jesse_ChenandClaude Fable 5.1 ab41532d89 docs(tasks): open consult answer-the-question brief (no motive guessing, follow-up turns answer directly)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 22:41:56 +08:00
Jesse_ChenandClaude Fable 5.1 24a9a63579 docs(tasks): cost brief E0/T1.0 — admin model form has no price fields (BUG-1069 reserved)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 22:27:21 +08:00
Jesse_ChenandClaude Fable 5.1 137410f4e5 docs(tasks): open cost-accounting gaps brief (cache pricing, unbilled calls, released runs)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 22:18:10 +08:00
Jesse_ChenandClaude Opus 5.5 0c95a7ecac docs(bugs): BUG-1061 deployed to staging d9c9e714
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 19:26:46 +08:00
Jesse_ChenandClaude Opus 5.5 d9c9e714f2 docs(tasks): BUG-1061 acceptance
Independent Staging Quality Gate / validate (push) Successful in 11m14s
Independent Staging Quality Gate / publish (push) Successful in 3m47s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 19:08:07 +08:00
Jesse_ChenandClaude Opus 5.5 fe4bcba3ef docs: BUG-1061 fix version
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 19:08:07 +08:00
Jesse_ChenandClaude Opus 5.5 fb543d3849 fix(engine): pair double-transit D1+D9 targets by identity, not name digits (BUG-1061)
Every D9 target name contains the "9" of "D9", so the digit comparison never
paired D1 N宫 with D9_N宫 and, for house 9, paired D1 9宫 with any D9 planet
target. Targets now carry structured metadata (layer/kind/house/planet); the
cross-layer loop pairs only the same house or targets that both point at the
D1 house-N lord. Target names and D1/D9/CL layer results are unchanged
(D1/CL golden regenerated byte-identical); 48 samples: cross entries 31 -> 38.
Evidence-card golden regenerated with the capture script.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 19:08:07 +08:00
Jesse_ChenandClaude Opus 5.5 037cd1aa1d docs: BUG-1062 verified by gate run 2977; gender DB gap cleared
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 19:00:51 +08:00
Jesse_ChenandClaude Opus 5.5 9aa37197a4 docs(tasks): gender optional acceptance
Independent Staging Quality Gate / validate (push) Successful in 12m53s
Independent Staging Quality Gate / publish (push) Successful in 3m27s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 18:38:00 +08:00
Jesse_ChenandClaude Opus 5.5 5bba952793 docs: gender-optional records (PROGRESS, checklist, CHANGELOG, BLOCKED) (T4)
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 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 5caf03844e feat(consult): marriage card and checklist follow the current subject's gender (T3)
The marriage evidence card's gender field is the bound subject's own value
(女 / 男, 性别未知 when not filled). The condensed checklist keeps the
gender-unknown rule only when unset; otherwise it names the spouse
significator per strict-workflow-router.md §4 and the repo's gender
interpretation contract (supplement only, core stack gender-neutral). The
methodology cache is keyed by gender so one person's line never serves
another. Tests drive the real getJyotishAgent with a prompt-recording model.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 18:30:57 +08:00