diff --git a/docs/research/pre_work_error_ledger.md b/docs/research/pre_work_error_ledger.md index 8ce219be..9f0235e3 100644 --- a/docs/research/pre_work_error_ledger.md +++ b/docs/research/pre_work_error_ledger.md @@ -84,6 +84,7 @@ For large architecture or release work, also read: | ERR-051 | Privacy redaction can replace executable numeric test fixtures with bare placeholder identifiers such as `REDACTED_YEAR`, causing `NameError` before a regression reaches its target. | observed 2026-07-12 | Public tests must use generic fixtures (for example 1990) or quoted placeholders only; run `rg -n "REDACTED_YEAR" tests` before release and repair executable occurrences. | | ERR-052 | Text-only privacy scanning cannot distinguish a harmless quoted placeholder from a bare Python identifier that will fail at runtime. | mitigated 2026-07-13 | `public_release_privacy_scan.py` parses shipped Python files and rejects executable `REDACTED_*` names; keep the AST regression test. | | ERR-053 | A parity manifest could label an external engine `official_verified` without a raw artifact, hash, or calculation settings, making claimed oracle closure unverifiable. | mitigated 2026-07-13 | `three_engine_parity_replay_validator.py` requires raw artifact existence, SHA-256 and settings for verified/imported external engines; otherwise parity is `invalid`. | +| ERR-054 | Candidate-time sensitivity scanning used the legacy `varga` CLI, so D4/D24/D30 could appear unavailable despite being supported by `varga-full`. | resolved 2026-07-13 | Scanner calls `varga-full --divisions D4,D9,D10,D24,D30` once per candidate and reads its canonical `Ascendant.sign` fields. | ## Fragment Sweep Command Set diff --git a/scripts/candidate_time_sensitivity_scan.py b/scripts/candidate_time_sensitivity_scan.py index 173017b7..295ed4b0 100644 --- a/scripts/candidate_time_sensitivity_scan.py +++ b/scripts/candidate_time_sensitivity_scan.py @@ -14,43 +14,31 @@ from typing import Any ROOT = Path(__file__).resolve().parents[1] ENGINE = ROOT / "scripts" / "jyotish_engine.py" -_VARGAS = ("d4", "d9", "d10", "d24", "d30") +_VARGAS = ("D4", "D9", "D10", "D24", "D30") def _engine_json(command: str, payload: dict[str, Any], *, timeout: int = 20) -> dict[str, Any]: args = ["python3", str(ENGINE), command] for key in ("year", "month", "day", "hour", "minute", "lat", "lon", "tz"): args.extend([f"--{key}", str(payload[key])]) - if command == "varga": - args.append(f"--{payload['varga']}") + if command == "varga-full": + args.extend(["--divisions", ",".join(_VARGAS)]) completed = subprocess.run(args, cwd=ROOT, capture_output=True, text=True, timeout=timeout, check=True) return json.loads(completed.stdout) -def _varga_ascendant(payload: dict[str, Any], varga: str) -> str | None: - try: - raw = _engine_json("varga", {**payload, "varga": varga}) - except subprocess.CalledProcessError: - return None - charts = raw.get("divisional_charts", {}) - for chart in charts.values(): - if isinstance(chart, dict): - return chart.get("ascendant") - return None - - def _all_varga_ascendants(payload: dict[str, Any]) -> dict[str, str | None]: - values = {varga.upper(): None for varga in _VARGAS} + values = {varga: None for varga in _VARGAS} try: - raw = _engine_json("varga", {**payload, "varga": "all"}) + raw = _engine_json("varga-full", payload) except subprocess.CalledProcessError: return values - for name, chart in (raw.get("divisional_charts") or {}).items(): + for name, chart in raw.items(): if not isinstance(chart, dict): continue for varga in _VARGAS: - if name.startswith(varga.upper() + "_"): - values[varga.upper()] = chart.get("ascendant") + if name.startswith(varga + "_"): + values[varga] = (chart.get("Ascendant") or {}).get("sign") return values diff --git a/tests/test_candidate_time_sensitivity_scan.py b/tests/test_candidate_time_sensitivity_scan.py index d6507c10..da8a0476 100644 --- a/tests/test_candidate_time_sensitivity_scan.py +++ b/tests/test_candidate_time_sensitivity_scan.py @@ -8,10 +8,11 @@ def test_scanner_reports_real_divisional_transitions(monkeypatch): return {"ascendant": {"sign": "Leo", "degree_in_sign": 10 + minute / 100}} ascendant = "Aries" if minute % 2 else "Taurus" return { - "divisional_charts": { - "D9_Navamsa": {"ascendant": ascendant}, - "D10_Dasamsa": {"ascendant": ascendant}, - } + "D4_Turyamsa": {"Ascendant": {"sign": ascendant}}, + "D9_Navamsa": {"Ascendant": {"sign": ascendant}}, + "D10_Dasamsa": {"Ascendant": {"sign": ascendant}}, + "D24_Siddhamsa": {"Ascendant": {"sign": ascendant}}, + "D30_Trimsamsa": {"Ascendant": {"sign": ascendant}}, } monkeypatch.setattr(scanner, "_engine_json", fake_engine)