Repository navigation
feat(solar): derive the equation of time instead of approximating it - #60
seonghobae wants to merge 1 commit into
Conversation
Issue #58 measured the existing `_equation_of_time_minutes` in `calendar.py`, an unsourced three-term sine fit, at up to 81 seconds from a standard reference. This adds the derived value so that the risky half of that repair, the celestial mechanics, is implemented and independently verified. I was wrong in #58 about what it takes. I wrote that apparent right ascension had to be exported from `solar.py` first. It does not: Meeus 28.3 computes the equation of time from the Sun's geometric mean longitude, mean anomaly, eccentricity, and true obliquity alone. Only nutation in obliquity was missing, and it is a four-term companion to the nutation in longitude already here. The tests check the result against values every almanac publishes rather than against this code: the minimum is -14.23 minutes on 11 February, the maximum is +16.49 minutes on 3 November, and the curve crosses zero on 16 April, 13 June, 2 September, and 25 December. Worst disagreement with the removed-in-future approximation across 2026 is 1.12 minutes, 67 seconds, on 5 December. `calendar.py` is deliberately NOT switched over in this change. Doing so advances `CALCULATION_VERSION`, and that value is pinned in seven places by design so a calculation change cannot pass unnoticed. Three of them sit in files open pull requests occupy: `scripts/product_gap_audit.py` (#31, #37, #39), `docs/technical/TRD.md` (#31, #35, #38, #39), and `src/four_pillars/models.py` (#31). Reaching into those from here is the conflict bypass this project's collaboration rule forbids, so the switch stays one small follow-up on #58 with the pin sites listed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
Changes균시차 계산
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Feature Merge Risk: ⚪ Minimal · up to No merge-blocking issue was established in the reviewed change. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
seonghobae
left a comment
There was a problem hiding this comment.
exact 878b48a20ffe70830edfa2b7552be6f52591725a에서 식 자체보다 verification/doctoring이 아직 계산-version 변경을 지탱하기 부족합니다.
현재 tests는 2026년의 extrema 날짜/넓은 값 범위와 zero-crossing 날짜만 봅니다. 이 정도 shape test는 계수가 몇 초~수십 초 틀려도 그대로 GREEN일 수 있어, PR 본문의 “published almanac values against independent astronomy”와 실제 evidence가 대응하지 않습니다. 테스트/CHANGELOG에도 어느 연감·판본·표·행에서 값이 왔는지 provenance가 없습니다.
또 docstring/CHANGELOG는 이 함수가 apparent_solar_longitude와 “same time scale and corrections”를 쓴다고 하지만 구현은 그 함수의 apparent longitude 결과, nutation-in-longitude, aberration을 사용하지 않고 Meeus-style low-order EoT series와 4-term nutation-in-obliquity approximation을 별도로 계산합니다. 공식 USNO는 EoT를 apparent solar time − mean solar time으로 정의하고, approximate solar-coordinate path에서는 EqT = q/15 − RA로 제시하며, 별도 geocentric data service에서 Sun의 EoT를 1800–2050에 제공합니다: https://aa.usno.navy.mil/faq/eqtime , https://aa.usno.navy.mil/faq/sun_approx , https://aa.usno.navy.mil/data/geocentric . 따라서 현재 표현은 ‘같은 corrections’라기보다 별도 근사식입니다.
RED: right-cleared USNO/Astronomical Almanac reference에서 고정 시점 표본을 frozen fixture로 넣고 source URL/판본, 조회 시각, UT1/TT 해석을 기록하십시오. extrema/zero-crossing뿐 아니라 연중 여러 고정 시점에 대해 signed error, max absolute error, RMSE를 계산해 predecessor와 current를 함께 비교하고, 계산-version을 올리기 전에 제품이 허용할 error budget을 명시적으로 정하십시오. live network test가 아니라 committed fixture여야 합니다.
GREEN은 둘 중 하나입니다. (a) 이 구현을 명시적으로 Meeus 28.3 계열 approximation으로 doctoring하고 독립 fixture에 대한 실제 error bound를 release acceptance로 고정하거나, (b) ‘same apparent corrections’가 제품 요구라면 canonical apparent-Sun RA/longitude pipeline에서 EoT를 유도해 correction source를 하나로 만드십시오. 어느 쪽이든 현재 coarse shape test만으로 #58의 replacement를 계산-version successor로 승격하면 안 됩니다. 기존 timezone-invariance/naive-datetime tests는 그대로 보존하십시오.
There was a problem hiding this comment.
Pull request overview
OpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed.
Findings
1. HIGH Current-head GitHub Checks - Fix failed required checks before approval
- Problem: Failed same-head checks remain for
878b48a20ffe70830edfa2b7552be6f52591725a. - Root cause: The model-unavailable evidence fallback is allowed only when peer GitHub Checks are complete and clean.
- Fix: Read and fix the failed check logs below, then rerun the current-head checks.
- Regression test: Keep the model-unavailable fallback gated on an empty failed-check rollup.
Failed checks:
- CodeQL PR/CodeQL compatibility analysis (actions): FAILURE (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964457/job/104245083086)
- CodeQL PR/CodeQL compatibility analysis (python): FAILURE (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964457/job/104245083085)
- CodeQL compatibility analysis (actions) check run: failure (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964457/job/104245083086)
- CodeQL compatibility analysis (python) check run: failure (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964457/job/104245083085)
- Required Noema Review/noema-review: FAILURE (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964438/job/104245534593)
- Strix Security Scan/strix: CANCELLED (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964439/job/104251403706)
- Strix Security Scan/strix: cancelled (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964439/job/104251403706)
- noema-review check run: failure (https://github.com/ContextualWisdomLab/four-pillars/actions/runs/34911964438/job/104245534593)
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Repository file: CHANGELOG.md"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Repository file: CHANGELOG.md"]
R1 --> V1["required checks"]
Evidence --> S2["Python package: solar.py"]
S2 --> I2["Python runtime API"]
I2 --> R2["Review risk: Python package: solar.py"]
R2 --> V2["pytest plus coverage"]
Evidence --> S3["Test: test_equation_of_time.py"]
S3 --> I3["regression suite"]
I3 --> R3["Review risk: Test: test_equation_of_time.py"]
R3 --> V3["targeted test run"]
OpenCode Review Overview
|
|
Exact-head admission audit: 현재 blocker: 활성 CHANGES_REQUESTED 1건; terminal workflow: CodeQL PR:failure. 유효 commit·diff·review evidence를 보존한 채 Draft/Proposed로 교정합니다. Base 이동이나 queue 대기만을 이유로 Close하지 않으며, Force Push·synthetic status/approval·manual rerun·bypass는 사용하지 않습니다. Blocker 수리 후 새 exact head에서 Checks와 review admission을 다시 받아야 합니다. |
What this lands, and what it deliberately does not
#58 measured the existing
_equation_of_time_minutesincalendar.py, an unsourced three-term sine fit, at up to 81 seconds away from a standard reference. This change implements and verifies the replacement. It does not switchcalendar.pyover, for a reason given at the end.I was wrong in #58 about the cost, and this corrects it
I wrote there that apparent right ascension had to be exported from
solar.pybefore the equation of time could be derived. That is not true. Meeus 28.3 computes it from the Sun's geometric mean longitude, mean anomaly, orbital eccentricity, and true obliquity alone. The only missing piece was nutation in obliquity, a four-term companion to the nutation in longitude the module already had.So the repair is materially smaller than I estimated, and the hard part is now done.
Verified against published astronomy, not against this code
Checking a replacement against my own derivation would prove nothing. The tests assert the shape of the curve every almanac publishes:
Two further tests pin that a naive datetime is refused, since an instant is required, and that the same instant expressed in another timezone yields the same correction.
Worst disagreement with the approximation this will eventually replace, across all of 2026: 1.12 minutes, or 67 seconds, on 5 December.
Why
calendar.pyis untouched hereSwitching the apparent solar time basis onto this function changes
normalized_birthfor everyapparent_solarchart, which changes its fingerprint, which meansCALCULATION_VERSIONmust advance. That value is pinned in seven places by design, so a calculation change cannot pass unnoticed. I confirmed that by making the switch locally: the golden-fixture test and the product-gap audit both failed immediately on the stale pin, which is the mechanism working exactly as intended.Three of those pins sit in files that open pull requests occupy:
scripts/product_gap_audit.pydocs/technical/TRD.mdsrc/four_pillars/models.pyReaching into those from a separate branch is the conflict bypass this project's collaboration rule forbids. The switch therefore stays a single small follow-up, and I have listed every pin site on #58 so whoever holds those files can do it in one pass.
Worth noting from the same local trial: the KASI golden fixtures for the 2026 Li Chun year-pillar transition still passed. The solar-term timing is untouched; only the apparent-solar normalization would move.
Verification
pytest -m 'not nim_live' -W error::ResourceWarning --cov=four_pillarsruff check .compileall src scriptsscripts/check_docs.pyscripts/product_gap_audit.py🤖 Generated with Claude Code
Summary by CodeRabbit
새 기능
테스트
문서