- career layer gets the D1 longitudes, so the paksha has one source (Obama
base vs career mismatch fixed)
- card carries movable_lagna_moon.reason, Narayana ad_status / ad_reason and
the mahadasha cycle_index; running line says "sub-period undecided"
- engine keeps the MD when the AD is undecided; timingFollowing skips
zero_duration rows explicitly
- timingKeys allowlist: adstatus / adreason / cycleindex / zeroduration
- fixtures + capture script, 16 engine tests, 7 card tests, PROGRESS, BUG-1812
Co-Authored-By: Grok (agent loop)
The 星历 page gets a month calendar for the chosen person: every day is
吉 / 平 / 凶 with two or three life themes from transits against their own
chart, the selected day opens to its themes and "为什么", and below it
「接下来要留心」, 「这几天」 and 「回看」 (owner, 2026-11-07: A's grid plus
C's lower half).
Engine: scripts/personal_calendar.py joins existing calculators on one
date axis (one call, <0.5 s for 45 days): Panchanga in the subject's own
ayanamsa, Tara / Chandra bala, Moon house from Lagna and Moon,
Ashtakavarga SAV + Moon BAV, transit conjunctions with natal points,
functional benefic / malefic, activity verdicts with native inputs,
ingress / station / combustion / eclipse / Vimshottari AD+PD boundaries,
and a month backdrop (Vimshottari MD/AD/PD, Narayana, Sade Sati / Kantaka,
slow-graha contacts, Jupiter+Saturn double transit). New endpoint
/api/personal_calendar.
BUG-1666: check_activity_muhurta ignored Vishti karana, Vyatipata /
Vaidhriti and an avoided Chandra bala, so a Vishti day could be 大吉.
BUG-1667 (closes BUG-703 / BUG-707): /api/panchanga_range now honours the
requested ayanamsa; the day view asks for the subject's own and drops the
Lahiri note.
Frontend: /api/ephemeris/month (own rate-limit bucket, cached),
/api/ephemeris/checks + migration 20261107010000_ephemeris_day_checks
(answers kept with the birth declaration they were made under). Copy is
life-first with the sky events folded under 为什么; draft wording pending
the astrologer. TASK-ephemeris-page decisions 4/6 and hard lines 3/7/9
superseded per the owner; DESIGN.md §16 updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
The full reading and the dasha registry called the Kalachakra module without
the Moon longitude, so BUG-1487's PVR ch.24 sign periods never ran in the
product. The report printed the legacy approximation (planet lords, 7..18
years) under a "simplified model" label.
Both callers now pass the Moon longitude. The dasha family carries
method_profile. Classical results keep their own AD/PD rows instead of the
rotated simplified table, and the reader and research tables list signs.
The PyJHora comparison was rerun: majors now agree, sub-period division still
differs (documented).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
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
Part 2 of #144.
- The varga-segments scan gains opt-in stability_items: lagna degree, Sripati
cusp signs, Moon sign / nakshatra / pada / house per minute, plus a
historical-timezone check. The precheck requests D1/D9/D10 with it.
- Chart page shows nine computed items (一致 / 有变化) only for a range the
user gave, the verbatim comparison sentence, a verify-first block for the
conditions stored data can show, and the verbatim Dasha boundary sentence.
- Precheck sends the chart's ayanamsa and node mode and drops replies with
other settings; the endpoint honours node_mode. candidate_time_sensitivity_scan
and flexible_birth_time_profile take no defaults (BUG-1515).
- 只记得时辰 third question, stored in birth_time_clue; no migration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
Verify-only run on the intake branch: tsc 0 errors, lint 0 errors, the ten
changed frontend test files 105/105, and test:db 98 tests with 82 passing.
All 13 known Windows failures still fail; three tests in
database-segment-saved-native.test.ts fail only because the Windows Python
alias returns 9009, and they pass 3/3 when PYTHON points at the repo venv.
No source, test or migration changes. Flagged for a decision instead of
fixing, per the brief.
Co-Authored-By: Grok (agent loop)
jesse chose A: keep asking for the source, stop mapping a source to a
fixed error, let the user give earliest/latest or "error unknown", and
add the columns needed (additive only). Part 2, per-item stability over
the range, is a separate queued issue.
Co-Authored-By: Claude (agent loop) <noreply@anthropic.com>
Shadbala (Q4): one rule everywhere, total / the body's own BPHS minimum.
100 % or more is 达标 (light green), below is 未达标 (light warm tint), a
body the engine left out is grey 未计算, never 0. The 120 % / 90 % strong /
medium / weak tiers are gone from the inspector, 命盘速览, 能量图谱, the board
星力 tags and the data card.
Dasha (Q5): MD 大运, AD 小运, PD 细运 across the chart page, 深读, inspector,
命盘速览, the data card, board chips and the consult / report-reading model
prompts. The board keeps the wash on the houses the period lord rules, adds
an outline on the house it sits in, drops the lines between period lords,
and gets a 「从运主起算」 toggle that renumbers the houses from the lord with
a 「宫位从某星起算」 chip. Chara marks the lord the engine used (co-lords as
returned) and outlines its house from the engine's lord_in_sign.
敌友 (Q6): the centre defaults to the lagna lord (the Moon with a chip when
the lagna may change), remembered per browser; the seven grahas only;
natural, temporary and compound side by side plus the reverse direction;
the board says which relationship it shows.
瑜伽 (Q7): highlight only, no array-order lines (the yoga rows carry no
relation data).
Names (Q8): 八分法 (title 八分法(Ashtakavarga)), BAV / SAV labels,
Arudha 映射.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
Twelve domains x five astrologer-reviewed prompts fill the composer and
select the first blank. Phone bottom sheet, desktop popover; hidden for
synastry, rectification and incomplete profiles. No extra model call.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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)
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>
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)
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)
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>
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>
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>
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.
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.
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)
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)
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>