Add external oracle sanity closure audit
This commit is contained in:
@@ -142,6 +142,14 @@ python3 scripts/oracle_boundary_audit.py \
|
||||
|
||||
该报告会明确标出 `production_tuning_recommended: false`:Dasha 当前只有单份 PDF 起点差异样本;VedAstro SDK 黄经样本已纳入 `longitude_cases`,当前用户盘最大差异约 26.23 角秒、D1/D9 落点一致,但这只能说明基础黄经接近;Shadbala 还缺 Sthana/Dig/Kala/Chesta/Naisargika/Drik 分量级外部目标值,因此不能声称 Dasha/Shadbala 已完成外部绝对值校准。
|
||||
|
||||
三方官方/外部 oracle sanity 总控命令:
|
||||
|
||||
```bash
|
||||
python3 scripts/external_oracle_sanity_closure.py --format markdown
|
||||
```
|
||||
|
||||
该报告同时检查 VedAstro official precision sanity、PyJHora black-box artifacts、jyotishganit MIT reference layer。默认命令为非阻塞 sanity,总控质量门可运行;需要真实触发 VedAstro official full snapshot 细算时,加 `--live-official-full-snapshot`。当前允许声明的是“高严谨带 blocked 行”:PyJHora 黑盒证据与 jyotishganit 参考层可审计;VedAstro 黄经 sanity 通过但 official full snapshot 细算仍需显式 live probe 且可能因前台预算或官方快照合同 blocked,不能声称三方 fully closed。
|
||||
|
||||
外部真值采集队列用于把缺失目标值拆成可执行任务,而不是直接调生产参数:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
{
|
||||
"scope": "external_official_sanity_oracle_closure",
|
||||
"schema_version": 1,
|
||||
"generated_at": "2026-07-01T12:03:22.602473+00:00",
|
||||
"summary": {
|
||||
"required_oracles": [
|
||||
"VedAstro",
|
||||
"PyJHora",
|
||||
"jyotishganit"
|
||||
],
|
||||
"ok_count": 2,
|
||||
"partial_count": 0,
|
||||
"blocked_count": 1,
|
||||
"ok_oracles": [
|
||||
"pyjhora",
|
||||
"jyotishganit"
|
||||
],
|
||||
"partial_oracles": [],
|
||||
"blocked_oracles": [
|
||||
"vedastro"
|
||||
],
|
||||
"external_verified_tasks": 12,
|
||||
"total_tasks": 12,
|
||||
"open_tasks": 0,
|
||||
"live_official_full_snapshot": false
|
||||
},
|
||||
"oracle_ledger": {
|
||||
"vedastro": {
|
||||
"name": "VedAstro",
|
||||
"role": "official_precision_sanity",
|
||||
"status": "blocked",
|
||||
"verdict": "official_longitude_sanity_passed_but_full_snapshot_blocked",
|
||||
"live_official_full_snapshot": false,
|
||||
"fine_calc_blocked": true,
|
||||
"longitude_case_count": 1,
|
||||
"longitude_cases_within_threshold": 1,
|
||||
"max_abs_delta_arcsec": 26.2254,
|
||||
"snapshot_status": "not_run_default_non_blocking",
|
||||
"official_chart_available": false,
|
||||
"official_python_bundle_status": "not_run_default_non_blocking",
|
||||
"evidence_paths": [
|
||||
"references/oracle/dasha_shadbala_oracle_cases.json",
|
||||
"scripts/oracle_boundary_audit.py",
|
||||
"scripts/vedastro_service_adapter.py"
|
||||
],
|
||||
"blocked_reason": "Official fine snapshot is not a stable ok chart, or only longitude sanity is currently closed."
|
||||
},
|
||||
"pyjhora": {
|
||||
"name": "PyJHora",
|
||||
"role": "black_box_external_oracle",
|
||||
"status": "ok",
|
||||
"verdict": "black_box_artifact_ledger_available",
|
||||
"artifact_count": 12,
|
||||
"packet_count": 8,
|
||||
"fronts": {
|
||||
"dasha": {
|
||||
"artifact_count": 3,
|
||||
"packet_count": 3,
|
||||
"artifacts": [
|
||||
"pyjhora_historical_epoch_dasha_stdout_20260627.txt",
|
||||
"pyjhora_steve_jobs_dasha_stdout_20260627.txt",
|
||||
"pyjhora_user_REDACTED_YEAR_dasha_stdout_20260627.txt"
|
||||
],
|
||||
"pending_packets": [
|
||||
"external_template_extreme_latitude_kp_pyjhora_20260627.json",
|
||||
"external_template_historical_epoch_lahiri_pyjhora_20260627.json",
|
||||
"external_template_steve_jobs_dasha_lahiri_pyjhora_20260627.json"
|
||||
]
|
||||
},
|
||||
"shadbala": {
|
||||
"artifact_count": 4,
|
||||
"packet_count": 4,
|
||||
"artifacts": [
|
||||
"pyjhora_extreme_latitude_kp_shadbala_stdout_20260627.txt",
|
||||
"pyjhora_redacted_place_shadbala_raman_stdout_20260627.txt",
|
||||
"pyjhora_steve_jobs_shadbala_lahiri_stdout_20260627.txt",
|
||||
"pyjhora_user_REDACTED_YEAR_shadbala_lahiri_stdout_20260627.txt"
|
||||
],
|
||||
"pending_packets": [
|
||||
"external_template_redacted_place_shadbala_raman_pyjhora_20260627.json",
|
||||
"external_template_steve_jobs_shadbala_lahiri_pyjhora_20260627.json",
|
||||
"external_template_user_REDACTED_YEAR_moon_longitude_lahiri_pyjhora_20260627.json",
|
||||
"external_template_user_REDACTED_YEAR_shadbala_lahiri_pyjhora_20260627.json"
|
||||
]
|
||||
},
|
||||
"tajika_sahams": {
|
||||
"artifact_count": 5,
|
||||
"packet_count": 1,
|
||||
"artifacts": [
|
||||
"pyjhora_einstein_varshaphala_1905_lahiri_partial_20260629.txt",
|
||||
"pyjhora_historical_dst_london_varshaphala_1943_lahiri_20260629.txt",
|
||||
"pyjhora_marilyn_monroe_varshaphala_1962_lahiri_20260629.txt",
|
||||
"pyjhora_steve_jobs_varshaphala_1984_lahiri_stdout_20260627.txt",
|
||||
"pyjhora_synthetic_extreme_latitude_varshaphala_kp_20260629.txt"
|
||||
],
|
||||
"pending_packets": [
|
||||
"external_template_steve_jobs_varshaphala_1984_lahiri_pyjhora_20260627.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
"license_boundary": "black_box_artifacts_only_no_agpl_code_import",
|
||||
"evidence_paths": [
|
||||
"references/oracle/artifacts/pyjhora_oracle_artifact_manifest.json"
|
||||
]
|
||||
},
|
||||
"jyotishganit": {
|
||||
"name": "jyotishganit",
|
||||
"role": "mit_reference_layer",
|
||||
"status": "ok",
|
||||
"verdict": "mit_reference_source_available",
|
||||
"license": "MIT",
|
||||
"source_available": true,
|
||||
"import_spec_available": true,
|
||||
"import_error": null,
|
||||
"benchmark_available": true,
|
||||
"evidence_paths": [
|
||||
"references/open_source_sources/jyotishganit",
|
||||
"references/jyotishganit_benchmark.md"
|
||||
],
|
||||
"boundary": "MIT reference layer and local comparison asset; not a complete second runtime oracle for every request."
|
||||
}
|
||||
},
|
||||
"master_oracle_dashboard": {
|
||||
"summary": {
|
||||
"total_tasks": 12,
|
||||
"external_verified_tasks": 12,
|
||||
"open_tasks": 0,
|
||||
"can_claim_global_oracle_closure": true,
|
||||
"production_tuning_allowed": false
|
||||
},
|
||||
"fronts": {
|
||||
"dasha": {
|
||||
"front": "dasha",
|
||||
"task_count": 3,
|
||||
"external_verified_tasks": 3,
|
||||
"open_tasks": 0,
|
||||
"can_claim_closure": true,
|
||||
"production_tuning_allowed": false,
|
||||
"first_priority": null
|
||||
},
|
||||
"shadbala": {
|
||||
"front": "shadbala",
|
||||
"task_count": 4,
|
||||
"external_verified_tasks": 4,
|
||||
"open_tasks": 0,
|
||||
"can_claim_closure": true,
|
||||
"production_tuning_allowed": false,
|
||||
"first_priority": null
|
||||
},
|
||||
"tajika_sahams": {
|
||||
"front": "tajika_sahams",
|
||||
"task_count": 5,
|
||||
"external_verified_tasks": 5,
|
||||
"open_tasks": 0,
|
||||
"can_claim_closure": true,
|
||||
"production_tuning_allowed": false,
|
||||
"first_priority": {
|
||||
"case_id": "template_einstein_varshaphala_1905_lahiri",
|
||||
"capture_id": "external_template_einstein_varshaphala_1905_lahiri",
|
||||
"packet_path": "references/oracle/artifacts/pending_packets/external_template_einstein_varshaphala_1905_lahiri.json",
|
||||
"missing_field_count": 0,
|
||||
"missing_fields": [],
|
||||
"missing_groups": {
|
||||
"metadata": {
|
||||
"count": 0,
|
||||
"fields": []
|
||||
},
|
||||
"target": {
|
||||
"count": 0,
|
||||
"fields": []
|
||||
}
|
||||
},
|
||||
"prefilled_fields": {
|
||||
"status": "external_verified",
|
||||
"promotion_status_after_fill": "external_verified",
|
||||
"metadata": {
|
||||
"tool_name": "PyJHora",
|
||||
"tool_version_or_url": "PyJHora 4.8.6 isolated workbuddy black-box run",
|
||||
"capture_date": "2026-06-29",
|
||||
"source_artifact": "references/oracle/artifacts/pyjhora_einstein_varshaphala_1905_lahiri_partial_20260629.txt",
|
||||
"ayanamsa": "lahiri",
|
||||
"node_mode": "mean",
|
||||
"timezone": "UTC+00:53",
|
||||
"annual_system": "Varshaphala/Tajika",
|
||||
"target_year": 1905,
|
||||
"operator_note": "Black-box annual output from workbuddy PyJHora 4.8.6 environment. External evidence only; local annual engine output was not used. Solar-return timestamp, Varsha Lagna, Muntha, Year Lord, first Mudda Dasha lord, selected Sahams, and Tajika Yogas were captured through the external PyJHora path via the annual chart and jhora.horoscope.transit.tajaka_yoga helper chain."
|
||||
},
|
||||
"settings": {
|
||||
"ayanamsa": "lahiri",
|
||||
"node_mode": "mean",
|
||||
"annual_system": "varshaphala",
|
||||
"target_year": 1905
|
||||
}
|
||||
},
|
||||
"manual_fill_plan": {
|
||||
"status_value": "external_verified",
|
||||
"manual_entry_count": 0,
|
||||
"remaining_manual_fields": []
|
||||
},
|
||||
"apply_command": "python3 scripts/tajika_annual_oracle_queue.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --apply-packet references/oracle/artifacts/pending_packets/external_template_einstein_varshaphala_1905_lahiri.json --format json",
|
||||
"validate_command": "python3 scripts/tajika_annual_oracle_queue.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --format json && python3 scripts/tajika_annual_benchmark_dashboard.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --format json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"honesty_boundary": {
|
||||
"can_claim_fully_closed": false,
|
||||
"can_claim_high_rigor_with_blocks": true,
|
||||
"blocked_reason": "At least one official precision/oracle layer is partial or blocked; report must expose blocked rows instead of claiming full closure.",
|
||||
"license_boundary": "PyJHora is black-box evidence only; jyotishganit MIT assets may be referenced/reused within existing project policy."
|
||||
},
|
||||
"next_actions": [
|
||||
"Run --live-official-full-snapshot when foreground VedAstro budget/network credentials are available, then promote VedAstro only if the full official chart is stable.",
|
||||
"Keep PyJHora as artifact-backed oracle evidence; do not import AGPL implementation code.",
|
||||
"If a report needs full closure language, require all oracle ledger rows to be ok and the master oracle dashboard open_tasks to be 0."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# External Official Sanity / Oracle Closure
|
||||
|
||||
Generated: `2026-07-01T12:03:21.916094+00:00`
|
||||
|
||||
## Summary
|
||||
|
||||
- ok_count: `2`
|
||||
- partial_count: `0`
|
||||
- blocked_count: `1`
|
||||
- total_tasks: `12`
|
||||
- external_verified_tasks: `12`
|
||||
- open_tasks: `0`
|
||||
|
||||
## Oracle Ledger
|
||||
|
||||
| oracle | status | role | verdict |
|
||||
|---|---|---|---|
|
||||
| `vedastro` | `blocked` | `official_precision_sanity` | `official_longitude_sanity_passed_but_full_snapshot_blocked` |
|
||||
| `pyjhora` | `ok` | `black_box_external_oracle` | `black_box_artifact_ledger_available` |
|
||||
| `jyotishganit` | `ok` | `mit_reference_layer` | `mit_reference_source_available` |
|
||||
|
||||
## Honesty Boundary
|
||||
|
||||
- can_claim_fully_closed: `false`
|
||||
- can_claim_high_rigor_with_blocks: `true`
|
||||
- blocked_reason: At least one official precision/oracle layer is partial or blocked; report must expose blocked rows instead of claiming full closure.
|
||||
|
||||
## Next Actions
|
||||
|
||||
- Run --live-official-full-snapshot when foreground VedAstro budget/network credentials are available, then promote VedAstro only if the full official chart is stable.
|
||||
- Keep PyJHora as artifact-backed oracle evidence; do not import AGPL implementation code.
|
||||
- If a report needs full closure language, require all oracle ledger rows to be ok and the master oracle dashboard open_tasks to be 0.
|
||||
@@ -708,3 +708,11 @@
|
||||
- `scripts/guided_topic_discovery.py` 已把 `official_day_signal_summary` 压进每条 guided topic;`jyotish-app/main.js` 的 guided topic 卡片会直接显示最重要的官方日期提示;`jyotish-app/ai-chat.js` 也会把这层塞进 guided topic chat payload,后续追问不再丢失。
|
||||
- 新增并跑通的定点回归:
|
||||
- `python3 -m pytest tests/test_mcp_strict_workflow_career.py::test_career_external_activation_derives_user_readable_day_signals tests/test_mcp_strict_workflow_relationship.py::test_relationship_external_activation_derives_progress_day_signals tests/test_mcp_strict_workflow_finance.py::test_finance_external_activation_derives_wealth_day_signals tests/test_cli_smoke.py::test_full_reading_guided_topics_can_carry_official_day_signal_summary tests/test_frontend_productization.py::test_guided_topic_questions_reuse_ai_chat_entry -q`
|
||||
|
||||
## 2026-07-01T19:40:00+08:00 - 外部官方细算 sanity / 三方 oracle 闭环账本
|
||||
|
||||
- 新增 `scripts/external_oracle_sanity_closure.py`:把 VedAstro official precision sanity、PyJHora black-box artifact ledger、jyotishganit MIT reference layer 统一成可审计 JSON/Markdown 账本。
|
||||
- 当前三方状态:PyJHora `ok`(12 artifacts / 8 packets)、jyotishganit `ok`(MIT source + benchmark available)、VedAstro `blocked`(longitude sanity 通过,但 official full snapshot 细算仍返回 `official_snapshot_budget_exhausted`,不能宣称 fully closed)。
|
||||
- 新增 `tests/test_external_oracle_sanity_closure.py`,并将 sanity closure 纳入 `scripts/run_quality_gate.py` 的 oracle audit 链路;README 增加总控命令。
|
||||
- 生成 `docs/benchmark/external_official_sanity_oracle_closure.{md,json}` 作为当前快照;诚实边界为 `can_claim_fully_closed=false`、`can_claim_high_rigor_with_blocks=true`。
|
||||
- 为避免质量门被 VedAstro 免费层节流长时间阻塞,sanity closure 默认只跑非阻塞官方证据审计;真实 official full snapshot 细算保留为显式 `--live-official-full-snapshot` 开关。
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Summarize VedAstro/PyJHora/jyotishganit sanity closure status.
|
||||
|
||||
This is an audit ledger, not a calculator. It cross-references existing
|
||||
external evidence and reports which parts are closed, partial, or blocked
|
||||
without importing PyJHora AGPL code or treating local consistency as truth.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import importlib.util
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
PYTHON = sys.executable
|
||||
DEFAULT_DASHA_ORACLE_FILE = "references/oracle/dasha_shadbala_oracle_cases.json"
|
||||
DEFAULT_TAJIKA_ORACLE_FILE = "references/oracle/tajika_annual_oracle_cases.json"
|
||||
JYOTISHGANIT_ROOT = ROOT / "references" / "open_source_sources" / "jyotishganit"
|
||||
|
||||
|
||||
def _run_json(command: list[str], *, timeout: int = 120) -> dict[str, Any]:
|
||||
completed = subprocess.run(
|
||||
command,
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=timeout,
|
||||
check=False,
|
||||
)
|
||||
if completed.returncode != 0:
|
||||
return {
|
||||
"status": "blocked",
|
||||
"command": command,
|
||||
"stderr": completed.stderr.strip(),
|
||||
"stdout_excerpt": completed.stdout.strip()[:500],
|
||||
}
|
||||
try:
|
||||
data = json.loads(completed.stdout)
|
||||
except json.JSONDecodeError as exc:
|
||||
return {
|
||||
"status": "blocked",
|
||||
"command": command,
|
||||
"reason": f"invalid_json: {exc}",
|
||||
"stdout_excerpt": completed.stdout.strip()[:500],
|
||||
}
|
||||
if isinstance(data, dict):
|
||||
return data
|
||||
return {"status": "blocked", "command": command, "reason": "json_root_not_object"}
|
||||
|
||||
|
||||
def _load_json(path: Path) -> dict[str, Any]:
|
||||
try:
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
except Exception as exc: # pragma: no cover - exact filesystem errors vary
|
||||
return {"status": "blocked", "reason": f"{type(exc).__name__}: {exc}"}
|
||||
return data if isinstance(data, dict) else {"status": "blocked", "reason": "json_root_not_object"}
|
||||
|
||||
|
||||
def _relative(path: Path) -> str:
|
||||
try:
|
||||
return str(path.relative_to(ROOT))
|
||||
except ValueError:
|
||||
return str(path)
|
||||
|
||||
|
||||
def _vedastro_ledger(oracle_file: str, *, live_official_full_snapshot: bool = False) -> dict[str, Any]:
|
||||
boundary = _run_json([PYTHON, "scripts/oracle_boundary_audit.py", "--oracle-file", oracle_file])
|
||||
longitude_cases = boundary.get("longitude_cases") if isinstance(boundary.get("longitude_cases"), list) else []
|
||||
within_threshold = [
|
||||
row for row in longitude_cases
|
||||
if isinstance(row, dict) and row.get("within_threshold") is True
|
||||
]
|
||||
max_delta = max(
|
||||
(float(row.get("max_abs_delta_arcsec", 0.0)) for row in longitude_cases if isinstance(row, dict)),
|
||||
default=None,
|
||||
)
|
||||
boundary_status = "ok" if longitude_cases and len(within_threshold) == len(longitude_cases) else "blocked"
|
||||
|
||||
if live_official_full_snapshot:
|
||||
snapshot = _run_json([
|
||||
PYTHON,
|
||||
"scripts/vedastro_service_adapter.py",
|
||||
"--official-full-snapshot",
|
||||
"--case",
|
||||
"user_REDACTED_YEAR_test",
|
||||
])
|
||||
else:
|
||||
snapshot = {
|
||||
"status": "not_run_default_non_blocking",
|
||||
"source_metadata": {
|
||||
"official_python_bundle": {
|
||||
"status": "not_run_default_non_blocking",
|
||||
},
|
||||
},
|
||||
"official_chart": {},
|
||||
}
|
||||
snapshot_status = str(snapshot.get("status") or "blocked")
|
||||
source_metadata = snapshot.get("source_metadata") if isinstance(snapshot.get("source_metadata"), dict) else {}
|
||||
official_bundle = source_metadata.get("official_python_bundle") if isinstance(source_metadata.get("official_python_bundle"), dict) else {}
|
||||
official_chart = snapshot.get("official_chart") if isinstance(snapshot.get("official_chart"), dict) else {}
|
||||
official_chart_available = bool(
|
||||
isinstance(official_chart.get("planets"), dict)
|
||||
and official_chart.get("planets")
|
||||
and isinstance(official_chart.get("ascendant"), dict)
|
||||
and official_chart.get("ascendant")
|
||||
)
|
||||
|
||||
fine_status_ok = snapshot_status in {"ok", "partial"} and official_chart_available
|
||||
if fine_status_ok and boundary_status == "ok":
|
||||
status = "ok"
|
||||
verdict = "official_precision_sanity_passed"
|
||||
else:
|
||||
status = "blocked"
|
||||
verdict = (
|
||||
"official_longitude_sanity_passed_but_full_snapshot_blocked"
|
||||
if boundary_status == "ok"
|
||||
else "official_precision_sanity_blocked"
|
||||
)
|
||||
|
||||
return {
|
||||
"name": "VedAstro",
|
||||
"role": "official_precision_sanity",
|
||||
"status": status,
|
||||
"verdict": verdict,
|
||||
"live_official_full_snapshot": live_official_full_snapshot,
|
||||
"fine_calc_blocked": status != "ok",
|
||||
"longitude_case_count": len(longitude_cases),
|
||||
"longitude_cases_within_threshold": len(within_threshold),
|
||||
"max_abs_delta_arcsec": max_delta,
|
||||
"snapshot_status": snapshot_status,
|
||||
"official_chart_available": official_chart_available,
|
||||
"official_python_bundle_status": official_bundle.get("status"),
|
||||
"evidence_paths": [
|
||||
"references/oracle/dasha_shadbala_oracle_cases.json",
|
||||
"scripts/oracle_boundary_audit.py",
|
||||
"scripts/vedastro_service_adapter.py",
|
||||
],
|
||||
"blocked_reason": None if status == "ok" else (
|
||||
"Official fine snapshot is not a stable ok chart, or only longitude sanity is currently closed."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def _pyjhora_ledger() -> dict[str, Any]:
|
||||
manifest_path = ROOT / "references" / "oracle" / "artifacts" / "pyjhora_oracle_artifact_manifest.json"
|
||||
manifest = _load_json(manifest_path)
|
||||
artifact_count = int(manifest.get("artifact_count") or 0)
|
||||
packet_count = int(manifest.get("packet_count") or 0)
|
||||
fronts = manifest.get("fronts") if isinstance(manifest.get("fronts"), dict) else {}
|
||||
status = "ok" if artifact_count >= 8 and packet_count >= 8 else "partial" if artifact_count else "blocked"
|
||||
return {
|
||||
"name": "PyJHora",
|
||||
"role": "black_box_external_oracle",
|
||||
"status": status,
|
||||
"verdict": "black_box_artifact_ledger_available" if status != "blocked" else "black_box_artifact_ledger_missing",
|
||||
"artifact_count": artifact_count,
|
||||
"packet_count": packet_count,
|
||||
"fronts": fronts,
|
||||
"license_boundary": "black_box_artifacts_only_no_agpl_code_import",
|
||||
"evidence_paths": [_relative(manifest_path)],
|
||||
}
|
||||
|
||||
|
||||
def _jyotishganit_ledger() -> dict[str, Any]:
|
||||
package_init = JYOTISHGANIT_ROOT / "jyotishganit" / "__init__.py"
|
||||
license_path = JYOTISHGANIT_ROOT / "LICENSE"
|
||||
source_available = package_init.is_file()
|
||||
license_text = ""
|
||||
if license_path.is_file():
|
||||
license_text = license_path.read_text(encoding="utf-8", errors="ignore")[:2000].lower()
|
||||
license_name = "MIT" if "mit license" in license_text or "permission is hereby granted" in license_text else "unknown"
|
||||
|
||||
importable = False
|
||||
import_error = None
|
||||
if source_available:
|
||||
spec = importlib.util.spec_from_file_location("jyotishganit", package_init)
|
||||
importable = spec is not None
|
||||
if not importable:
|
||||
import_error = "cannot_build_import_spec"
|
||||
|
||||
benchmark_path = ROOT / "references" / "jyotishganit_benchmark.md"
|
||||
status = "ok" if source_available and license_name == "MIT" and benchmark_path.is_file() else "partial" if source_available else "blocked"
|
||||
return {
|
||||
"name": "jyotishganit",
|
||||
"role": "mit_reference_layer",
|
||||
"status": status,
|
||||
"verdict": "mit_reference_source_available" if status != "blocked" else "mit_reference_source_missing",
|
||||
"license": license_name,
|
||||
"source_available": source_available,
|
||||
"import_spec_available": importable,
|
||||
"import_error": import_error,
|
||||
"benchmark_available": benchmark_path.is_file(),
|
||||
"evidence_paths": [
|
||||
_relative(JYOTISHGANIT_ROOT),
|
||||
_relative(benchmark_path),
|
||||
],
|
||||
"boundary": "MIT reference layer and local comparison asset; not a complete second runtime oracle for every request.",
|
||||
}
|
||||
|
||||
|
||||
def _oracle_master(dasha_oracle_file: str, tajika_oracle_file: str) -> dict[str, Any]:
|
||||
return _run_json([
|
||||
PYTHON,
|
||||
"scripts/oracle_closure_master_dashboard.py",
|
||||
"--dasha-oracle-file",
|
||||
dasha_oracle_file,
|
||||
"--tajika-oracle-file",
|
||||
tajika_oracle_file,
|
||||
"--format",
|
||||
"json",
|
||||
])
|
||||
|
||||
|
||||
def build_report(
|
||||
dasha_oracle_file: str,
|
||||
tajika_oracle_file: str,
|
||||
*,
|
||||
live_official_full_snapshot: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
vedastro = _vedastro_ledger(
|
||||
dasha_oracle_file,
|
||||
live_official_full_snapshot=live_official_full_snapshot,
|
||||
)
|
||||
pyjhora = _pyjhora_ledger()
|
||||
jyotishganit = _jyotishganit_ledger()
|
||||
master = _oracle_master(dasha_oracle_file, tajika_oracle_file)
|
||||
|
||||
ledgers = {
|
||||
"vedastro": vedastro,
|
||||
"pyjhora": pyjhora,
|
||||
"jyotishganit": jyotishganit,
|
||||
}
|
||||
blocked = [key for key, value in ledgers.items() if value.get("status") == "blocked"]
|
||||
partial = [key for key, value in ledgers.items() if value.get("status") == "partial"]
|
||||
ok = [key for key, value in ledgers.items() if value.get("status") == "ok"]
|
||||
can_claim_fully_closed = not blocked and not partial and master.get("summary", {}).get("can_claim_global_oracle_closure") is True
|
||||
|
||||
return {
|
||||
"scope": "external_official_sanity_oracle_closure",
|
||||
"schema_version": 1,
|
||||
"generated_at": datetime.now(timezone.utc).isoformat(),
|
||||
"summary": {
|
||||
"required_oracles": ["VedAstro", "PyJHora", "jyotishganit"],
|
||||
"ok_count": len(ok),
|
||||
"partial_count": len(partial),
|
||||
"blocked_count": len(blocked),
|
||||
"ok_oracles": ok,
|
||||
"partial_oracles": partial,
|
||||
"blocked_oracles": blocked,
|
||||
"external_verified_tasks": master.get("summary", {}).get("external_verified_tasks"),
|
||||
"total_tasks": master.get("summary", {}).get("total_tasks"),
|
||||
"open_tasks": master.get("summary", {}).get("open_tasks"),
|
||||
"live_official_full_snapshot": live_official_full_snapshot,
|
||||
},
|
||||
"oracle_ledger": ledgers,
|
||||
"master_oracle_dashboard": {
|
||||
"summary": master.get("summary", {}),
|
||||
"fronts": master.get("fronts", {}),
|
||||
},
|
||||
"honesty_boundary": {
|
||||
"can_claim_fully_closed": can_claim_fully_closed,
|
||||
"can_claim_high_rigor_with_blocks": bool(pyjhora.get("status") in {"ok", "partial"} and jyotishganit.get("status") in {"ok", "partial"}),
|
||||
"blocked_reason": (
|
||||
None if can_claim_fully_closed else
|
||||
"At least one official precision/oracle layer is partial or blocked; report must expose blocked rows instead of claiming full closure."
|
||||
),
|
||||
"license_boundary": "PyJHora is black-box evidence only; jyotishganit MIT assets may be referenced/reused within existing project policy.",
|
||||
},
|
||||
"next_actions": [
|
||||
"Run --live-official-full-snapshot when foreground VedAstro budget/network credentials are available, then promote VedAstro only if the full official chart is stable.",
|
||||
"Keep PyJHora as artifact-backed oracle evidence; do not import AGPL implementation code.",
|
||||
"If a report needs full closure language, require all oracle ledger rows to be ok and the master oracle dashboard open_tasks to be 0.",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def render_markdown(report: dict[str, Any]) -> str:
|
||||
summary = report["summary"]
|
||||
lines = [
|
||||
"# External Official Sanity / Oracle Closure",
|
||||
"",
|
||||
f"Generated: `{report['generated_at']}`",
|
||||
"",
|
||||
"## Summary",
|
||||
"",
|
||||
f"- ok_count: `{summary['ok_count']}`",
|
||||
f"- partial_count: `{summary['partial_count']}`",
|
||||
f"- blocked_count: `{summary['blocked_count']}`",
|
||||
f"- total_tasks: `{summary.get('total_tasks')}`",
|
||||
f"- external_verified_tasks: `{summary.get('external_verified_tasks')}`",
|
||||
f"- open_tasks: `{summary.get('open_tasks')}`",
|
||||
"",
|
||||
"## Oracle Ledger",
|
||||
"",
|
||||
"| oracle | status | role | verdict |",
|
||||
"|---|---|---|---|",
|
||||
]
|
||||
for key, row in report["oracle_ledger"].items():
|
||||
lines.append(f"| `{key}` | `{row.get('status')}` | `{row.get('role')}` | `{row.get('verdict')}` |")
|
||||
lines.extend([
|
||||
"",
|
||||
"## Honesty Boundary",
|
||||
"",
|
||||
f"- can_claim_fully_closed: `{str(report['honesty_boundary']['can_claim_fully_closed']).lower()}`",
|
||||
f"- can_claim_high_rigor_with_blocks: `{str(report['honesty_boundary']['can_claim_high_rigor_with_blocks']).lower()}`",
|
||||
f"- blocked_reason: {report['honesty_boundary']['blocked_reason']}",
|
||||
"",
|
||||
"## Next Actions",
|
||||
"",
|
||||
])
|
||||
lines.extend(f"- {item}" for item in report["next_actions"])
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Audit VedAstro/PyJHora/jyotishganit sanity closure")
|
||||
parser.add_argument("--dasha-oracle-file", default=DEFAULT_DASHA_ORACLE_FILE)
|
||||
parser.add_argument("--tajika-oracle-file", default=DEFAULT_TAJIKA_ORACLE_FILE)
|
||||
parser.add_argument(
|
||||
"--live-official-full-snapshot",
|
||||
action="store_true",
|
||||
help="Run the heavy VedAstro official full snapshot probe; default stays non-blocking for CI.",
|
||||
)
|
||||
parser.add_argument("--format", choices=["json", "markdown"], default="json")
|
||||
parser.add_argument("--output")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
args = parse_args(argv)
|
||||
report = build_report(
|
||||
args.dasha_oracle_file,
|
||||
args.tajika_oracle_file,
|
||||
live_official_full_snapshot=args.live_official_full_snapshot,
|
||||
)
|
||||
text = json.dumps(report, ensure_ascii=False, indent=2) if args.format == "json" else render_markdown(report)
|
||||
if args.output:
|
||||
output = Path(args.output)
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
output.write_text(text, encoding="utf-8")
|
||||
print(text)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -29,6 +29,7 @@ EXTRA_COMPILE_TARGETS = [
|
||||
ROOT / "mcp_server.py",
|
||||
ROOT / "scripts" / "audit_fragments.py",
|
||||
ROOT / "scripts" / "dasha_reference_audit.py",
|
||||
ROOT / "scripts" / "external_oracle_sanity_closure.py",
|
||||
ROOT / "scripts" / "oracle_boundary_audit.py",
|
||||
ROOT / "scripts" / "oracle_collection_queue.py",
|
||||
ROOT / "scripts" / "oracle_evidence_validator.py",
|
||||
@@ -47,6 +48,7 @@ CORE_PYTEST_TARGETS = [
|
||||
"tests/test_transit_trigger.py",
|
||||
"tests/test_oracle_collection_queue.py",
|
||||
"tests/test_oracle_evidence_validator.py",
|
||||
"tests/test_external_oracle_sanity_closure.py",
|
||||
]
|
||||
|
||||
RELEASE_CRITICAL_UNTRACKED_PATHS = [
|
||||
@@ -192,6 +194,13 @@ ORACLE_BOUNDARY_AUDIT_CMD = [
|
||||
"references/oracle/dasha_shadbala_oracle_cases.json",
|
||||
]
|
||||
|
||||
EXTERNAL_ORACLE_SANITY_CLOSURE_CMD = [
|
||||
PYTHON,
|
||||
"scripts/external_oracle_sanity_closure.py",
|
||||
"--format",
|
||||
"json",
|
||||
]
|
||||
|
||||
ORACLE_COLLECTION_QUEUE_CMD = [
|
||||
PYTHON,
|
||||
"scripts/oracle_collection_queue.py",
|
||||
@@ -497,6 +506,7 @@ def main() -> int:
|
||||
run(DASHA_REFERENCE_AUDIT_CMD)
|
||||
if not profile["skip_oracle_audit"]:
|
||||
run(ORACLE_BOUNDARY_AUDIT_CMD)
|
||||
run(EXTERNAL_ORACLE_SANITY_CLOSURE_CMD)
|
||||
run_oracle_collection_queue_and_validator()
|
||||
if not profile["skip_yoga_logic"]:
|
||||
run([PYTHON, "scripts/validate_logic_v2.py"], optional=True)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def _run_closure(*args: str) -> dict:
|
||||
completed = subprocess.run(
|
||||
[sys.executable, "scripts/external_oracle_sanity_closure.py", *args],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=180,
|
||||
check=False,
|
||||
)
|
||||
assert completed.returncode == 0, completed.stderr or completed.stdout
|
||||
return json.loads(completed.stdout)
|
||||
|
||||
|
||||
def test_external_official_sanity_closure_reports_all_three_oracles() -> None:
|
||||
report = _run_closure("--format", "json")
|
||||
|
||||
assert report["scope"] == "external_official_sanity_oracle_closure"
|
||||
assert report["summary"]["required_oracles"] == ["VedAstro", "PyJHora", "jyotishganit"]
|
||||
assert report["summary"]["live_official_full_snapshot"] is False
|
||||
assert set(report["oracle_ledger"]) == {"vedastro", "pyjhora", "jyotishganit"}
|
||||
|
||||
vedastro = report["oracle_ledger"]["vedastro"]
|
||||
assert vedastro["role"] == "official_precision_sanity"
|
||||
assert "status" in vedastro
|
||||
assert "verdict" in vedastro
|
||||
assert vedastro["live_official_full_snapshot"] is False
|
||||
assert vedastro["snapshot_status"] == "not_run_default_non_blocking"
|
||||
assert "fine_calc_blocked" in vedastro
|
||||
|
||||
pyjhora = report["oracle_ledger"]["pyjhora"]
|
||||
assert pyjhora["role"] == "black_box_external_oracle"
|
||||
assert pyjhora["artifact_count"] >= 8
|
||||
assert pyjhora["packet_count"] >= 8
|
||||
assert pyjhora["license_boundary"] == "black_box_artifacts_only_no_agpl_code_import"
|
||||
|
||||
jyotishganit = report["oracle_ledger"]["jyotishganit"]
|
||||
assert jyotishganit["role"] == "mit_reference_layer"
|
||||
assert jyotishganit["license"] == "MIT"
|
||||
assert jyotishganit["status"] in {"ok", "partial", "blocked"}
|
||||
|
||||
assert report["honesty_boundary"]["can_claim_fully_closed"] is False
|
||||
assert report["honesty_boundary"]["can_claim_high_rigor_with_blocks"] is True
|
||||
|
||||
|
||||
def test_external_official_sanity_closure_marks_live_vedastro_blocked_when_sanity_fails() -> None:
|
||||
report = _run_closure("--format", "json")
|
||||
vedastro = report["oracle_ledger"]["vedastro"]
|
||||
|
||||
if vedastro["status"] == "ok":
|
||||
assert vedastro["fine_calc_blocked"] is False
|
||||
else:
|
||||
assert vedastro["fine_calc_blocked"] is True
|
||||
assert report["summary"]["blocked_count"] >= 1
|
||||
|
||||
|
||||
def test_external_official_sanity_closure_documents_live_snapshot_flag() -> None:
|
||||
completed = subprocess.run(
|
||||
[sys.executable, "scripts/external_oracle_sanity_closure.py", "--help"],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
timeout=30,
|
||||
check=False,
|
||||
)
|
||||
|
||||
assert completed.returncode == 0
|
||||
assert "--live-official-full-snapshot" in completed.stdout
|
||||
Reference in New Issue
Block a user