Commit Graph
380 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 7827d9aff0 chore(rectification): re-freeze after the BUG-1622..1626 renumber (ERR-110)
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
2026-11-05 15:35:31 +08:00
ClaudeandClaude Opus 5.5 093da4468d docs: renumber this branch's records BUG-1613..1617 -> BUG-1622..1626
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
2026-11-05 15:32:05 +08:00
ClaudeandClaude Opus 5.5 3c81ebf3cf chore(rectification): re-freeze sealed holdout and offset sweep for the #166 2026-11-05 labels (ERR-110, BUG-1613..1617)
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
2026-11-05 15:31:43 +08:00
ClaudeandClaude Opus 5.5 6e10c7242e docs(moolatrikona): label the in-varga D9 Moolatrikona as pending; correct the V.P. Jain provenance (BUG-1613)
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
2026-11-05 15:31:43 +08:00
ClaudeandClaude Opus 5.5 bd60ed6270 docs(yoga): Matrunasa 198 labels and the 199 effects text (BUG-1616)
Astrologer 2026-11-05 (#166 comment 39249, item 5). Detection unchanged.

- 198: nodes casting no aspect labelled a conservative engineering choice,
  pending review; malefic set declared (Sun, Mars, Saturn, Rahu, Ketu for
  hemming / conjunction; aspects from Sun, Mars, Saturn); Raman edition and
  page pending (pp. 188-190 is only a locator).
- 199: effects / effects_en described 198 ("Moon under malefic influence");
  they now describe the 4th lord's Navamsa chain.
- Both: a hit is a structural feature, never the mother's health or life.
  The consult card carries only the yoga name and hit flag (no effect text);
  reports render these effects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-05 15:31:43 +08:00
ClaudeandClaude Opus 5.5 1c298c7257 fix(yoga): strict Gajakesari no longer counts a natural-malefic Mercury as a supporter (BUG-1615)
Astrologer 2026-11-05 (#166 comment 39249, item 6): PVR §11.6 strict
definition needs a benefic supporter; a Mercury that is malefic by
association must follow the chosen natural-nature rule.

- New sandbox helper mercury_malefic_companions() calls
  shadbala.mercury_malefic_companions (the one implementation of
  MERCURY_NATURE_CONVENTION: same sign as Sun / Mars / Saturn / waning Moon,
  nodes excluded), imported lazily; no import cycle.
- gajakesari: Mercury is dropped from benefic_links when malefic; when Venus
  still supports, a trigger names the excluded Mercury.
- gajakesari_strong_jupiter_variant: its "strict does not hold" check uses the
  same rule, so the two rules stay mutually exclusive; the variant itself uses
  no supporter.
- Labels: natural (not five-fold) enmity for the enemy-sign test and the Moon
  excluded as a supporter are both pending astrologer review.

yoga_engine.py / yoga_rules.json are not in the frozen identity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-05 15:31:43 +08:00
ClaudeandClaude Opus 5.5 013f889529 chore(rectification): re-freeze sealed holdout and offset sweep for #166 batch 2 at scoring-15 (ERR-110, BUG-1590..1598)
Independent Staging Quality Gate / validate-frontend (push) Successful in 6m25s
Independent Staging Quality Gate / validate-python (push) Successful in 6m30s
Independent Staging Quality Gate / publish (push) Successful in 3m3s
FREEZE / REPORT constants first, --freeze, then replay:
astrologer_166b_2026_11_04 (frozen after 7ff447ac); contract rotated with
previous = astrologer_166_2026_11_04 (kept byte-for-byte).

Versus astrologer_166_2026_11_04 (no tuning):
- sealed 20: all identical, metrics unchanged.
- reported offset 900: 114 changed; top-1 hits at +-15/30/60 stay 4/3/0;
  top-3 30/34/29 -> 31/34/30; delivery coverage at +-15 220 -> 219; mean
  top-1 minute error 20.87 -> 20.52.

BUG-1590..1598 recorded; ledger and CHANGELOG lines added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-04 22:42:41 +08:00
ClaudeandClaude Opus 5.5 7ff447ac67 fix(engine): keep the Chinese report free of English glue from #166 triggers and cell notes (BUG-1596, BUG-1597, BUG-1590)
Quick gate: test_report_english_sweep_smoke counted 3 zh_han_function_glue
hits on chart #1, all new in 4b223eb8: the Matrunasa 199 trigger "Moon ->
Mercury -> Moon in house 8" (the renderer turns "house" into Chinese and
leaves "in") and the English ambiguous_cell_notes ("Lagna lord, ...").

- A custom rule's trigger item may be a (Chinese, English) pair; the Chinese
  combination uses the Chinese items, combination_en and `triggers` the
  English ones, `triggers_zh` the Chinese. Gajakesari, the variant and both
  Matrunasa rules emit pairs (PLANET_ZH in the sandbox).
- ambiguous_cell_notes carry Chinese summary / basis plus summary_en /
  basis_en, worded without the glue words.
No role or score changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-04 22:39:15 +08:00
ClaudeandClaude Opus 5.5 4b223eb8ea fix(engine): apply #166 batch 2 rulings to functional roles, yogas, Chara / Narayana, Gulika, sunrise records and varga methods (BUG-1590..1598)
Astrologer ruling 2026-11-04 on #166, product decisions the same day (Q9
display only, later; Q12 record, do not switch).

- Q4 (BUG-1590): Gemini Saturn (8, 9) and Virgo Saturn (5, 6) are mixed
  (neutral), not pure benefics by trine priority; the astrologer's table for
  the eight ambiguous cells rides along as ambiguous_cell_notes. Other
  lordships are kept.
- Q10 (BUG-1591): Chara Dasha with both Scorpio / Aquarius lords in the sign
  is fixed at 12 years (Ketu exalted in Scorpio gave 13).
- Q11 (BUG-1592): legacy Narayana counts only the nine grahas as occupants.
- Q8 (BUG-1593): Narayana period reports the adjustment that took effect
  (Mercury in Virgo: 12, +0, not "12 + 1" capped silently).
- Q15 (BUG-1594): upagrahas carry both raw Saturn-part points and name the
  mapping (PyJHora-compatible Gulika = start, Maandi = midpoint; PVR 4.3 is the
  reverse and is listed, never claimed).
- Q12 / Q13 (BUG-1595): every day/night window, Shadbala and the birth
  Panchanga record their sunrise convention and hora method. No value changes.
- Q5 (BUG-1596): "Gajakesari Yoga" is PVR's strict definition (benefic
  association, not debilitated, combust or in a natural enemy's sign); the
  strong-Jupiter variant and the bare Moon-Jupiter kendra relation are
  separate rules outside the card's closed list. New sandbox helpers combust()
  and in_natural_enemy_sign().
- Q6 (BUG-1597): Matrunasa split into Raman 198 (named Parashari aspects,
  nodes for conjunction / hemming only) and Raman 199 (same parents-card row
  via canonical_mapping); each hit names its trigger; "high confidence" and
  mother's-health effects removed. Custom rules may set `triggers`.
- Q31 (BUG-1598): calc_varga names the D3 / D24 / D30 / D60 method; D3 / D24 /
  D60 of varga.py and divisional_charts_extended agree on every 0.1 deg.
- Q29: the 7-karaka note says PiK does not apply in that scheme.

tests/test_astrologer_rulings_166_batch2.py (25 tests). Rectification
identity and re-freeze follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-04 22:24:40 +08:00
ClaudeandClaude Opus 5.5 1989649f70 chore(rectification): re-freeze sealed holdout and offset sweep for the #166 rulings at scoring-14 (ERR-110, BUG-1581..1589)
FREEZE / REPORT constants first, --freeze, then replay: astrologer_166_2026_11_04.
Contract rotated with previous = d30_venus_2026_11_04 (kept byte-for-byte);
freshness test and frontend confirmation-gate test updated.

Versus d30_venus_2026_11_04 (no tuning):
- sealed 20: 17 identical / 3 changed (case 6 true_rank 8 -> 4, case 16
  13 -> 11, case 20 1 -> 8 with minute error 10 -> 8); top_1 0.45 -> 0.40,
  top_3 0.50 -> 0.45, MAE 7.05 -> 6.95, coverage 0 unchanged.
- reported offset 900: 584 identical / 316 changed (rank better 122, worse
  139); top-1 hits at +-15/30/60 4/3/0 and top-3 30/34/29 unchanged; delivery
  coverage at +-15 219 -> 220; mean top-1 minute error 19.51 -> 20.87.
No per-ruling attribution replay was run.

BUG-1581..1589 recorded (BUG-1575 resolved with BUG-1583); ledger and
CHANGELOG lines added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-04 21:14:16 +08:00
ClaudeandClaude Opus 5.5 78f98eba93 fix(engine): apply the #166 astrologer rulings to Shadbala, Arudha and D30 (BUG-1581..1589, BUG-1575)
Astrologer ruling 2026-11-04 on #166; product decision the same day (Moon
option C, rulings implemented as given). The default is a named BPHS version;
the pre-#166 precise Sthana / Drik is kept byte-for-byte as variant
"raman_gbb" (Raman, Graha and Bhava Balas Ex. 13 / 55 still pass on it).

- Q3 (BUG-1581): the Moon's own Paksha is P on both sides (Sanskrit 27.11 lists
  indu), Chesta = Paksha, total 2P. Drik still classifies a waning Moon as a
  malefic (Q26), classify_drik_planets unchanged for the Moon.
- Q2 (BUG-1582): the Sun's Ayana is not doubled; Chesta = base Ayana; A + A.
  On the VP Jain fixture Kala + Chesta = 46.73 + 35.07 = published 81.80 + 0.
- Q18 (BUG-1583, BUG-1575): Moolatrikona Moon Taurus from 3 deg, Mercury Virgo
  from 15 deg, in shadbala.py and jyotish_engine.MOOLATRIKONA.
- Q16 / Q20 (BUG-1584): Saptavargaja 45/30/20/15/10/4/2, compound relation from D1.
- Q25 (BUG-1585): Mercury is a natural malefic with any natural malefic in its
  sign (nodes not counted, recorded as an implementation choice).
- Q24 (BUG-1586): BPHS 26.9-12 piecewise special aspects replace the general
  segment for Saturn, Mars and Jupiter; a single aspect stays within 0-60.
- Q21 (BUG-1587): Kendradi Bala by whole sign from the Lagna sign.
- Q27 (BUG-1588): jaimini.calc_arudha_pada_for_house takes the 10th from the
  first-count pada (pada in the 7th -> 4th from the house), as special_lagnas did.
- Q30 (BUG-1589): D30 degree inside the sign is proportional within the
  unequal span in varga.py; divisional_charts_extended uses exact 30/7.
- method_variants names every convention. Q22 edges and the Q24 60 cap are
  locked in tests/test_astrologer_rulings_166.py (42 tests).

Raman / PyJHora comparison tests now run on "raman_gbb"; the VP Jain report
labels the new convention rows; chart-insight-golden.json's planets-only
Shadbala section regenerated from /api/shadbala. Rectification identity,
golden and re-freeze follow in separate commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
2026-11-04 21:08:32 +08:00
ClaudeandClaude Opus 5.5 71d38b0d67 chore(rectification): re-freeze sealed holdout and offset sweep for D30 and Venus roles at scoring-13 (ERR-110, BUG-1560, BUG-1570)
Independent Staging Quality Gate / validate-python (push) Successful in 7m24s
Independent Staging Quality Gate / validate-frontend (push) Successful in 7m25s
Independent Staging Quality Gate / publish (push) Successful in 2m59s
FREEZE / REPORT constants first, --freeze, then replay: d30_venus_2026_11_04.
Contract rotated with previous = audit_wave2_2026_11_04 (kept byte-for-byte);
freshness test and frontend confirmation-gate test updated.

Versus audit_wave2_2026_11_04 (product accepted these costs 2026-11-04, no
tuning):
- sealed 20: 17 identical / 3 changed (case 5 rank 1 -> 3, case 18 12 -> 10,
  case 14 reasons only); top_1 0.50 -> 0.45, MAE 6.65 -> 7.05; top_3 0.50 and
  coverage 0 unchanged. All from the D30 table.
- reported offset 900: 650 identical / 250 changed; top-1 hits at
  +-15/30/60 14/17/15 -> 4/3/0 of 300 (all from Venus roles); top-3 and
  delivery coverage unchanged at every radius; mean minute error
  19.79 -> 19.51 (from D30).
Attribution from single-fix replays on git-archive copies: D30 alone 3 sealed
/ 166 offset trials, Venus alone 0 / 108; they overlap only in case 20.

BUG-1560 and BUG-1570 resolved; ledger and CHANGELOG lines added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:46:58 +08:00
ClaudeandClaude Opus 5.5 18c685c428 fix(engine): even-sign D30 per BPHS ch. 6 and Venus malefic for Aries / Scorpio per BPHS 34 (BUG-1560, BUG-1570)
Product decision 2026-11-04: the calculation follows the sources even though
rectification scores move.

- scripts/varga.py: even-sign Trimsamsa 12-20 Pisces, 20-25 Capricorn,
  25-30 Scorpio (was Capricorn / Scorpio / Pisces). KNOWN DEFECT comment
  removed; the strict xfail in tests/test_varga_bphs_starts_audit_g.py is now
  an ordinary test and the 0.1-degree BPHS sweep covers varga.py on all signs.
- scripts/functional_benefics.py: ROLE_OVERRIDES adds Venus = malefic for
  Aries (BPHS 34.20) and Scorpio (34.35); profile doc lists both cells.

Both feed rectification scoring; the scoring-13 identity bump, memoization
golden v6 and the ERR-110 re-freeze follow in the next commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:33:26 +08:00
ClaudeandClaude Opus 5.5 607a48b6c3 chore(rectification): re-freeze sealed holdout and offset sweep once for the merged audit wave 2 (ERR-110)
Independent Staging Quality Gate / validate-frontend (push) Successful in 6m27s
Independent Staging Quality Gate / validate-python (push) Successful in 6m34s
Independent Staging Quality Gate / publish (push) Successful in 3m1s
G (BUG-1560/1561: varga.py, divisional_charts_extended.py), H (BUG-1566/1567:
jaimini.py) and J (BUG-1270/1576: shadbala.py) each changed frozen identity
files and each froze its own audit_g / audit_h / audit_j record, which only
matches that branch's tree. Per ERR-110 the merged tree is frozen once as
audit_wave2_2026_11_04 (FREEZE/REPORT constants first, --freeze, then replay).
The contract now points at audit_wave2 with moon_paksha_2026_11_04 as the
previous record; the per-branch records are kept byte-for-byte and named as
intermediate in the superseded_reason notes. Freshness test and frontend gate
test updated.

Compared field by field with moon_paksha_2026_11_04: sealed holdout 20/20
trials identical, metrics unchanged; reported offset 900/900 identical,
summary unchanged; changed_trial_count vs 2026-09-20 stays 8 / 581.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:24:31 +08:00
ClaudeandClaude Opus 5.5 728b077d44 merge: data audit wave 2 I (yoga rules and Parivartana Raja Yoga, BUG-1570..1573)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:05:37 +08:00
ClaudeandClaude Opus 5.5 895a75a2ed chore(rectification): re-freeze sealed holdout and offset sweep for the varga fixes (ERR-110)
BUG-1560 / BUG-1561 changed scripts/varga.py and
scripts/divisional_charts_extended.py, both in the frozen scoring identity.
Per ERR-110 new records were created with each script's --freeze and
replayed as audit_g_2026_11_04; scripts, contract, freshness test and the
frontend gate test point at them. Prior records are kept byte-for-byte.

Compared field by field with moon_paksha_2026_11_04: sealed holdout 20/20
trials identical, metrics unchanged; reported offset 900/900 identical,
summary unchanged; changed_trial_count vs 2026-09-20 stays 8 / 581.
(The D16/D20/D27/D45 and extended-module charts are not read by scoring.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:02:53 +08:00
ClaudeandClaude Opus 5.5 ba27b0e758 fix(varga): D16/D20/D27/D45 starts and the chart-page D30/D40 follow BPHS ch. 6 (BUG-1560..1562)
Data audit wave 2 (G): 19 fixed charts, Raman and Lahiri, mean nodes, both
engines set explicitly. Against PyJHora method 1 ("traditional Parasara") on
the same longitudes, varga.py matched D16/D20 26%, D27 25%, D45 14%, and
divisional_charts_extended (chart page, consultation varga spectrum) matched
D16/D20 7%, D27 14%, D40/D45 25%, D30 50%. jyotishganit agrees with PyJHora
190/190 on every one of these, and both follow BPHS ch. 6.

- varga.varga_map: D16/D45 movable/fixed/dual from Aries/Leo/Sagittarius,
  D20 from Aries/Sagittarius/Leo, D27 fiery/earthy/airy/watery from
  Aries/Cancer/Libra/Capricorn (were odd/even starts). BUG-1560.
- divisional_charts_extended: D16/D20/D27/D40/D45 signs now read varga_map;
  D30 uses the BPHS signs (odd 25-30 Libra; even Taurus, Virgo, Pisces,
  Capricorn, Scorpio). BUG-1561.
- trimshamsa_d30: even-sign table copied from jyotishganit swapped Jupiter
  and Saturn; now 12-20 Pisces, 20-25 Capricorn, 25-30 Scorpio. BUG-1562.
- shodasavarga guide: D4/D10/D24/D27/D30/D40 rule text corrected.

Held back: varga.py even-sign D30 has the same defect, but it feeds
rectification scoring. Fixing it moved the sealed holdout (top-1 0.50 to
0.45) and 166/900 offset trials and turned the memoization goldens red,
which per BUG-1260/1275 means a scoring-13 identity: a product decision.
It carries a KNOWN DEFECT comment and a strict xfail test.

After: same-longitude agreement with PyJHora is 190/190 for D3-D60 in
divisional_charts_extended and for every varga.py chart except D30.
D9/D10/D12, karakas and Arudha are unchanged; the evidence card check
(27 cards, 765 fields) shows 0 differences before and after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 17:02:53 +08:00
ClaudeandClaude Opus 5.5 5a112bf5f5 fix(yoga): revive nine custom rules and Raja Yoga (Parivartana) (BUG-1571, BUG-1572)
Data audit wave 2 (I). 04d901e1 (2026-06-27) renamed the evaluator's
pyjhora_* helpers to external_benchmark_* but left the rule expressions
calling the old names; the NameError is swallowed, so nine rules (Matru
Sneha on the parents card, Bhratruvriddhi, Amala, Sumukha, Bandhu Pujya,
Kaalanirdesat Puthranaasa, ...) never formed. The rule library now calls
the current names; logic is unchanged. Against PyJHora (Raman, mean nodes,
19 samples) the revived rules agree 18-19/19; the 20 Raman packet rules
go from 302/380 to 327/380.

_eval_parivartana resolved "$a" / "$b" with ctx.resolve, which knows no
any_pair bindings, so raja_yoga_parivartana (kendra lord <-> trikona lord
exchange, BPHS 34.11) never fired. Bare "$x" refs now go through
_resolve_binding.

New test scans every custom expression for names the evaluator does not
define (only parvata_yoga, non-classical and left off, is excepted).
Neither file is in the rectification frozen identity; sealed 20/20 and
reported-offset 900/900 replay identical to moon_paksha_2026_11_04.

BUG-1570 (Aries / Scorpio Venus malefic by BPHS 34.20 / 34.35) and
BUG-1573 (packet members with no evaluable detector, no D9 context in the
consultation yoga path) are recorded, not changed: the BUG-1570 trial cut
reported-offset top-1 by 3-5 pp and needs a product decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 16:44:42 +08:00
ClaudeandClaude Opus 5.5 18b01c23e5 fix(shadbala): count the Moon's Paksha 2x, not 4x; adopt BPHS-Santhanam 27.10-11 + 27.18 (BUG-1557)
Independent Staging Quality Gate / publish (push) Canceled after 0s
Independent Staging Quality Gate / validate-python (push) Canceled after 1m32s
Independent Staging Quality Gate / validate-frontend (push) Canceled after 1m33s
The precise path doubled the Moon's Paksha in Kala (Raman, Graha and Bhava
Balas §55(c)) and then took that doubled value again as her Chesta (BPHS
27.18), so her Paksha entered the total four times; Chesta could reach 120,
clamping Kashta to 0 and pushing Ishta past 60. Every surveyed source
counts 2P.

Product decision 2026-11-04: BPHS (Santhanam) 27.10-11 + 27.18, as in
saravali.github.io, Maitreya8 (default) and jyotishyamitra. The Moon's
Paksha is the folded base, not doubled; waxing Moon benefic, waning Moon
malefic (BPHS 3.11, already what classify_drik_planets does, unchanged);
Chesta = Paksha. method_variants.moon_paksha names the convention. Other
planets, Drik and the legacy calc_kala_bala path are unchanged.

shadbala.py is in the rectification frozen identity, so per ERR-110 new
records were frozen and replayed as moon_paksha_2026_11_04. Compared field
by field with data_audit_2026_11_04: sealed holdout 20/20 and reported
offset 900/900 identical, metrics and summary unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 15:46:16 +08:00
ClaudeandClaude Opus 5.5 1b367e6ba8 chore(rectification): re-freeze sealed holdout and offset sweep for the data-audit engine fixes (ERR-110)
Independent Staging Quality Gate / validate-frontend (push) Successful in 6m17s
Independent Staging Quality Gate / validate-python (push) Successful in 6m20s
Independent Staging Quality Gate / publish (push) Successful in 2m43s
BUG-1545 (scripts/narayana_dasha.py, scripts/active_rectification_event_engine.py)
and BUG-1546 (scripts/shadbala.py) changed files in the frozen scoring
identity, so the integrity gate went red. Per ERR-110, new records were
created with each script's --freeze and replayed under the label
data_audit_2026_11_04; the scripts, contract, freshness test and frontend
gate test now point at them, following 129313e1. Prior records are kept
byte-for-byte.

Compared field by field with the d60_mapping_2026_10_29 records:
- sealed holdout: 20/20 trials identical; metrics unchanged.
- reported offset: 898/900 identical; 2 trials changed true_rank only
  (one case, radius 60, offsets -30/-20: 76->67, 80->77). Top-1,
  minute error, delivery coverage and summary are unchanged. Reverting
  only the BUG-1545 files restores the old ranks; reverting shadbala.py
  does not; a different PYTHONHASHSEED gives the same result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 14:13:00 +08:00
ClaudeandClaude Opus 5.5 a6f5ffbb4f docs(sync10): record sync 10 in the ledger, changelog and progress note
Ledger entry for upstream 5fb8379c with target 9d69cd56 and rollback list.
The progress note has the inventory, what was not ported and why, test
results, and the status of the two 2026-10-03 upstream issues. Both are
fixed upstream: KARAKA_8 now follows BPHS order, and Narayana profiles now
reach calc_narayana_mahadasha.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 12:08:51 +08:00
ClaudeandClaude Opus 5.5 2539d57fee docs(skill): take upstream's source corrections to five reference guides
Upstream corrected guides whose calculations we already ported. Our guides
still described the old rules:

- argala: secondary Argala is house 5, blocked by house 9 (PVR Integrated
  Approach 10.5-10.7). The 8th-house and planet-gender rules are dropped.
  scripts/argala.py already does this (BUG-1386).
- sahams: the calculator carries all 36 PVR Table 74 formulas with day and
  night exceptions (BUG-1474). references/saham_rules.json is byte-equal to
  upstream.
- shodasavarga: Shodasa-varga weights are D27 0.5 and D30 1. The old 1 and
  1.5 summed to 21. They now match vimsopaka_calculator.py.
- yogi-avayogi: the mixed historical notes are marked as not a formula. The
  live profile is Sun + Moon + 93 deg 20 min in
  scripts/annual_native/yogi_sphuta.py; the upstream path is adapted.
- ai-reading workflow: adds the 2026-10-02 full-text evidence boundary
  (conditional openings, untested is not "absent", no celebrity fill-in).

event_judgment_wealth and SKILL.md now name finance-timing-strict with
wealth-timing-strict as the legacy alias, as the router already does. Chat
binds only the 商业运行时路由 section of SKILL.md and router sections, so
no chat prompt text changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 11:55:13 +08:00
ClaudeandClaude Opus 5.5 297e27e0bd docs(privacy): swap the leftover private sample for upstream's public example
Upstream replaced the redacted-year sample (April 17, 14:45, about 36.5N
114.2E) with a public birth (1935-06-21 11:00, Cajarc, France) in the
reading workflow and in the narayana-dasha / solar-return usage text. Our
copies still carried the private date, time and place. The PDF guide's
example coordinates now name the San Francisco values it already labels.

Doc and docstring text only; no calculation changes. The same sample is
still a quality-gate fixture in scripts/run_quality_gate.py and appears in
older docs/research notes; neither is changed here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 11:54:12 +08:00
ClaudeandClaude Opus 5.5 3bae79fbca docs(upstream): mirror upstream SKILL.md at main 5fb8379c (sync 10)
Run scripts/import_yinduzhanxing.py --apply from a clean clone of upstream
main 5fb8379c, the upstream HEAD on 2026-11-04. Only the root SKILL.md
moves into references/upstream/yinduzhanxing; the six semantic-merge paths
stay review_required and untouched. The new mirror drops the private
"yn-1993" sample wording the b9a0ef8f mirror still carried.

source-manifest.json and import-plan.json now pin 5fb8379c. The b9a0ef8f
import record stays as history and its test now checks only the record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-04 11:51:04 +08:00
ClaudeandClaude Opus 5.5 578a361460 feat(chart): functional roles, 7/8 Chara Karaka and three new 特殊点 groups (#163 1-3)
/api/chart_points:
- karaka_scheme 7 (default) / 8 / both; shared ranking in
  chart_view_points/karaka_rank.py (unrounded in-sign degree, Rahu reversed
  in the 8 scheme, Ketu out). Bodies equal at full precision mark only the
  roles they span as tied; Goel uses the same ranking (BUG-1512).
- functional_roles: v2 BPHS ch.34 profile laid out per body, nodes pending,
  Yogakaraka / Badhaka / Kendradhipati (conditions not evaluated) as
  separate labels.
- sensitive_points (Bhrigu Bindu per chart node_mode, 64th Navamsa, 22nd
  Drekkana sign-only), sahams (PVR Table 74, nine first, all kept),
  goel_points (printed-text policy, worked example beside it).

盘面数据: 行星 gets Chara Karaka (AK · 自我, 七星/八星 switch), 自然属性,
管辖宫位, 功能角色, 补充身份; 特殊点 splits into 特殊上升 / 敏感点 / Saham /
Goel 特殊点 and the board's 特殊点 layer follows the open group.

jaimini.py, functional_benefics.py and varga.py are untouched (rectification
frozen identity).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
2026-11-02 20:35:31 +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-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-uxandGrok (agent loop) 13f45e3475 docs(sync): note upstream main 5fb8379c without moving the pinned mirror (issue #141)
source_commit stays b9a0ef8f because the pin tests require it and that object was rewritten. The ledger target is the last calculation commit 8aed605a43. hash_contract_result is a prose pass, same shape as the previous entry. Importer --apply was not run.

Co-Authored-By: Grok (agent loop)
2026-10-28 09:47:44 +08:00
jesse-uxandGrok (agent loop) 16bae00615 fix(saham): apply Table 74 before legacy rows (BUG-1474, upstream cb8a1ca7)
Directed-arc sign stays as BUG-1387. formula_traces remains the 36-row report list. Book rows are no longer overwritten by the old house approximation.

Co-Authored-By: Grok (agent loop)
2026-10-28 09:45:06 +08:00
Jesse_ChenandClaude Opus 5.5 ac3dccbac8 fix(yoga): Chinese combination text from a Chinese source, not 未判定 (#91 fix2 F3, BUG-1418)
Removing the English-to-Chinese back-translation left every BVR semantic
note and every yogas_doshas raj/dhana "H*_Lord(...) in H*" sentence as
未判定 in the Chinese yoga table and pages.

- yoga_engine: semantic conditions return BiText(Chinese, old note). The
  Chinese comes from references/yoga_semantic_notes_zh.json, one sentence per
  note, so dedup keeps the same equality classes. English-only custom
  templates get the same lookup. combination_en is unchanged.
- yogas_doshas: raj/dhana rows add combination_zh; combination is unchanged.
- chinese_combination prefers a clean combination_zh.

Which yogas fire, their strength and category are unchanged (fictional
charts 0-19, same rows as staging; only set-iteration order differs).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HwMNZEzdzmrbPhuRNmZe3C
2026-10-22 21:55:02 +08:00
jesse-uxGrok (agent loop)Cursor
ba1ffeb35f fix(report): keep the English edition when one phrase was untranslated
The English personal report was discarded whenever a Chinese fragment survived the trailing glossary. English sections now render the English fields that were already calculated.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 02:56:00 +08:00
jesse-uxGrok (agent loop)Cursor
300a8842d3 fix(synastry): keep the scripts root file count inside the budget
Move the three local glue modules into scripts/marriage_match_service and point the invocation matrix at marriage_match.py. The upstream engine file stays where it is.

Checked the file-count and oracle contracts, the marriage-match tests, and a Windows full pytest. The 176 failures are python3-missing and path-separator noise; the named contracts passed.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 21:33:30 +08:00
jesse-uxGrok (agent loop)Cursor
2cc5c0c128 merge origin/staging into the second marriage-match fix
Keep both changelog sections and both bug-history tails.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 20:29:46 +08:00
Jesse_ChenandClaude Opus 5.5 79f6ac5297 chore(rectification): refreeze sealed and offset replays as upstream_sync8_2026_10_18
Sync8 changed ashtakavarga.py, dasha_analyzer.py and narayana_dasha.py,
which are in the frozen scoring identity. Sealed (20) and reported-offset
(900) replays match the scoring_perf_2026_10_13 records trial for trial,
so ERR-110 stores a new record. Prior records are kept byte-for-byte.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HwMNZEzdzmrbPhuRNmZe3C
2026-10-18 18:57:02 +08:00
jesse-uxGrok (agent loop)Cursor
2f8263b6ac fix(saham): add 30 degrees when the third operand misses the B-to-A arc
Upstream ce9fed15. The exception now tests C on the forward arc from B to A, in both the value and the trace. BUG-1387.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 16:44:43 +08:00
jesse-uxGrok (agent loop)Cursor
cf063834ca feat(synastry): store the upstream seven-item marriage match
Move the bde5d615 engine and full-synastry skill in unchanged, save both profiles without billing or a page, and retire the old synastry module.

Checked targeted pytest, tsc 0, lint 0 errors, service tests 6/6, and test:db 73 pass / 13 fail matching the Windows known list.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 16:44:05 +08:00
jesse-uxandGrok (agent loop) 8e0503f9c0 Speed up rectification scoring without changing results.
Cache work that depends only on the candidate minute, drop unread response fields, and reject windows above 241 candidates before any chart is built. Eleven canonical scenario hashes match 77057a819. Sealed and reported-offset replays match the 2026-10-08 records (changed_trial_count 8 and 581) and are stored as scoring_perf_2026_10_13.

Co-Authored-By: Grok (agent loop)
2026-10-14 02:06:14 +08:00
jesse-uxandJesse_Chen c4fc1044e3 research(rectification): score D12 parent probes, sample underpowered (BUG-1308) 2026-10-12 15:37:00 +08:00
Jesse_ChenandClaude Opus 5.5 db0134f9db test(ephemeris): move the expectations BUG-1275 shifts and regenerate three goldens
Independent Staging Quality Gate / validate (push) Successful in 16m45s
Independent Staging Quality Gate / publish (push) Successful in 4m25s
The nutation branch left the quick gate red: eight expectations still encoded
the mean-ayanamsa frame (dasha boundaries two days late, a solar-return frame
gap that was the bug itself, a 0.01 Kala drift from frozen sidereal fixtures)
and three goldens were never regenerated. Python full suite is back to the
baseline list; quick gate passes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-10-08 22:28:09 +08:00
jesse-ux e5f2a75183 fix(ephemeris): include nutation in the sidereal frame
恒星黄道改为与 Swiss Ephemeris FLG_SIDEREAL 同一套含章动岁差。
产品默认路径不再用平岁差去减含章动的视位置。上升和宫头用同一个岁差。
校正身份升到 rectification-v5-matrix-scoring-12。
BUG-1275。未推送,未部署。v5 先验头名三格下降 1.3 个百分点,不调参。
2026-10-08 18:42:45 +08:00
jesse-ux 3b84a3b028 fix(rectification): re-freeze sealed identity after D5/D11 (ERR-110, BUG-1260) 2026-10-07 18:08:25 +08:00
jesse-ux eb739d4e6b fix(yoga): record Jupiter upachaya from the Moon as a configuration (BUG-1266, upstream 1918ffaf) 2026-10-07 17:36:06 +08:00
Jesse_ChenandClaude Opus 5.5 dda966e656 fix(yoga-rules): English siblings for reference_only_reason (batch-1 left test_report_english_dictionary red)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 17:24:26 +08:00
Jesse_ChenandClaude Opus 5.5 7cb332bce6 feat(narayana): Sanjay Rath profile replayed against the book tables; not wired (BUG-1215)
Round-4 ruling Q4. scripts/narayana_rath.py builds the Rath sequence from the
rule ledger and book rows ported verbatim from upstream yinduzhanxing c7117f92
(sanjay_rath_narayana_book_ledger JSON + md, chara_narayana_book_golden_cases):
Table 10 order (Saturn -> Table 11, Ketu -> reversed), years by
jaimini_odd_footed_dignity_v2 with jaimini_dual_lord_source_v1, ADs twelve
equal parts from the MD sign (Table 13 / 11 / 14), start sign by the existing
select_narayana_seed_sign, ties reported as parameter_sensitive with both
sequences.

Given the book's start sign, Tables 15 / 17 / 18 match 36/36 MD signs and
years. The start sign does not: Table 17 picks Virgo (book Pisces), Table 18
ties (book Cancer). Task red line 2: the profile stays out of every
user-visible surface and out of scoring; T5 trial not run. A test pins that no
script imports it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 16:36:31 +08:00
Jesse_ChenandClaude Opus 5.5 0afcc2d9a3 feat(tajika): year lord by the Panchadhikari rule, ported from upstream c7117f92 (BUG-1214)
Round-4 astrologer ruling Q3. tajika.calc_panchadhikari_year_lord and its
missing pieces (Tri-Rasi tables, planet index maps, ayanamsa-aware PyJHora
lookups) plus references/tajika_panchavargiya_rules.json (blob e8c15ac3) are
ported verbatim from yinduzhanxing c7117f92, with one keyword added
(muntha_sign_idx): upstream builds the Muntha-lord candidate from the annual
Lagna + years; ours stays natal Lagna + completed years (BUG-1212).

Both annual producers (solar_return_full_report, cmd_tajika) call the new
tajika_year_lord.select_annual_year_lord, so the pack conflict gate compares
the same rule. Output carries candidates / candidate_list with Panchavargiya
score and engine, aspect flags, selection_basis and a one-sentence basis
(zh/en). The product path always uses the native proxy (PyJHora is AGPL, absent
from the API image and CI); JYOTISH_YEAR_LORD_PYJHORA_REFERENCE=1 restores the
upstream PyJHora lookup for research. Card varshesha_basis and the report
'Selection basis' rows show the sentence; the BUG-1212 stand-in label is gone.
Mudda Dasha and Tri-Pataka follow the selected year lord.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 16:30:28 +08:00
Jesse_ChenandClaude Opus 5.5 9392f0601b chore(rectification): re-freeze research records for astrologer rulings batch 1 (ERR-110); scores unchanged, no version bump
scripts/jaimini.py (BPHS 8-karaka order), scripts/ashtakavarga.py (calc_sodhita_av
removed) and scripts/shadbala.py (local house score renamed and dropped from the
result) are in the frozen production identity. Records re-frozen under the label
astrologer_rulings_batch1_2026_10_03 (--freeze, then replay; PYTHONHASHSEED=0,
chart cache TTL 0); the upstream_sync5 records become 'previous', byte-for-byte
preserved. Replays identical to upstream_sync5: reported offset 0 of 900 trials
changed, sealed holdout 20 trials and metrics identical. v5 77-case evaluation
unchanged (see PROGRESS). ALGORITHM_VERSION stays rectification-v5-matrix-scoring-10.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 15:00:46 +08:00
Jesse_ChenandClaude Opus 5.5 de79390175 fix(yoga): Pancha Mahapurusha has one main detector; combust/afflicted only reduced (T1, BUG-1207)
Astrologer ruling 甲5. scripts/pancha_mahapurusha.py is the only detector: kendras from
the Lagna; retrograde no longer cancels; combustion (shared orb table), malefic
conjunction and malefic graha drishti (Sun 7, Mars 4/7/8, Saturn 3/7/10) mark the
yoga reduced with reasons; D9 debilitation still cancels when navamsa_sign is given
(current behaviour, ruling silent, asked next round). _detect_yogas now passes the
Sun's longitude (combustion was never checked). mahapurusha_*, *_own, moolatrikona_*,
hamsa_trikona (Jupiter 1/5/9, not classical) and bvr_maalavya_yoga are reference_only;
yogas_doshas.calc_pancha_mahapurusha_yoga is kept as reference_yogas only. The rule
engine appends main-detector rows; cmd_yoga rows now carry lon + retrograde so the
report and card get the same combustion verdict. Card label lists 部分减弱 reasons.

Changed assertions (three columns in PROGRESS): self-conjunction tests (malefic in
same sign: invalid -> reduced), run_all t31/t32 (combust/retro: invalid -> reduced /
full), run_all t54 (evaluated rules >= 400 -> evaluated + reference_only >= 400).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 12:26:22 +08:00
Jesse_ChenandClaude Opus 5.5 6916bbaecc fix(yoga): Kemadruma has one main detector; lunar/solar neighbour yogas count five planets (T2, BUG-1206)
Astrologer ruling 甲7: yoga_expansion.detect_kemadruma is the main detector (2nd/12th
from the Moon count only Mars..Saturn, no kendra cancellation, nodes in kendras do
not cancel). kemadruma_yoga (ky2 kendra cancellation) and kemadruma_variant (nodes as
neighbours) are reference_only; YogaEngine.detect appends the main row.

BUG-1187 omission: the algorithmic _detect_solar_lunar_yogas block still counted the
Sun, Moon and nodes, so Ketu next to the Moon gave 'Anapha Yoga' beside Kemadruma
(Taylor) and Sun/nodes gave Durudhura beside Sunaphaa. Both blocks now count the
five true planets. divisional_yoga compared a 'house' key vargas never carry (always
'isolated') and counted the Sun; it now uses sign adjacency and the same five.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 11:40:54 +08:00
Jesse_ChenandClaude Opus 5.5 df21e591e8 fix(yoga): Neecha Bhanga lists the conditions that hold, never Raja Yoga (T8, BUG-1205)
Astrologer ruling 乙14. One condition source, yogas_doshas.calc_nicha_bhanga_raj_yoga
(conditions A-F, now also structured). New scripts/main_yoga_detectors.py turns it
into yoga_engine-shaped rows (zh + en twins) that YogaEngine.detect appends; the
four neechabhanga_* rules are reference_only (kept, renamed, not evaluated).
Card: traditional_yogas canonical 落陷取消(Neecha Bhanga) with 成立条件; compact
yoga entries keep conditions/reductions. Report: category 落陷取消, mixed group,
not raja; personal-report alias neecha_bhanga -> special.

Changed assertion (test_consultation_yoga_detection_merge): canonical name
'Neecha Bhanga Raja Yoga' -> '落陷取消(Neecha Bhanga)' (ruling 乙14).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 11:38:52 +08:00
Jesse_ChenandClaude Opus 5.5 1029cbaa0a chore(rectification): re-freeze research records for upstream sync 5 (ERR-110); scores unchanged, no version bump
scripts/jaimini.py (Chara Karaka 8 Rahu reversal), scripts/ashtakavarga.py
(Trikona / Ekadhipatya Shodhana, unwired) and scripts/rectification/
decision_policy.py (R1 floor, BUG-1193) are in the frozen production identity.
Records re-frozen under the label upstream_sync5_2026_10_02 (--freeze, then
replay; PYTHONHASHSEED=0, chart cache TTL 0); the upstream_sync4 records become
"previous", byte-for-byte preserved. Replays identical to upstream_sync4:
reported offset 0 of 900 trials changed, sealed holdout 20 trials identical,
metrics equal. ALGORITHM_VERSION stays rectification-v5-matrix-scoring-10.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-10-03 00:15:51 +08:00