require auditable external parity artifacts
This commit is contained in:
@@ -83,6 +83,7 @@ For large architecture or release work, also read:
|
||||
| ERR-050 | Prashna CLI/API/UI could synthesize or accept a non-question chart; legacy Tajika/Saham/Sphuta/Kunda paths also exposed approximate values as usable evidence. | mitigated 2026-07-12 | Require backend Swiss `PrashnaContext` with question text/time/location/timezone; reject client planets/ascendant. Block legacy Sphuta/Kunda/Gulika/Panchavargiya and no-location Saham paths; keep seven-planet Tajika interactions partial until named-yoga golden cases and formula parity exist. |
|
||||
| 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`. |
|
||||
|
||||
## Fragment Sweep Command Set
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@@ -12,6 +13,33 @@ from typing import Any
|
||||
REQUIRED_ENGINES = {"VedAstro", "PyJHora_JHora", "jyotishganit"}
|
||||
REQUIRED_ROW_FIELDS = {"section", "field", "local_value", "oracle_values", "status"}
|
||||
VALID_ROW_STATUSES = {"match", "mismatch", "blocked", "not_comparable"}
|
||||
RAW_VERIFIED_STATUSES = {"verified", "official_verified", "imported"}
|
||||
|
||||
|
||||
def _artifact_errors(engine: str, payload: Any, manifest_dir: Path) -> list[dict[str, Any]]:
|
||||
if not isinstance(payload, dict):
|
||||
return [{"field": f"engines.{engine}", "error": "not_object"}]
|
||||
if payload.get("status") not in RAW_VERIFIED_STATUSES:
|
||||
return []
|
||||
raw_path = payload.get("official_raw_response_path") or payload.get("raw_output_path")
|
||||
artifact_hash = payload.get("artifact_hash")
|
||||
errors: list[dict[str, Any]] = []
|
||||
if not isinstance(raw_path, str) or not raw_path:
|
||||
errors.append({"field": f"engines.{engine}.raw_output_path", "error": "required_for_verified_status"})
|
||||
return errors
|
||||
if not isinstance(artifact_hash, str) or len(artifact_hash) != 64:
|
||||
errors.append({"field": f"engines.{engine}.artifact_hash", "error": "sha256_required_for_verified_status"})
|
||||
return errors
|
||||
artifact_path = (manifest_dir / raw_path).resolve()
|
||||
if not artifact_path.is_file():
|
||||
errors.append({"field": f"engines.{engine}.raw_output_path", "error": "missing_artifact"})
|
||||
return errors
|
||||
actual_hash = hashlib.sha256(artifact_path.read_bytes()).hexdigest()
|
||||
if actual_hash != artifact_hash:
|
||||
errors.append({"field": f"engines.{engine}.artifact_hash", "error": "hash_mismatch"})
|
||||
if not isinstance(payload.get("settings"), dict):
|
||||
errors.append({"field": f"engines.{engine}.settings", "error": "required_for_verified_status"})
|
||||
return errors
|
||||
|
||||
|
||||
def _row_errors(row: Any, index: int) -> list[dict[str, Any]]:
|
||||
@@ -37,6 +65,8 @@ def validate_manifest(path: str | Path) -> dict[str, Any]:
|
||||
missing_engines = sorted(REQUIRED_ENGINES - set(engines))
|
||||
for engine in missing_engines:
|
||||
errors.append({"field": f"engines.{engine}", "error": "missing"})
|
||||
for engine, payload in engines.items():
|
||||
errors.extend(_artifact_errors(engine, payload, manifest_path.parent))
|
||||
|
||||
if not isinstance(rows, list):
|
||||
rows = []
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import json
|
||||
|
||||
from scripts.three_engine_parity_replay_validator import validate_manifest
|
||||
|
||||
|
||||
def test_verified_oracle_requires_raw_artifact_hash_and_settings(tmp_path):
|
||||
manifest = {
|
||||
"engines": {
|
||||
"VedAstro": {"status": "official_verified"},
|
||||
"PyJHora_JHora": {"status": "blocked"},
|
||||
"jyotishganit": {"status": "blocked"},
|
||||
},
|
||||
"comparison_rows": [],
|
||||
}
|
||||
path = tmp_path / "manifest.json"
|
||||
path.write_text(json.dumps(manifest), encoding="utf-8")
|
||||
|
||||
result = validate_manifest(path)
|
||||
|
||||
assert result["status"] == "invalid"
|
||||
assert any(error["error"] == "required_for_verified_status" for error in result["errors"])
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -18,12 +19,19 @@ def test_three_engine_parity_manifest_blocks_without_oracle_rows() -> None:
|
||||
|
||||
|
||||
def test_three_engine_parity_validator_accepts_one_same_chart_row(tmp_path: Path) -> None:
|
||||
raw = tmp_path / "vedastro.json"
|
||||
raw.write_text('{"source":"official"}', encoding="utf-8")
|
||||
manifest = {
|
||||
"case_id": "public_same_chart_001",
|
||||
"birth_data_policy": "public_case_only",
|
||||
"status": "tested",
|
||||
"engines": {
|
||||
"VedAstro": {"status": "official_verified", "official_raw_response_path": "references/oracle/artifacts/vedastro.json"},
|
||||
"VedAstro": {
|
||||
"status": "official_verified",
|
||||
"official_raw_response_path": "vedastro.json",
|
||||
"artifact_hash": hashlib.sha256(raw.read_bytes()).hexdigest(),
|
||||
"settings": {"ayanamsa": "lahiri"},
|
||||
},
|
||||
"PyJHora_JHora": {"status": "tested", "raw_output_path": "references/oracle/artifacts/pyjhora.txt"},
|
||||
"jyotishganit": {"status": "tested", "raw_output_path": "references/oracle/artifacts/jyotishganit.json"},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user