Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run the full read-only preflight for a 1C patch workspace."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from check_1c_patch_source_freshness import check_workspace_sources
|
||||
from check_1c_patch_workspace_integrity import check_workspace
|
||||
from diff_1c_patch_workspace import build_diff
|
||||
from validate_1c_patch_workspace_semantics import validate_workspace
|
||||
|
||||
|
||||
def load_json(path: Path) -> dict[str, Any]:
|
||||
return json.loads(path.read_text(encoding="utf-8-sig"))
|
||||
|
||||
|
||||
def safety_from_workspace(workspace: Path) -> dict[str, Any]:
|
||||
path = workspace / "safety.json"
|
||||
if not path.exists():
|
||||
return {
|
||||
"schema": "onec_change_proposal_safety_check.v1",
|
||||
"passed": False,
|
||||
"findings": [{"severity": "error", "code": "missing_safety_json", "message": f"Missing {path}"}],
|
||||
"counts": {"errors": 1, "warnings": 0},
|
||||
}
|
||||
return load_json(path)
|
||||
|
||||
|
||||
def status_from_checks(safety: dict[str, Any], integrity: dict[str, Any], freshness: dict[str, Any], semantic: dict[str, Any], diff: dict[str, Any]) -> str:
|
||||
if not safety.get("passed") or not integrity.get("passed") or not freshness.get("passed") or not semantic.get("passed") or not diff.get("passed"):
|
||||
return "blocked"
|
||||
modified = (diff.get("counts") or {}).get("modified", 0)
|
||||
if modified:
|
||||
return "ready_for_review"
|
||||
return "ready_for_editing"
|
||||
|
||||
|
||||
def collect_gate(name: str, data: dict[str, Any]) -> dict[str, Any]:
|
||||
return {
|
||||
"name": name,
|
||||
"schema": data.get("schema"),
|
||||
"passed": data.get("passed"),
|
||||
"counts": data.get("counts"),
|
||||
}
|
||||
|
||||
|
||||
def next_actions(status: str) -> list[str]:
|
||||
if status == "blocked":
|
||||
return [
|
||||
"Inspect failed gates and recreate the workspace if source files changed.",
|
||||
"Do not generate, package, or apply patches until all gates pass.",
|
||||
]
|
||||
if status == "ready_for_editing":
|
||||
return [
|
||||
"Edit only files under working/.",
|
||||
"Run preflight again after edits; BSL/Form.xml semantic validation is included.",
|
||||
]
|
||||
return [
|
||||
"Review the workspace diff.",
|
||||
"Run external BSL/1C validation in a disposable base before packaging or applying.",
|
||||
]
|
||||
|
||||
|
||||
def build_preflight(workspace: Path, *, max_patch_chars: int) -> dict[str, Any]:
|
||||
safety = safety_from_workspace(workspace)
|
||||
integrity = check_workspace(workspace)
|
||||
freshness = check_workspace_sources(workspace)
|
||||
semantic = validate_workspace(workspace)
|
||||
diff = build_diff(workspace, max_patch_chars=max_patch_chars)
|
||||
status = status_from_checks(safety, integrity, freshness, semantic, diff)
|
||||
return {
|
||||
"schema": "onec_patch_preflight.v1",
|
||||
"workspace": str(workspace),
|
||||
"status": status,
|
||||
"passed": status != "blocked",
|
||||
"gates": [
|
||||
collect_gate("proposal_safety", safety),
|
||||
collect_gate("workspace_integrity", integrity),
|
||||
collect_gate("source_freshness", freshness),
|
||||
collect_gate("workspace_semantic_validation", semantic),
|
||||
collect_gate("workspace_diff", diff),
|
||||
],
|
||||
"diff_summary": diff.get("counts"),
|
||||
"next_actions": next_actions(status),
|
||||
"details": {
|
||||
"safety": safety,
|
||||
"integrity": integrity,
|
||||
"freshness": freshness,
|
||||
"semantic": semantic,
|
||||
"diff": diff,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Run 1C patch workspace preflight.")
|
||||
parser.add_argument("--workspace", type=Path, required=True)
|
||||
parser.add_argument("--max-patch-chars", type=int, default=200000)
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
result = build_preflight(args.workspace, max_patch_chars=args.max_patch_chars)
|
||||
output = json.dumps(result, ensure_ascii=False, indent=2) + "\n"
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(output, encoding="utf-8")
|
||||
print(json.dumps({"output": str(args.output) if args.output else None, "passed": result["passed"], "status": result["status"], "diff": result["diff_summary"]}, ensure_ascii=False))
|
||||
return 0 if result["passed"] else 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user