Initial SQL-only 1C adapter baseline

This commit is contained in:
2026-07-22 03:03:47 +03:00
commit e2503b77e7
545 changed files with 184711 additions and 0 deletions
+116
View File
@@ -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())