merge: sync remaining observation packets

This commit is contained in:
732642856
2026-07-23 22:04:07 +08:00
5 changed files with 612 additions and 2 deletions
@@ -5,8 +5,8 @@
"production_tuning_allowed": false,
"boundary": "Index of current governance packets only. Raw oracle artifacts remain in references/oracle/artifacts and are not all duplicated here.",
"summary": {
"packet_count": 183,
"blocked_or_partial_count": 167,
"packet_count": 185,
"blocked_or_partial_count": 169,
"human_review_required_count": 4
},
"packets": [
@@ -1473,6 +1473,22 @@
"claim_status": "one_reviewer_confirmed_second_required",
"consumer_policy": "human_review_required",
"claim_boundary": "One reviewer confirmation advances candidate governance but reviewer 2 is still missing, so the two-reviewer freeze requirement and timing claim upgrade remain unsatisfied."
},
{
"claim_boundary": "Three fixed public/synthetic PyJHora cases show Panchanga field observations and Gulika formula deltas. Maandi and Muhurta windows remain raw observations; no automatic election, prediction, or truth upgrade is permitted.",
"claim_status": "observation_only",
"consumer_policy": "research_observation_only",
"domain": "panchanga_gulika_muhurta",
"packet_id": "pyjhora_multi_case_panchanga_gulika_replay_2026_07_23",
"path": "references/oracle/pyjhora_multi_case_panchanga_gulika_replay_2026_07_23.json"
},
{
"claim_boundary": "KP house cusp star/sub/sub-sub raw from VedicAstro runtime. Observation-only until matched against complete public numeric KP worked examples.",
"claim_status": "observation_only",
"consumer_policy": "observation_only",
"domain": "vedastro_kp_house_cusp_runtime",
"packet_id": "vedicastro_kp_house_cusp_probe_steve_jobs_sf_runtime_2026_07_23",
"path": "references/oracle/vedicastro_kp_house_cusp_probe_steve_jobs_sf_runtime_2026_07_23.json"
}
]
}
@@ -0,0 +1,281 @@
{
"scope": "pyjhora_multi_case_panchanga_gulika_replay",
"claim_status": "observation_only",
"consumer_policy": "research_observation_only",
"production_tuning_allowed": false,
"truth_matrix_allowed": false,
"license_boundary": "agpl_observation_only_do_not_vendor",
"cases": [
{
"case_id": "synthetic_beijing_1990",
"input": {
"date": "1990-01-01",
"time": "12:00:00",
"place": "Beijing",
"latitude": 39.9042,
"longitude": 116.4074,
"timezone": "+8.0",
"ayanamsa": "Lahiri"
},
"pyjhora_raw": {
"gulika": [
0,
21.86746645438376
],
"maandi": [
1,
3.2201065576970933
],
"tithi": [
5,
11.401823527467947,
34.6584870278223
],
"nakshatra": [
23,
4,
-14.853022746851815,
14.859636315765911,
24,
4,
38.51772116304289
],
"yogam": [
16,
8.958840534945733,
31.144813742828212,
0.862924225295027
],
"karana": [
9,
11.401823527467947,
23.03015527764512
],
"raahu_kaalam": [
"08:50:12",
"09:59:24"
],
"yamaganda_kaalam": [
"11:08:36",
"12:17:49"
],
"durmuhurtam": [
"12:36:16",
"13:13:10",
"14:26:59",
"15:03:54"
],
"abhijit_muhurta": [
"11:59:21",
"12:36:16"
]
},
"field_comparison": {
"tithi": {
"local": 5,
"pyjhora": 5,
"status": "match"
},
"nakshatra": {
"local": 23,
"pyjhora": 23,
"status": "match"
},
"yogam": {
"local": 16,
"pyjhora": 16,
"status": "match"
},
"gulika": {
"local_degrees": 22.154273,
"pyjhora_degrees": 21.86746645438376,
"delta_degrees": 0.28680654561622987,
"status": "observed_formula_comparison"
}
},
"raw_sha256": "5fc5a16707ec2c534ac1362ef41abfafc3bad884dcc9f1ad19918a06cd596082"
},
{
"case_id": "public_smoke_chennai_1996",
"input": {
"date": "1996-12-07",
"time": "10:34:00",
"place": "Chennai",
"latitude": 13.0878,
"longitude": 80.2785,
"timezone": "+5.5",
"ayanamsa": "Lahiri"
},
"pyjhora_raw": {
"gulika": [
7,
21.383659705803353
],
"maandi": [
8,
0.9728038266439683
],
"tithi": [
27,
3.794324939203282,
27.737153187822777
],
"nakshatra": [
15,
1,
10.027826442502807,
34.17010921765149,
16,
1,
57.534226468779096
],
"yogam": [
5,
1.708026918006322,
24.459678359544334,
0.6106375061410549
],
"karana": [
53,
3.794324939203282,
15.76573906351303
],
"raahu_kaalam": [
"09:11:27",
"10:35:55"
],
"yamaganda_kaalam": [
"13:24:50",
"14:49:18"
],
"durmuhurtam": [
"07:52:37",
"08:37:40"
],
"abhijit_muhurta": [
"11:37:51",
"12:22:54"
]
},
"field_comparison": {
"tithi": {
"local": 27,
"pyjhora": 27,
"status": "match"
},
"nakshatra": {
"local": 15,
"pyjhora": 15,
"status": "match"
},
"yogam": {
"local": 5,
"pyjhora": 5,
"status": "match"
},
"gulika": {
"local_degrees": 230.491313,
"pyjhora_degrees": 231.38365970580335,
"delta_degrees": 0.8923467058033623,
"status": "observed_formula_comparison"
}
},
"raw_sha256": "71f27a8506bd316782f1f67422bc2f439fe10c2f146ce61818ea5bf7a519a1a2"
},
{
"case_id": "synthetic_london_2000",
"input": {
"date": "2000-06-21",
"time": "06:30:00",
"place": "London",
"latitude": 51.5074,
"longitude": -0.1278,
"timezone": "+1.0",
"ayanamsa": "Lahiri"
},
"pyjhora_raw": {
"gulika": [
4,
14.741959946166133
],
"maandi": [
4,
25.579883181279968
],
"tithi": [
19,
-16.859470689461304,
9.414198800364817,
20,
9.414198800364817,
35.56876152480244
],
"nakshatra": [
22,
4,
7.246692047412758,
7.246706958152929,
23,
4,
33.904123331811256
],
"yogam": [
27,
-16.974349258973135,
7.887321996036926,
0.055801638517445434,
9,
7.887321996036926,
46.13306196606291,
1.0
],
"karana": [
38,
-3.7226359445482435,
9.414198800364817
],
"raahu_kaalam": [
"13:02:19",
"15:05:22"
],
"yamaganda_kaalam": [
"06:53:10",
"08:56:13"
],
"durmuhurtam": [
"12:29:30",
"13:35:08"
],
"abhijit_muhurta": [
"12:29:30",
"13:35:08"
]
},
"field_comparison": {
"tithi": {
"local": 19,
"pyjhora": 19,
"status": "match"
},
"nakshatra": {
"local": 22,
"pyjhora": 22,
"status": "match"
},
"yogam": {
"local": 27,
"pyjhora": 27,
"status": "match"
},
"gulika": {
"local_degrees": 134.404229,
"pyjhora_degrees": 134.74195994616613,
"delta_degrees": 0.33773094616614685,
"status": "observed_formula_comparison"
}
},
"raw_sha256": "ffd49a9e39b67dcf35dc056a6e053653606c2776f7b2d4bdead1d60a9a8f7df0"
}
],
"boundary": "Three fixed public/synthetic cases compare field observations only. Maandi and Muhurta windows remain raw observations; no automatic election, prediction, or truth upgrade is allowed."
}
@@ -0,0 +1,227 @@
{
"boundary": "KP house cusp star/sub/sub-sub raw from VedicAstro runtime. Observation-only until matched against complete public numeric KP worked examples.",
"claim_status": "observation_only",
"created_at": "2026-07-23",
"dependency_identity": {
"flatlib": "0.3.1.dev0",
"observed_pinned_flatlib_commit": "2618c348ce1ab2588548f935ff65f031630b4872",
"polars": "1.43.0",
"required_flatlib_source": "git+https://github.com/diliprk/flatlib.git@sidereal",
"timezonefinder": "8.2.4"
},
"engine": "VedicAstro",
"production_tuning_allowed": false,
"raw": {
"ayanamsa_identity": {
"mode": "Krishnamurti",
"source": "flatlib.ephem.swe.get_ayanamsa",
"value_degrees": 23.138843795
},
"houses": [
{
"DegSize": 25.952,
"HouseNr": 1,
"LonDecDeg": 149.152,
"Nakshatra": "UttaraPhalgunī",
"NakshatraLord": "Sun",
"Object": "I",
"Rasi": "Leo",
"RasiLord": "Sun",
"SignLonDMS": "+29:09:09",
"SignLonDecDeg": 29.152,
"SubLord": "Mars",
"SubSubLord": "Sun"
},
{
"DegSize": 30.11,
"HouseNr": 2,
"LonDecDeg": 175.104,
"Nakshatra": "Chitra",
"NakshatraLord": "Mars",
"Object": "II",
"Rasi": "Virgo",
"RasiLord": "Mercury",
"SignLonDMS": "+25:06:14",
"SignLonDecDeg": 25.104,
"SubLord": "Rahu",
"SubSubLord": "Mercury"
},
{
"DegSize": 32.962,
"HouseNr": 3,
"LonDecDeg": 205.214,
"Nakshatra": "Vishakha",
"NakshatraLord": "Jupiter",
"Object": "III",
"Rasi": "Libra",
"RasiLord": "Venus",
"SignLonDMS": "+25:12:52",
"SignLonDecDeg": 25.214,
"SubLord": "Mercury",
"SubSubLord": "Rahu"
},
{
"DegSize": 33.159,
"HouseNr": 4,
"LonDecDeg": 238.176,
"Nakshatra": "Jyeshtha",
"NakshatraLord": "Mercury",
"Object": "IV",
"Rasi": "Scorpio",
"RasiLord": "Mars",
"SignLonDMS": "+28:10:35",
"SignLonDecDeg": 28.176,
"SubLord": "Saturn",
"SubSubLord": "Saturn"
},
{
"DegSize": 30.735,
"HouseNr": 5,
"LonDecDeg": 271.335,
"Nakshatra": "UttaraAshadha",
"NakshatraLord": "Sun",
"Object": "V",
"Rasi": "Capricorn",
"RasiLord": "Saturn",
"SignLonDMS": "+01:20:06",
"SignLonDecDeg": 1.335,
"SubLord": "Jupiter",
"SubSubLord": "Jupiter"
},
{
"DegSize": 27.082,
"HouseNr": 6,
"LonDecDeg": 302.07,
"Nakshatra": "Dhanishta",
"NakshatraLord": "Mars",
"Object": "VI",
"Rasi": "Aquarius",
"RasiLord": "Saturn",
"SignLonDMS": "+02:04:13",
"SignLonDecDeg": 2.07,
"SubLord": "Ketu",
"SubSubLord": "Sun"
},
{
"DegSize": 25.952,
"HouseNr": 7,
"LonDecDeg": 329.152,
"Nakshatra": "PurvaBhādrapadā",
"NakshatraLord": "Jupiter",
"Object": "VII",
"Rasi": "Aquarius",
"RasiLord": "Saturn",
"SignLonDMS": "+29:09:09",
"SignLonDecDeg": 29.152,
"SubLord": "Sun",
"SubSubLord": "Saturn"
},
{
"DegSize": 30.11,
"HouseNr": 8,
"LonDecDeg": 355.104,
"Nakshatra": "Revati",
"NakshatraLord": "Mercury",
"Object": "VIII",
"Rasi": "Pisces",
"RasiLord": "Jupiter",
"SignLonDMS": "+25:06:14",
"SignLonDecDeg": 25.104,
"SubLord": "Rahu",
"SubSubLord": "Mercury"
},
{
"DegSize": 32.962,
"HouseNr": 9,
"LonDecDeg": 25.214,
"Nakshatra": "Bharani",
"NakshatraLord": "Venus",
"Object": "IX",
"Rasi": "Aries",
"RasiLord": "Mars",
"SignLonDMS": "+25:12:52",
"SignLonDecDeg": 25.214,
"SubLord": "Mercury",
"SubSubLord": "Rahu"
},
{
"DegSize": 33.159,
"HouseNr": 10,
"LonDecDeg": 58.176,
"Nakshatra": "Mrigashīrsha",
"NakshatraLord": "Mars",
"Object": "X",
"Rasi": "Taurus",
"RasiLord": "Venus",
"SignLonDMS": "+28:10:35",
"SignLonDecDeg": 28.176,
"SubLord": "Saturn",
"SubSubLord": "Saturn"
},
{
"DegSize": 30.735,
"HouseNr": 11,
"LonDecDeg": 91.335,
"Nakshatra": "Punarvasu",
"NakshatraLord": "Jupiter",
"Object": "XI",
"Rasi": "Cancer",
"RasiLord": "Moon",
"SignLonDMS": "+01:20:06",
"SignLonDecDeg": 1.335,
"SubLord": "Rahu",
"SubSubLord": "Rahu"
},
{
"DegSize": 27.082,
"HouseNr": 12,
"LonDecDeg": 122.07,
"Nakshatra": "Maghā",
"NakshatraLord": "Ketu",
"Object": "XII",
"Rasi": "Leo",
"RasiLord": "Sun",
"SignLonDMS": "+02:04:13",
"SignLonDecDeg": 2.07,
"SubLord": "Venus",
"SubSubLord": "Jupiter"
}
],
"request": {
"ayanamsa": "Krishnamurti",
"day": 24,
"hour": 19,
"house_system": "Placidus",
"latitude": 37.7749,
"longitude": -122.4194,
"minute": 15,
"month": 2,
"second": 0,
"timezone": "America/Los_Angeles",
"year": 1955
}
},
"raw_hash": "ac5ff43c253cf137648da0dfab495a7e90f975a23ccd04deee9e280dcf63981a",
"schema_fingerprint": {
"fields": [
"Object",
"HouseNr",
"Rasi",
"LonDecDeg",
"SignLonDMS",
"SignLonDecDeg",
"DegSize",
"Nakshatra",
"RasiLord",
"NakshatraLord",
"SubLord",
"SubSubLord"
],
"house_count": 12
},
"scope": "vedicastro_kp_house_cusp_probe",
"source_file": "references/open_source_sources/VedicAstro/vedicastro/VedicAstro.py",
"source_file_sha256": "1469c89a28dd4de6e576c2c4bd907902ee45d8a261b22836ea45503af369fa1d",
"status": "complete",
"truth_matrix_allowed": false
}
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
"""Compare fixed public/synthetic PyJHora Panchanga and Gulika observations."""
from __future__ import annotations
import contextlib
import hashlib
import io
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
from gulika import calculate_gulika
from muhurta import _swisseph_sun_moon_lon, calc_panchanga
CASES = (
{"case_id": "synthetic_beijing_1990", "date": (1990, 1, 1), "time": (12, 0, 0), "place": ("Beijing", 39.9042, 116.4074, 8.0)},
{"case_id": "public_smoke_chennai_1996", "date": (1996, 12, 7), "time": (10, 34, 0), "place": ("Chennai", 13.0878, 80.2785, 5.5)},
{"case_id": "synthetic_london_2000", "date": (2000, 6, 21), "time": (6, 30, 0), "place": ("London", 51.5074, -0.1278, 1.0)},
)
def _hash(value: Any) -> str:
return hashlib.sha256(json.dumps(value, sort_keys=True, default=str).encode()).hexdigest()
def build_report() -> dict[str, Any]:
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
from jhora import utils
from jhora.panchanga import drik
drik.set_ayanamsa_mode("LAHIRI")
rows = []
try:
for item in CASES:
y, m, d = item["date"]
hh, mm, ss = item["time"]
name, lat, lon, tz = item["place"]
dob, tob, place = drik.Date(y, m, d), (hh, mm, ss), drik.Place(name, lat, lon, tz)
local_jd = utils.julian_day_number(dob, tob)
raw = {
"gulika": drik.gulika_longitude(dob, tob, place),
"maandi": drik.maandi_longitude(dob, tob, place),
"tithi": drik.tithi(local_jd, place),
"nakshatra": drik.nakshatra(local_jd, place),
"yogam": drik.yogam(local_jd, place),
"karana": drik.karana(local_jd, place),
"raahu_kaalam": drik.raahu_kaalam(local_jd, place),
"yamaganda_kaalam": drik.yamaganda_kaalam(local_jd, place),
"durmuhurtam": drik.durmuhurtam(local_jd, place),
"abhijit_muhurta": drik.abhijit_muhurta(local_jd, place),
}
utc_jd = local_jd - tz / 24
sun_moon = _swisseph_sun_moon_lon(utc_jd, "lahiri")
local = calc_panchanga(*sun_moon, weekday=(datetime(y, m, d).weekday() + 1) % 7)
local_gulika = calculate_gulika(datetime(y, m, d, hh, mm, ss), lat=lat, lon=lon, tz=tz)
py_gulika_deg = raw["gulika"][0] * 30 + raw["gulika"][1]
field_comparison = {
"tithi": {"local": local["tithi"]["tithi_num"], "pyjhora": raw["tithi"][0], "status": "match" if local["tithi"]["tithi_num"] == raw["tithi"][0] else "mismatch"},
"nakshatra": {"local": local["nakshatra"]["nakshatra_idx"] + 1, "pyjhora": raw["nakshatra"][0], "status": "match" if local["nakshatra"]["nakshatra_idx"] + 1 == raw["nakshatra"][0] else "mismatch"},
"yogam": {"local": local["yoga"]["yoga_idx"] + 1, "pyjhora": raw["yogam"][0], "status": "match" if local["yoga"]["yoga_idx"] + 1 == raw["yogam"][0] else "mismatch"},
"gulika": {"local_degrees": local_gulika["longitude"], "pyjhora_degrees": py_gulika_deg, "delta_degrees": abs(((local_gulika["longitude"] - py_gulika_deg + 180) % 360) - 180), "status": "observed_formula_comparison"},
}
rows.append({"case_id": item["case_id"], "input": {"date": f"{y:04d}-{m:02d}-{d:02d}", "time": f"{hh:02d}:{mm:02d}:{ss:02d}", "place": name, "latitude": lat, "longitude": lon, "timezone": f"{tz:+03.1f}", "ayanamsa": "Lahiri"}, "pyjhora_raw": raw, "field_comparison": field_comparison, "raw_sha256": _hash(raw)})
finally:
drik.reset_ayanamsa_mode()
return {"scope": "pyjhora_multi_case_panchanga_gulika_replay", "claim_status": "observation_only", "consumer_policy": "research_observation_only", "production_tuning_allowed": False, "truth_matrix_allowed": False, "license_boundary": "agpl_observation_only_do_not_vendor", "cases": rows, "boundary": "Three fixed public/synthetic cases compare field observations only. Maandi and Muhurta windows remain raw observations; no automatic election, prediction, or truth upgrade is allowed."}
if __name__ == "__main__":
print(json.dumps(build_report(), ensure_ascii=False, indent=2, default=str))
@@ -0,0 +1,13 @@
from scripts.pyjhora_multi_case_panchanga_gulika_replay import build_report
def test_pyjhora_multi_case_replay_is_observation_only() -> None:
report = build_report()
assert report["claim_status"] == "observation_only"
assert report["production_tuning_allowed"] is False
assert report["truth_matrix_allowed"] is False
assert len(report["cases"]) == 3
for case in report["cases"]:
assert case["raw_sha256"]
assert set(case["pyjhora_raw"]) >= {"gulika", "maandi", "tithi", "nakshatra", "yogam", "karana"}
assert set(case["field_comparison"]) == {"tithi", "nakshatra", "yogam", "gulika"}