Astrologer ruling 甲13. shadbala.calc_bhava_bala renamed calc_local_bhava_score and
removed from calc_shadbala's result (it fed the report's Bhava Bala table). New
bhava_bala.bhava_bala_from_chart (Bhavadhipati = lord's Shadbala virupas, Bhava
Dig, Bhava Drishti; equal houses as /api/bhava_bala; total and total_rupas; the
module's invented level bands not shown) drives modules.bhava_bala in the full
reading. Reader table: Bhavadhipati | Dig | Drishti | Total (Virupa) | Total
(Rupa); reference edition table and wealth/summary lines read the formal totals.
Other users of the local score: none outside shadbala.py (remedies and health
narrative read Shadbala rupas only).
Changed assertions (three columns in PROGRESS): test_shadbala_complete local-score
tests renamed; test_report_longform_gaps2 fixture rows and heading.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Astrologer ruling 乙8. New scripts/ashtakavarga_shodhana.py: per BAV row Trikona then
Ekadhipatya (the two existing ashtakavarga functions, previously only called by
tests), Sodhita SAV = sum of reduced rows; occupied signs = seven grahas. Removed
calc_sodhita_av (Sun/Mars/Saturn contribution removal labelled 'BPHS标准').
Wired into /api/ashtakavarga (result.sodhita, house_scores[*].sav_sodhita) and the
full reading. Reader: SAV table 'Sodhita SAV | Raw SAV', house table gains
Sodhita column, Sodhita BAV table before raw BAV; reference edition section
rewritten. Card: sav_sodhita before sav_score plus sav_columns label. Personal
report facts: score = Sodhita, rawScore/savRawTotal beside (optional schema
fields). Fact tables: Sodhita column and Sodhita BAV subtable. Transit scoring
unchanged (raw bindus).
Golden: report-density-fictional-engine.json leaf worksheets.strengths_and_scores
.ashtakavarga recaptured from the real engine (scripts/research/refresh_density_
fixture_ashtakavarga.py); bav/sav identical, every other leaf byte-equal.
Changed assertions (three columns in PROGRESS): BUG-1200 house-table tests,
report-fact-tables ashtakavarga columns/subtables, run_all t1/t57.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Astrologer ruling 甲13. New scripts/shadbala_display.py (display only; shadbala.py is
frozen and unchanged): chart.shadbala now carries min_required, meets_minimum,
minimum_check (达到/未达到 BPHS 最低要求), level_source=site_band and level
'<band>(网站分档)'; report Shadbala table gains 'BPHS minimum' and 'Site band'
columns (zh/en); evidence snapshot ranking and health narrative say the minimum
check first and mark the band as the site's.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
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
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
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
KARAKA_8 put Putrakaraka 5th, Darakaraka 7th and Pitrukaraka 8th. BPHS ch. 32
order with Rahu counted is AK, AmK, BK, MK, PiK, PK, GK, DK. Test pins the
table and a public AA chart (Steve Jobs, Raman, mean nodes) plus the reader
report's live 8-karaka rows. jaimini.py is in the frozen rectification identity;
re-freeze follows in a separate commit (rectification does not read karakas).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
- Report p33 table: no Kranti column (no producer; materials.kranti stays blocked).
- Report p53 table: the "SAV" column was the with-Lagna total (386). Split in the
reader into SAV / Lagna BAV / SAV + Lagna with a totals row; ashtakavarga.py is
untouched (frozen rectification identity, ERR-115).
- /api/chart ascendant carries nakshatra / pada / lord (_nakshatra_fields shared with
the nine bodies); chart cache schema 4 -> 5.
- /api/varga_full bodies carry dignity_level from varga_dignity_level, the function
the Vimsopaka path now shares (A/B identical); the chart page shows the D1 status
wording and no longer derives a three-level dignity itself.
- Report page draws each chart once: the trailing block skips charts the body already
fenced (same rule as the export); the birth-time caveat moves under the body's
chart heading.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
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
Product decision 2026-10-02 (TASK-upstream-sync5 R1): a time range is offered
only with at least 4 dated, primary-scoreable events covering 3 domains,
counted on all of them (training + reserved holdout). Was 3 training events /
2 domains in three TS copies and the Python acceptance gate while the policy
file already said 4/3.
- One definition: references/rectification_policy.v1.json
(minConfirmationEvents / minConfirmationDomains). TS core/types MIN_DATED_*,
rectification-decision MIN_STANDALONE_*, evidence-model MIN_ACCEPTANCE_*,
the convergence evaluator and the post-inference trainingGateOpen all read
it; Python decision_policy MIN_ACCEPTANCE_* alias MIN_CONFIRMATION_*.
- Python receipt counts all scoreable events / domains for event_quality and
domain_diversity; decision policy identity v3 -> v4 (candidate UUIDs carry
it). Candidate scores unchanged (77 v5 cases A/B identical), so the
algorithm stays rectification-v5-matrix-scoring-10.
- Memoization golden v3 written by write_golden; v2 frozen by sha256 with a
test that its scores equal v3 and only the receipt policy moved.
- Collect gap copy names the exact gap ("再来两件……其中至少一件不是……")
instead of always "再来一件"; VOICE.md updated. Legacy life-events form copy
4/3 as well.
- 30 frontend test files, 4 Python tests: fixtures extended to the same
scenario at 4/3, or assertions changed with 原值/新值/原因 notes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Preta Yoga hard-coded the 11th house as Badhaka; it now uses the single
yoga_engine.badhaka_house() definition (movable 11 / fixed 9 / dual 7).
Remaining early-death / lineage-ending phrases removed from curse yoga
family effects and the Matru-hani yoga effects list.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
A combust Mercury keeps the Budha-Aditya formation visible but downgrades it
to conditional. Upstream's other card-gating fields in the same hunk come
from separate commits and are not taken. TASK-upstream-sync5-20261002 U7.
(cherry picked from commit 994638f0)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
(nakshatra + 3) mod 8 seed. The upstream edit to
tests/test_dasha_master_pack_coverage.py is dropped: that file does not
exist here. TASK-upstream-sync5-20261002 U5.
(cherry picked from commit cb7fe017)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
One direct / retrograde orb table (Moon included) in the shared
COMBUSTION_ORBS / is_combust, used by the full reading and the consultation
graha-drishti layer. TASK-upstream-sync5-20261002 U3.
(cherry picked from commit 080c286c, resolved onto our shared helper)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
scripts/shadbala.py is in the frozen scoring identity (dataset
frozen_scoring.files), so the ported Kala/Chesta fixes and the BPHS Sun
minimum (BUG-1188/1189) turned the integrity gate red although the scorer only
reads the Sthana/Drik/Naisargika components. Records re-frozen under the label
upstream_sync4_2026_10_02 (--freeze, then replay; PYTHONHASHSEED=0, chart cache
TTL 0); the functional_v2 records become "previous", byte-for-byte preserved.
Replays are identical to functional_v2: reported offset 0 of 900 trials
changed, sealed holdout 20 trials identical; memoization golden v2 scores
unchanged and the v5 77-case evaluation is byte-identical to a18f8d4e, so
ALGORITHM_VERSION stays rectification-v5-matrix-scoring-10 (decision 6 only
bumps on a score change).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
With the aspect count from 1 (42d1582f) the public charts get same-layer
overlaps for the first time, and the overlap / cross-layer loops iterated
Python sets, so the double_transit list order changed with PYTHONHASHSEED
(the D1/CL golden failed under seeds 1 and 2). The loops now iterate sorted
names; the golden is recaptured and passes under seeds 0/1/2/5.
tests/test_double_transit_cross_layer_pairing.py: three expectations updated
with original / new / reason (Jobs house-7 summary now leads with the D1
layer; the ninth-house non-pairing example moves to Jobs house 9; the
same-house set is recomputed).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
BPHS ch. 27 (Evaluation of Strengths) sl. 32-33 gives 390, 360, 300, 420, 390,
330 and 300 virupas for Sun..Saturn; the Sun was 5.0. MIN_REQUIRED in
scripts/shadbala.py is the only requirement table in our code (the 5.0 default
in .get() is for unknown bodies; vendored jyotishganit / dashaflow tables
already say 6.5). Upstream yinduzhanxing 0a6696c5 still has 5.0 (to notify).
Product decision 2026-10-02 (added to TASK-upstream-sync4-20261002).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
TASK-upstream-sync4-20261002 T6, decision 4. Visible parallel calculators were
found in three places and all now read jaimini:
- yogas_doshas.calc_arudha_lagna / calc_upapada_lagna (house number taken as an
Aries-based sign index, no 1/7 exception) are deleted; the module's
arudha_lagna / upapada_lagna fields come from jaimini.
- special_lagnas.calculate_arudha_lagna / calculate_upapada_lagna ("count from
the landing" 1/7 exception, which disagrees with jaimini when the lord is
4th/10th from the source) are deleted; the full reading's Arudha_Lagna /
Upapada_Lagna rows are built from jaimini padas.
- the transit multi-reference table took "ascendant degree + 12th-lord degree"
as AL; it now uses jaimini's A1.
jaimini's own exception counting is unchanged (astrologer question 5); the
upstream "count from the landing" variant is not ported. A10 in special_lagnas
keeps its own exception rule (outside decision 4; listed in progress).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
TASK-upstream-sync4-20261002 T1 (upstream yinduzhanxing 0afa2780 for the
idea; wording is ours, in Chinese, per decision 2). _interpret_marriage_count
and _marriage_recommendations no longer state relationship counts, order,
quality or loyalty; the Marriage-counting evidence is always neutral and
carries only geometric_index (the dead D9-quality line in the adjudication is
removed). The count is computed before the Parivartana override (the old order
raised UnboundLocalError) and the exchange check now tests a real exchange
instead of a conjunction with the dispositor.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
final_dispositor_from_chain and its regression test are upstream
yinduzhanxing e9beae6b; probability is None with probability_basis. The
Narayana convergence additions of that commit are out of scope.
TASK-upstream-sync4-20261002 T7.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Ported from yinduzhanxing 0afa2780 (algorithm hunks and its four regression
tests; the PyJHora / profile-metadata hunks do not apply to our file). The
archived-PyJHora Kala test follows upstream's rewrite. The V.P. Jain
benchmark expectations still need the three-column update (follow-up in this
branch). TASK-upstream-sync4-20261002 T3.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
bvr_002..004 (Sunaphaa/Anaphaa/Duradhara) and bvr_016..018 (Vesi/Vosi/
Ubhayachara) take upstream yinduzhanxing 2dd6062a's logic (Mars..Saturn
only). kemadruma_yoga also ignores the nodes (product decision: classical
definition; upstream still counts them). The six lunar/solar duplicates of
upstream's RETIRED_RULE_IDS are retired; upstream's four other retirements
are out of scope. TASK-upstream-sync4-20261002 T5.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Saturn's 7th aspect was judged on the 8th house, Jupiter 5/9 on 6/10, Mars
4/8 on 5/9. Ported from yinduzhanxing 2dd6062a with product authorization
(TASK-upstream-sync4-20261002 T2).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Functional roles feed the *_functional_*_auxiliary rules, so 57782aea changes
candidate scores for identical input (memoization fixture 12:00: 8.6274 ->
8.4977). Per the "scoring semantics change => bump ALGORITHM_VERSION"
precedent (scoring-7 -> 8 -> 9), the identity moves to scoring-10; policy v3,
input contract v5 and Skill versions are unchanged, history is not relabeled.
Five frontend sites and one SQL guard tested `=== "...scoring-9"` for the
dated candidate-window contract; they now use isDatedScoringAlgorithmVersion /
a generation regex (>= 9). Migration 20261002010000 only recreates
validate_dated_rectification_candidate (one-line guard change).
Memoization golden v2 written by the test's own write_golden; v1 (scoring-8)
frozen by sha256. Real-engine scoring-10 cross-midnight golden added. Research
records re-frozen per ERR-110 (label functional_v2_2026_10_02) and
scripts/functional_benefics.py added to the frozen production identity
(ERR-114: 57782aea changed scores without tripping it).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Ported verbatim from the upstream skill repo (yinduzhanxing e9beae6b) with
product authorization 2026-10-02: scripts/functional_benefics.py,
scripts/pancha_mahapurusha.py, references/functional-role-profile.md; only
the two functional-role methods of scripts/yoga_engine.py (our file diverged).
v5 77-case rectification eval: 5 cells up (to +7.8pp), one cell -1.3pp (one
case); product accepted. Rectification memoization golden still to be
regenerated (scores change with the grouping).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
TASK-consult-no-presupposition-and-backtest-20261001 T4 infrastructure only
(T1-T3 untouched). New files only, so it merges cleanly with the parallel
evidence-card brief.
- capture_consult_biography_backtest_golden.py: same handler/body/trim as the
evidence-card golden; nine public AA charts x parents/marriage/health/career.
- consult-biography-backtest-golden.json: real engine output, byte-reproducible.
- consult_biography_backtest_rubric.json: facts with sources, must_not,
expected_signals per figure x domain.
- consult-biography-backtest.mts: runs the product's real agent, tools, card,
methodology, user-turn shape and streamAgentResponse; deterministic checks only.
- Baseline on 9b937c4a: 39/72 severe biography conflicts; all five audit cases
reproduce in both runs.
BUG-1170 is registered when brief 3 lands.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
TASK-consult-card-affliction-data-20261001 T1-T4 (BUG-1154~1157, BUG-1159 mitigation).
- Engine layer graha_drishti (aspects.calc_house_aspects; combustion via the
full reading's own rule, extracted as jyotish_engine.is_combust, orbs
unchanged); yoga_domains (fixed Raman packet table by rule_id, with the
sieve's hit); slow_transits.saturn_from_moon_house.
- Card: planets get aspected_by / conjunct_with / combust (true only);
domain house rows get aspected_by; parents roles get lord_rows and
significator_rows with functional class, D12 house lord and its sign;
health houses [1,6,8,12], education [4,5,9]; annual copies
saturn_from_moon_house; yogas filtered by domain tag with hits.
- Budget (D6): antardashas as [lord, start, end], D9 vargottama only when
true; all 12,000-char assertions unchanged.
- Golden regenerated by the real engine; jyotish_api_server.py untouched.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
The staging publish job built the web image without frontend/tests, and
next build type-checks every .ts under frontend/, so the harness importing
../tests/helpers/postgres-fixture.ts failed with TS2307. The harness depends
on the test fixture, so it now lives in frontend/tests/research; the Python
driver points there. A new test fails if src/ or scripts/ import tests/.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
Review-only snapshot for BUG-1115 through BUG-1117; not merge-ready. New opening and append-turn PostgreSQL permission failures remain blocked. Persisted joint replay has zero completed questions; segment ordering remains off by default. The existing offline replay JSON is retained stale and unchanged after a denied overwrite, including its CRLF line endings. Browser/provider validation and final serial gates remain pending. No deployment, role permission changes, or staging/main push.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Bundled media carry Next's per-deploy ?dpl= and were downloaded again after
every release. Bytes unchanged; /fonts/serif-sc/* is immutable. Overturns the
serif-headings contract line "bundled by Next, not served from public/"
per TASK-home-first-load-20260930 decision 2.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
Archive research scripts, regression tests, M1 results and safe M0 smoke. Keep the incomplete study and failing quick gate explicit. Exclude full M0 JSON, raw logs and unrelated oracle newline changes.
Co-Authored-By: Claude Code <noreply@anthropic.com>
- /api/professional_report_reference accepts languages [zh,en]; one packet, zh
byte-identical, markdown_en + reader_dasha_applicability_en, or
english_unavailable when a Chinese character would leak.
- pl9_reader_english renders the parity volume with report_language=en and a
fixed term table; yoga_engine carries combination_en / effects_en / strength_en.
- 75 fictional charts: zero Han, same line count, same numbers outside yoga tables.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE