Add interpretation source inventory gate

This commit is contained in:
732642856
2026-07-02 14:17:18 +08:00
parent 801416458f
commit f2a741d36b
7 changed files with 353 additions and 2 deletions
+176 -1
View File
@@ -116,21 +116,158 @@ def _load_json_file(path: str) -> Dict[str, Any]:
return data if isinstance(data, dict) else {}
def _existing_paths(paths: List[str]) -> List[str]:
return [path for path in paths if _repo_relative_exists(path)]
def _build_interpretation_source_inventory(source_refs: List[str]) -> Dict[str, Any]:
primary_truth = [
"references/interpretation_template_registry.json",
"references/raman-house-judgment-methodology.md",
"references/bphs-ch48-narayana-dasha.md",
"references/mandatory-verification-gate-protocol.md",
"references/real-reading-quality-checklist.md",
]
frontend_interpretation = [
"jyotish-app/interpretation.js",
"jyotish-app/analysis-deep.js",
"jyotish-app/planet-house-details-a.js",
"jyotish-app/planet-house-details-b.js",
"jyotish-app/planet-house-details-c.js",
]
qa_governance = [
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/qa_rules.md",
]
reader_validation = [
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/chart_reading_rules.md",
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/validation_rules.md",
]
yoga_rules = [
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/yogas.md",
"references/yoga_rules.json",
"jyotish-app/yoga-details-a.js",
"jyotish-app/yoga-details-b.js",
"jyotish-app/yoga-extended.js",
"jyotish-app/yoga-extended-b.js",
]
saham_rules = [
"references/saham_rules.json",
]
reference_layer = [
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/p1_p12.md",
"references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/house_framework.md",
*frontend_interpretation,
*qa_governance,
*reader_validation,
*yoga_rules,
*saham_rules,
]
quarantined_drafts = [
"docs/research/local_drafts/2026-06/skill_fragment_map_and_source_of_truth_2026_06_26.md",
"docs/research/local_drafts/2026-06/dasha_accuracy_closure_status_2026_06_26.md",
"docs/research/local_drafts/2026-06/dasha_code_only_priority_rerank_2026_06_26.md",
]
layers = {
"primary_truth": {
"status": "available",
"promotion_status": "primary_truth",
"source_refs": _existing_paths(primary_truth),
"missing_refs": [path for path in primary_truth if not _repo_relative_exists(path)],
},
"frontend_interpretation": {
"status": "available",
"promotion_status": "reference_layer",
"source_refs": _existing_paths(frontend_interpretation),
"missing_refs": [path for path in frontend_interpretation if not _repo_relative_exists(path)],
},
"qa_governance": {
"status": "available",
"promotion_status": "reference_layer",
"source_refs": _existing_paths(qa_governance),
"missing_refs": [path for path in qa_governance if not _repo_relative_exists(path)],
},
"reader_validation": {
"status": "available",
"promotion_status": "reference_layer",
"source_refs": _existing_paths(reader_validation),
"missing_refs": [path for path in reader_validation if not _repo_relative_exists(path)],
},
"yoga_rules": {
"status": "available",
"promotion_status": "reference_layer",
"source_refs": _existing_paths(yoga_rules),
"missing_refs": [path for path in yoga_rules if not _repo_relative_exists(path)],
},
"saham_rules": {
"status": "available",
"promotion_status": "reference_layer",
"source_refs": _existing_paths(saham_rules),
"missing_refs": [path for path in saham_rules if not _repo_relative_exists(path)],
},
"quarantined_drafts": {
"status": "quarantined",
"promotion_status": "not_truth_source",
"source_refs": _existing_paths(quarantined_drafts),
"missing_refs": [path for path in quarantined_drafts if not _repo_relative_exists(path)],
"boundary": "Listed for awareness only; drafts are not promoted into runtime source_refs.",
},
}
missing_refs = [path for layer in layers.values() for path in layer["missing_refs"]]
quarantined_refs = set(layers["quarantined_drafts"]["source_refs"])
promoted_quarantined = sorted(quarantined_refs.intersection(source_refs))
status = "used" if not missing_refs and not promoted_quarantined else "partial"
return {
"status": status,
"source": "repo_interpretation_source_inventory_v1",
"layers": layers,
"summary": {
"primary_truth_count": len(layers["primary_truth"]["source_refs"]),
"reference_layer_count": len(_existing_paths(reference_layer)),
"quarantined_draft_count": len(layers["quarantined_drafts"]["source_refs"]),
"missing_ref_count": len(missing_refs),
"promoted_quarantined_count": len(promoted_quarantined),
},
"missing_refs": missing_refs,
"promoted_quarantined_refs": promoted_quarantined,
"boundary": "Inventory is explicit and conservative; local drafts are indexed but not treated as truth sources.",
}
@lru_cache(maxsize=1)
def _existing_interpretation_source_pack() -> Dict[str, Any]:
"""Return the existing repo interpretation/source layers as an explicit evidence pack."""
template_path = "references/interpretation_template_registry.json"
p1_p12_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/p1_p12.md"
house_framework_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/house_framework.md"
qa_rules_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/qa_rules.md"
core_yogas_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/yogas.md"
reader_chart_rules_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/chart_reading_rules.md"
reader_validation_rules_path = "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/validation_rules.md"
raman_path = "references/raman-house-judgment-methodology.md"
bphs_narayana_path = "references/bphs-ch48-narayana-dasha.md"
mevg_path = "references/mandatory-verification-gate-protocol.md"
real_case_checklist_path = "references/real-reading-quality-checklist.md"
frontend_interpretation_paths = [
"jyotish-app/interpretation.js",
"jyotish-app/analysis-deep.js",
]
planet_house_paths = [
"jyotish-app/planet-house-details-a.js",
"jyotish-app/planet-house-details-b.js",
"jyotish-app/planet-house-details-c.js",
]
yoga_rule_paths = [
core_yogas_path,
"references/yoga_rules.json",
"jyotish-app/yoga-details-a.js",
"jyotish-app/yoga-details-b.js",
"jyotish-app/yoga-extended.js",
"jyotish-app/yoga-extended-b.js",
]
saham_rule_paths = [
"references/saham_rules.json",
]
template_ids: List[str] = []
template_count = 0
@@ -151,14 +288,22 @@ def _existing_interpretation_source_pack() -> Dict[str, Any]:
bphs_narayana_path,
mevg_path,
real_case_checklist_path,
*frontend_interpretation_paths,
*planet_house_paths,
qa_rules_path,
reader_chart_rules_path,
reader_validation_rules_path,
*yoga_rule_paths,
*saham_rule_paths,
]
missing_refs = [path for path in source_refs if not _repo_relative_exists(path)]
inventory = _build_interpretation_source_inventory(source_refs)
return {
"status": "used" if not missing_refs else "partial",
"status": "used" if not missing_refs and inventory.get("status") == "used" else "partial",
"source": "repo_existing_interpretation_sources",
"source_refs": source_refs,
"missing_refs": missing_refs,
"interpretation_source_inventory": inventory,
"template_registry": {
"path": template_path,
"template_count": template_count,
@@ -171,11 +316,21 @@ def _existing_interpretation_source_pack() -> Dict[str, Any]:
"bphs_narayana_dasha",
"mevg_mandatory_external_verification",
"real_case_quality_checklist",
"qa_governance_rules",
"reader_validation_rules",
"frontend_interpretation_layer",
"yoga_rule_layer",
"saham_rule_layer",
],
"bphs_raman_layer": {
"status": "available" if _repo_relative_exists(raman_path) and _repo_relative_exists(bphs_narayana_path) else "partial",
"source_refs": [raman_path, bphs_narayana_path],
},
"frontend_interpretation_layer": {
"status": "available" if all(_repo_relative_exists(path) for path in frontend_interpretation_paths) else "partial",
"source_refs": frontend_interpretation_paths,
"promotion_status": "reference_layer",
},
"frontend_planet_house_details": {
"status": "available" if all(_repo_relative_exists(path) for path in planet_house_paths) else "partial",
"coverage": "9_planets_x_12_houses",
@@ -183,6 +338,26 @@ def _existing_interpretation_source_pack() -> Dict[str, Any]:
"house_count": 12,
"source_refs": planet_house_paths,
},
"qa_governance_layer": {
"status": "available" if _repo_relative_exists(qa_rules_path) else "partial",
"source_refs": [qa_rules_path],
"promotion_status": "reference_layer",
},
"reader_validation_layer": {
"status": "available" if all(_repo_relative_exists(path) for path in [reader_chart_rules_path, reader_validation_rules_path]) else "partial",
"source_refs": [reader_chart_rules_path, reader_validation_rules_path],
"promotion_status": "reference_layer",
},
"yoga_rule_layer": {
"status": "available" if all(_repo_relative_exists(path) for path in yoga_rule_paths) else "partial",
"source_refs": yoga_rule_paths,
"promotion_status": "reference_layer",
},
"saham_rule_layer": {
"status": "available" if all(_repo_relative_exists(path) for path in saham_rule_paths) else "partial",
"source_refs": saham_rule_paths,
"promotion_status": "reference_layer",
},
"mevg_gate": {
"status": "blocked",
"required": True,
@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Validate interpretation source inventory wiring and draft quarantine."""
from __future__ import annotations
import json
import sys
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from mcp_server import _existing_interpretation_source_pack # noqa: E402
REQUIRED_LAYERS = [
"primary_truth",
"frontend_interpretation",
"qa_governance",
"reader_validation",
"yoga_rules",
"saham_rules",
"quarantined_drafts",
]
def build_report() -> dict[str, Any]:
source_pack = _existing_interpretation_source_pack()
inventory = source_pack.get("interpretation_source_inventory") if isinstance(source_pack, dict) else {}
if not isinstance(inventory, dict):
inventory = {}
layers = inventory.get("layers") if isinstance(inventory.get("layers"), dict) else {}
summary = inventory.get("summary") if isinstance(inventory.get("summary"), dict) else {}
source_refs = source_pack.get("source_refs") if isinstance(source_pack.get("source_refs"), list) else []
missing_layers = [name for name in REQUIRED_LAYERS if name not in layers]
missing_refs = inventory.get("missing_refs") if isinstance(inventory.get("missing_refs"), list) else []
promoted_quarantined = (
inventory.get("promoted_quarantined_refs")
if isinstance(inventory.get("promoted_quarantined_refs"), list)
else []
)
failures: list[dict[str, Any]] = []
if source_pack.get("status") != "used":
failures.append({"id": "source_pack_not_used", "status": source_pack.get("status")})
if inventory.get("status") != "used":
failures.append({"id": "inventory_not_used", "status": inventory.get("status")})
if missing_layers:
failures.append({"id": "missing_inventory_layers", "layers": missing_layers})
if missing_refs:
failures.append({"id": "missing_source_refs", "refs": missing_refs})
if promoted_quarantined:
failures.append({"id": "quarantined_drafts_promoted", "refs": promoted_quarantined})
status = "pass" if not failures else "fail"
return {
"scope": "interpretation_source_inventory_gate",
"status": status,
"source_pack_status": source_pack.get("status"),
"inventory_status": inventory.get("status"),
"summary": summary,
"layers": layers,
"runtime_source_refs": source_refs,
"failures": failures,
"boundary": (
"This gate validates explicit source inventory wiring. It does not promote drafts "
"or replace MEVG/global-web/real-case verification for interpretive claims."
),
}
def main() -> int:
report = build_report()
print(json.dumps(report, ensure_ascii=False, indent=2))
return 0 if report["status"] == "pass" else 1
if __name__ == "__main__":
raise SystemExit(main())
+2
View File
@@ -30,6 +30,7 @@ EXTRA_COMPILE_TARGETS = [
ROOT / "scripts" / "audit_fragments.py",
ROOT / "scripts" / "dasha_reference_audit.py",
ROOT / "scripts" / "external_oracle_sanity_closure.py",
ROOT / "scripts" / "interpretation_source_inventory_gate.py",
ROOT / "scripts" / "oracle_boundary_audit.py",
ROOT / "scripts" / "oracle_collection_queue.py",
ROOT / "scripts" / "oracle_evidence_validator.py",
@@ -480,6 +481,7 @@ def main() -> int:
validate_json_files()
run([PYTHON, "scripts/audit_capabilities.py", "--mode", "validate"])
run([PYTHON, "scripts/audit_fragments.py", "--strict"])
run([PYTHON, "scripts/interpretation_source_inventory_gate.py"])
run([PYTHON, "scripts/deployment_preflight.py"])
if profile["check_release_hygiene"]:
release_hygiene_check()
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Regression tests for interpretation source inventory governance."""
from __future__ import annotations
import json
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def test_interpretation_source_inventory_gate_reports_layered_source_pack() -> None:
completed = subprocess.run(
[
sys.executable,
"scripts/interpretation_source_inventory_gate.py",
],
cwd=ROOT,
text=True,
capture_output=True,
timeout=120,
check=False,
)
assert completed.returncode == 0, completed.stderr or completed.stdout
report = json.loads(completed.stdout)
assert report["scope"] == "interpretation_source_inventory_gate"
assert report["status"] == "pass"
assert report["source_pack_status"] == "used"
assert report["summary"]["missing_ref_count"] == 0
assert report["summary"]["promoted_quarantined_count"] == 0
assert report["summary"]["primary_truth_count"] >= 5
assert report["summary"]["reference_layer_count"] >= 10
assert report["summary"]["quarantined_draft_count"] >= 1
layers = report["layers"]
assert "jyotish-app/interpretation.js" in layers["frontend_interpretation"]["source_refs"]
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/qa_rules.md" in layers["qa_governance"]["source_refs"]
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/validation_rules.md" in layers["reader_validation"]["source_refs"]
assert "references/yoga_rules.json" in layers["yoga_rules"]["source_refs"]
assert "references/saham_rules.json" in layers["saham_rules"]["source_refs"]
draft_refs = layers["quarantined_drafts"]["source_refs"]
source_refs = set(report["runtime_source_refs"])
assert any("docs/research/local_drafts/" in path for path in draft_refs)
assert all(path not in source_refs for path in draft_refs)
def test_quality_gate_runs_interpretation_source_inventory_gate() -> None:
quality_gate = (ROOT / "scripts" / "run_quality_gate.py").read_text(encoding="utf-8")
assert '"scripts/interpretation_source_inventory_gate.py"' in quality_gate
assert '[PYTHON, "scripts/interpretation_source_inventory_gate.py"]' in quality_gate
+29 -1
View File
@@ -5,7 +5,7 @@ from __future__ import annotations
import jyotish_engine
from mcp_server import _collect_strict_evidence
from mcp_server import _collect_strict_evidence, _existing_interpretation_source_pack
def _base_career_result() -> dict:
@@ -85,6 +85,16 @@ def test_career_strict_contract_attaches_existing_interpretation_source_pack() -
assert source_pack["template_registry"]["template_count"] >= 11
assert source_pack["frontend_planet_house_details"]["planet_count"] == 9
assert source_pack["frontend_planet_house_details"]["house_count"] == 12
assert source_pack["interpretation_source_inventory"]["status"] == "used"
assert source_pack["frontend_interpretation_layer"]["status"] == "available"
assert source_pack["frontend_interpretation_layer"]["source_refs"] == [
"jyotish-app/interpretation.js",
"jyotish-app/analysis-deep.js",
]
assert source_pack["yoga_rule_layer"]["status"] == "available"
assert "references/yoga_rules.json" in source_pack["yoga_rule_layer"]["source_refs"]
assert source_pack["reader_validation_layer"]["status"] == "available"
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/validation_rules.md" in source_pack["reader_validation_layer"]["source_refs"]
audit = strict["technique_audit_summary"]
assert audit["interpretation_source_pack"]["used"] is True
@@ -92,6 +102,24 @@ def test_career_strict_contract_attaches_existing_interpretation_source_pack() -
assert audit["real_case_calibration"]["status"] == "blocked"
def test_interpretation_source_inventory_classifies_sources_without_promoting_drafts() -> None:
source_pack = _existing_interpretation_source_pack()
inventory = source_pack["interpretation_source_inventory"]
assert inventory["status"] == "used"
assert inventory["summary"]["primary_truth_count"] >= 4
assert inventory["summary"]["reference_layer_count"] >= 4
assert inventory["summary"]["quarantined_draft_count"] >= 1
assert "jyotish-app/interpretation.js" in inventory["layers"]["frontend_interpretation"]["source_refs"]
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/qa_rules.md" in inventory["layers"]["qa_governance"]["source_refs"]
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-reader/resources/validation_rules.md" in inventory["layers"]["reader_validation"]["source_refs"]
assert "references/yoga_rules.json" in inventory["layers"]["yoga_rules"]["source_refs"]
draft_refs = inventory["layers"]["quarantined_drafts"]["source_refs"]
assert any("docs/research/local_drafts/" in path for path in draft_refs)
assert all(path not in source_pack["source_refs"] for path in draft_refs)
def test_career_blocks_label_when_d10_is_missing_but_preserves_jaimini_context() -> None:
result = _base_career_result()
del result["modules"]["varga_full"]["D10_Dasamsa"]
@@ -43,6 +43,10 @@ def test_finance_strict_contract_attaches_existing_interpretation_source_pack()
assert "yogi_asc_tight_orb_wealth" in source_pack["template_registry"]["template_ids"]
assert source_pack["bphs_raman_layer"]["status"] == "available"
assert source_pack["frontend_planet_house_details"]["coverage"] == "9_planets_x_12_houses"
assert source_pack["interpretation_source_inventory"]["status"] == "used"
assert source_pack["frontend_interpretation_layer"]["status"] == "available"
assert source_pack["yoga_rule_layer"]["status"] == "available"
assert source_pack["qa_governance_layer"]["status"] == "available"
audit = strict["technique_audit_summary"]
assert audit["interpretation_source_pack"]["used"] is True
@@ -72,6 +72,10 @@ def test_relationship_strict_contract_attaches_existing_interpretation_source_pa
assert "p1_p12" in source_pack["frameworks"]
assert "house_framework" in source_pack["frameworks"]
assert "raman_functional_house_judgment" in source_pack["frameworks"]
assert source_pack["interpretation_source_inventory"]["status"] == "used"
assert source_pack["qa_governance_layer"]["status"] == "available"
assert source_pack["reader_validation_layer"]["status"] == "available"
assert "references/open_source_sources/vedic-astro-skills/codex/skills/vedic-core/resources/qa_rules.md" in source_pack["qa_governance_layer"]["source_refs"]
audit = strict["technique_audit_summary"]
assert audit["interpretation_source_pack"]["source"] == "repo_existing_interpretation_sources"