feat: sync real case website e2e contract

This commit is contained in:
732642856
2026-07-20 13:55:54 +08:00
parent e47aedcc50
commit a509e27ec9
11 changed files with 1228 additions and 2 deletions
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""Create CI-safe capture packets for Muhurta numeric source candidates."""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
TRIAGE = ROOT / "references/oracle/public_worked_example_source_triage_2026_07_20.json"
OUT = ROOT / "references/oracle/muhurta_numeric_candidate_capture_packet_2026_07_20.json"
def sha(obj: Any) -> str:
return hashlib.sha256(json.dumps(obj, ensure_ascii=False, sort_keys=True).encode("utf-8")).hexdigest()
def next_path(source_id: str) -> str:
return f"references/oracle/artifacts/{source_id}_raw_capture_packet.json"
def build(date: str) -> dict[str, Any]:
triage = json.loads(TRIAGE.read_text(encoding="utf-8"))
rows = []
for src in triage["sources"]:
if src["domain"] != "muhurta_factor_scoring" or not src["numeric_fields_present"]:
continue
request = {
"source_id": src["source_id"],
"url": src["url"],
"topic": src["topic"],
"observed_numeric_fields": src["observed_numeric_fields"],
}
missing = list(src["missing_for_oracle"])
for field in ["raw_capture_hash", "exact_method_settings", "replay_comparison"]:
if field not in missing:
missing.append(field)
rows.append(
{
"source_id": src["source_id"],
"domain": src["domain"],
"topic": src["topic"],
"url": src["url"],
"source_observation_hash": src["observation_hash"],
"canonical_request_hash": sha(request),
"observed_numeric_fields": src["observed_numeric_fields"],
"raw_capture_status": "pending_raw_page_capture",
"upgrade_status": "not_oracle_ready",
"missing_for_oracle": missing,
"next_artifact_path": next_path(src["source_id"]),
"claim_boundary": "Numeric-looking public source; not oracle-ready until raw page, exact settings, hash, and local replay comparison are archived.",
}
)
return {
"scope": "muhurta_numeric_candidate_capture_packet",
"created_at": date,
"status": "capture_packet_ready",
"claim_status": "source_intake_only",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"sources": {"source_triage": str(TRIAGE.relative_to(ROOT))},
"summary": {
"candidate_count": len(rows),
"oracle_ready_count": 0,
"pending_raw_capture_count": sum(1 for row in rows if row["raw_capture_status"] == "pending_raw_page_capture"),
},
"capture_rows": rows,
"boundary": "Capture packet staging only; does not calculate or validate Muhurta verdicts.",
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--date", default="2026-07-20")
args = parser.parse_args()
print(json.dumps(build(args.date), ensure_ascii=False, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Create Prashna input contract and numeric oracle candidate queue."""
from __future__ import annotations
import argparse, hashlib, json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
CONTRACT = ROOT / "references/oracle/prashna_input_contract_2026_07_20.json"
QUEUE = ROOT / "references/oracle/prashna_numeric_oracle_packet_queue_2026_07_20.json"
def h(obj):
return hashlib.sha256(json.dumps(obj, ensure_ascii=False, sort_keys=True).encode()).hexdigest()
def build(date: str):
contract = {
"scope": "prashna_input_contract",
"created_at": date,
"status": "contract_ready",
"claim_status": "ready_contract",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"required_fields": [
{"field": "question_datetime_local", "format": "YYYY-MM-DDTHH:MM:SS", "boundary": "exact time question is received/accepted"},
{"field": "location", "format": "lat/lon + place label", "boundary": "place of querent/astrologer must be explicit"},
{"field": "timezone", "format": "IANA or UTC offset", "boundary": "no implicit local machine timezone"},
{"field": "ayanamsa", "format": "named sidereal ayanamsa", "boundary": "default must be recorded, e.g. Lahiri"},
{"field": "node_mode", "format": "mean|true", "boundary": "Rahu/Ketu mode must be frozen"},
],
"optional_fields": ["question_text", "querent_id", "house_focus", "language"],
"claim_boundary": "Input contract only; does not validate Prashna predictions or external numeric parity.",
}
rows = [
{
"source_id": "vedastro_prasna_marga_ch5_sphuta_example",
"domain": "horary_annual_sensitive_points",
"technique_family": "sphuta_trisphuta_family",
"url": "https://vedastro.org/book/PrasnaMarga/Chapter5",
"source_role": "public_numeric_candidate",
"numeric_fields_present": True,
"expected_values": {
"sun": "4s 3° 8' 25\"",
"moon": "3s 19° 36' 34\"",
"lagna": "3s 27° 22'",
"gulika": "3s 14° 10'",
"rahu": "3s 8° 16'",
"trisphuta": "11s 1° 8' 34\"",
"chatusphuta": "2s 15° 18' 34\"",
"panchasphuta": "5s 23° 34' 34\"",
},
"missing_for_oracle": ["complete_prashna_input", "ayanamsa", "node_mode", "timezone", "raw_capture_hash", "local_replay", "pyjhora_or_other_legal_replay"],
"upgrade_status": "candidate_not_oracle",
"candidate_hash": "",
"claim_boundary": "Numeric Sphuta example exists, but full Prashna input/settings are incomplete; use as candidate only.",
}
]
for row in rows:
row["candidate_hash"] = h(row)
queue = {
"scope": "prashna_numeric_oracle_packet_queue",
"created_at": date,
"status": "queue_ready",
"claim_status": "open_queue",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"summary": {"candidate_count": len(rows), "numeric_candidate_count": sum(r["numeric_fields_present"] for r in rows), "oracle_ready_count": 0},
"rows": rows,
"boundary": "Queue only; no Prashna/Saham/Gulika/Sphuta claim is upgraded until complete input, raw/hash and local/external replay close.",
}
return {"contract": contract, "queue": queue}
def main():
ap=argparse.ArgumentParser(); ap.add_argument("--date", default="2026-07-20"); args=ap.parse_args()
data=build(args.date)
CONTRACT.write_text(json.dumps(data["contract"], ensure_ascii=False, indent=2, sort_keys=True)+"\n")
QUEUE.write_text(json.dumps(data["queue"], ensure_ascii=False, indent=2, sort_keys=True)+"\n")
print(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True))
if __name__ == "__main__": main()
+100
View File
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Build a public-real-case website E2E evaluation contract."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
CASES = [
("steve_jobs", "Steve Jobs", "1955-02-24", "19:15", "San Francisco, CA, USA", ["career", "wealth", "timing"]),
("albert_einstein", "Albert Einstein", "1879-03-14", "11:30", "Ulm, Germany", ["education", "career", "timing"]),
("barack_obama", "Barack Obama", "1961-08-04", "19:24", "Honolulu, HI, USA", ["career", "migration", "annual"]),
("princess_diana", "Princess Diana", "1961-07-01", "19:45", "Sandringham, England", ["marriage", "family", "timing"]),
("donald_trump", "Donald Trump", "1946-06-14", "10:54", "Queens, NY, USA", ["career", "wealth", "annual"]),
("oprah_winfrey", "Oprah Winfrey", "1954-01-29", "04:30", "Kosciusko, MS, USA", ["career", "wealth", "family"]),
("elon_musk", "Elon Musk", "1971-06-28", "07:30", "Pretoria, South Africa", ["career", "migration", "wealth"]),
("mahatma_gandhi", "Mahatma Gandhi", "1869-10-02", "07:11", "Porbandar, India", ["career", "migration", "timing"]),
("marilyn_monroe", "Marilyn Monroe", "1926-06-01", "09:30", "Los Angeles, CA, USA", ["marriage", "career", "health"]),
("bill_gates", "Bill Gates", "1955-10-28", "22:00", "Seattle, WA, USA", ["career", "wealth", "education"]),
("j_k_rowling", "J. K. Rowling", "1965-07-31", "14:00", "Yate, England", ["career", "wealth", "timing"]),
("nelson_mandela", "Nelson Mandela", "1918-07-18", "14:54", "Mvezo, South Africa", ["career", "timing", "migration"]),
("mother_teresa", "Mother Teresa", "1910-08-26", "14:25", "Skopje, North Macedonia", ["career", "migration", "health"]),
("michael_jackson", "Michael Jackson", "1958-08-29", "19:33", "Gary, IN, USA", ["career", "wealth", "health"]),
("queen_elizabeth_ii", "Queen Elizabeth II", "1926-04-21", "02:40", "London, England", ["career", "family", "annual"]),
("john_f_kennedy", "John F. Kennedy", "1917-05-29", "15:00", "Brookline, MA, USA", ["career", "family", "health"]),
("martin_luther_king_jr", "Martin Luther King Jr.", "1929-01-15", "12:00", "Atlanta, GA, USA", ["career", "timing", "health"]),
("angelina_jolie", "Angelina Jolie", "1975-06-04", "09:09", "Los Angeles, CA, USA", ["marriage", "family", "career"]),
("brad_pitt", "Brad Pitt", "1963-12-18", "06:31", "Shawnee, OK, USA", ["marriage", "career", "wealth"]),
("serena_williams", "Serena Williams", "1981-09-26", "20:28", "Saginaw, MI, USA", ["career", "health", "annual"]),
]
QUESTION_MATRIX = {
"career": ["事业主轴是什么?", "哪类阶段更容易爆发?"],
"wealth": ["财富来源和风险是什么?"],
"marriage": ["婚恋关系中应看哪些印度占星指标?"],
"health": ["健康主题只能如何非医疗表达?"],
"migration": ["迁移/海外发展应看哪些宫位和 Dasha?"],
"family": ["家庭/子女主题应调用哪些分盘和宫位?"],
"education": ["学习与教育路径怎么看?"],
"timing": ["历史关键阶段能否用 Dasha + Narayana 回看?"],
"annual": ["年度运势应如何避免过度承诺?"],
}
def build(date: str) -> dict[str, Any]:
cases = []
for case_id, subject, date_s, time_s, place, domains in CASES:
cases.append(
{
"case_id": case_id,
"subject": subject,
"birth": {"date": date_s, "time": time_s, "place": place, "source_policy": "public_record_candidate"},
"domains": domains,
"prompts": [q for d in domains for q in QUESTION_MATRIX[d]],
"expected_runtime_context": [
"birth_input_contract",
"ayanamsa_node_mode",
"D1",
"D9_or_relevant_varga",
"Dasha",
"Narayana_Dasha_for_timing",
"functional_benefic_malefic",
"claim_boundary",
"similar_case_reference_allowed",
],
}
)
return {
"scope": "real_case_website_e2e_eval",
"created_at": date,
"claim_status": "ready_contract",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"case_count": len(cases),
"cases": cases,
"acceptance_rules": [
"Website must save/render input contract and runtime context JSON for each prompt.",
"Answers may use public cases as explanation references, not prediction proof.",
"Precise day/month claims must stay exploratory_unvalidated unless holdout closes.",
"Marriage/career/wealth/health/migration/family/education/timing/annual domains must route to matching technique context.",
"Any Shadbala/AV/KP conflict must be described as method/source difference, not majority-vote truth.",
],
"boundary": "Product E2E quality harness only; not an accuracy benchmark or independent holdout.",
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--date", default="2026-07-20")
args = parser.parse_args()
print(json.dumps(build(args.date), ensure_ascii=False, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())