Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def read_json(path: Path) -> dict[str, Any]:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def fail(message: str, failures: list[str]) -> None:
|
||||
failures.append(message)
|
||||
|
||||
|
||||
def check_registry(registry: dict[str, Any]) -> dict[str, Any]:
|
||||
failures: list[str] = []
|
||||
if registry.get("schema") != "codex_1c_moxel_schema_registry.v1":
|
||||
fail("unexpected schema", failures)
|
||||
rules = [rule for rule in registry.get("rules") or [] if isinstance(rule, dict)]
|
||||
if not rules:
|
||||
fail("registry must contain rules", failures)
|
||||
verified = [rule for rule in rules if rule.get("read_status") == "verified_read"]
|
||||
if not verified:
|
||||
fail("registry must contain at least one verified_read rule", failures)
|
||||
write_enabled = [rule for rule in rules if rule.get("write_status") == "verified_roundtrip"]
|
||||
if write_enabled:
|
||||
fail("write rules must stay disabled until explicit round-trip evidence is implemented", failures)
|
||||
counts = registry.get("counts") if isinstance(registry.get("counts"), dict) else {}
|
||||
expected_counts = {
|
||||
"rules": len(rules),
|
||||
"verified_read": len(verified),
|
||||
"candidate_read": sum(1 for rule in rules if rule.get("read_status") == "candidate_read"),
|
||||
"write_enabled": len(write_enabled),
|
||||
}
|
||||
for key, expected in expected_counts.items():
|
||||
if counts.get(key) != expected:
|
||||
fail(f"counts.{key} must be {expected}, got {counts.get(key)}", failures)
|
||||
|
||||
inline = [rule for rule in rules if rule.get("target") == "moxel.inline_text_cell.column"]
|
||||
if not inline:
|
||||
fail("missing moxel.inline_text_cell.column rule", failures)
|
||||
else:
|
||||
rule = inline[0]
|
||||
evidence = rule.get("evidence") if isinstance(rule.get("evidence"), dict) else {}
|
||||
if rule.get("read_status") != "verified_read":
|
||||
fail("inline column rule must be verified_read", failures)
|
||||
if evidence.get("ok") != evidence.get("total") or not isinstance(evidence.get("total"), int) or evidence.get("total") <= 0:
|
||||
fail("inline column rule evidence must be complete", failures)
|
||||
|
||||
for rule in rules:
|
||||
if not rule.get("target"):
|
||||
fail(f"rule {rule.get('id')} has no target", failures)
|
||||
if rule.get("read_status") not in {"verified_read", "candidate_read", "needs_more_evidence"}:
|
||||
fail(f"rule {rule.get('id')} has unsupported read_status", failures)
|
||||
if rule.get("write_status") not in {"blocked_until_roundtrip", "blocked_until_verified_read", "verified_roundtrip"}:
|
||||
fail(f"rule {rule.get('id')} has unsupported write_status", failures)
|
||||
|
||||
return {
|
||||
"schema": "codex_1c_moxel_schema_registry_check.v1",
|
||||
"status": "ok" if not failures else "failed",
|
||||
"failures": failures,
|
||||
"counts": {
|
||||
**expected_counts,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Validate the 1C MOXCEL schema registry safety contract.")
|
||||
parser.add_argument("--registry", default="plugins/1c/metadata/moxel-schema-registry.json")
|
||||
parser.add_argument("--output", default="reports/1c-template-baselines/moxel-schema-registry-check.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
report = check_registry(read_json(Path(args.registry)))
|
||||
output_path = Path(args.output)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
output_path.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
print(json.dumps(report, ensure_ascii=False, indent=2))
|
||||
return 0 if report["status"] == "ok" else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user