"""mcp/atelier/plugins/validation.py — agentic validation against Atelier principles. Implements 1 MCP tool (REQ-223): - atelier.validate_against_principles(snippet, domains) → pass/fail per checklist item with the principle citation. This is the agentic validation BEYOND deterministic scanners (Wiz/Checkmarx/Mend) — it catches correctness/clarity/simplicity/observability gaps that deterministic tools cannot. """ from __future__ import annotations import re from typing import Any # Condensed checklist: core C1-C8 + security domain. Each item is a # (check_id, description, heuristic_pattern, principle_citation). _CHECKLIST = [ # C1 Correctness {"id": "C1.1", "desc": "Does the code do what the task asked, completely?", "heuristic": r"TODO|FIXME|pass\s*$", "principle": "C1 Correctness", "neg": True}, {"id": "C1.2", "desc": "Does it handle failure cases? (errors, timeouts)", "heuristic": r"except\s*:?\s*pass", "principle": "C1 Correctness", "neg": True}, {"id": "C1.3", "desc": "Is there a test that would fail if the code were wrong?", "heuristic": r"def test_|describe\(", "principle": "C1 Correctness", "neg": False, "optional": True}, # C2 Clarity {"id": "C2.1", "desc": "Are names intent-revealing? (no 'data', 'temp', 'x')", "heuristic": r"\b(data|temp|x|foo|bar|doStuff)\b", "principle": "C2 Clarity", "neg": True}, # C3 Simplicity {"id": "C3.1", "desc": "Is there dead code? (unreachable branches)", "heuristic": r"return\s+\w+\s*$.*return", "principle": "C3 Simplicity", "neg": True, "multiline": True}, # C7 Observability {"id": "C7.1", "desc": "Are there logs for significant events?", "heuristic": r"log(ger|ging)?|print\(|console\.", "principle": "C7 Observability", "neg": False, "optional": True}, {"id": "C7.2", "desc": "Are there secrets in logs?", "heuristic": r"password|secret|token|api_key", "principle": "C7 Observability + Security P4", "neg": True}, # Security {"id": "SEC.1", "desc": "No secrets in code/logs/URLs", "heuristic": r"(password|secret|token|api_key)\s*=\s*['\"]", "principle": "Security P4 Secrets Never Exposed", "neg": True}, {"id": "SEC.2", "desc": "Input validated at the boundary", "heuristic": r"validate|schema|assert", "principle": "Security P1 Boundary Validation", "neg": False, "optional": True}, {"id": "SEC.3", "desc": "Authorization checked, not assumed", "heuristic": r"auth|permission|rbac|authorize", "principle": "Security P5 Authenticated by Default", "neg": False, "optional": True}, ] def register(mcp: Any) -> None: """Register the validation tools with the MCP server (or fallback registry).""" @mcp.tool() def atelier_validate_against_principles(snippet: str, domains: list[str] | None = None) -> dict[str, Any]: """Validate a code/diff snippet against Atelier principles. Runs the agent-checklist items against the snippet and returns pass/fail per item with the principle citation. This is the agentic validation BEYOND deterministic scanners (Wiz/Checkmarx/ Mend) — it catches correctness/clarity/simplicity/observability gaps that deterministic tools cannot. Args: snippet: The code or diff text to validate. domains: Optional list of domains to include (default: core + security). """ results: list[dict[str, Any]] = [] for check in _CHECKLIST: pattern = check["heuristic"] flags = re.DOTALL if check.get("multiline") else 0 found = bool(re.search(pattern, snippet, flags)) # neg=True means finding the pattern is a FAIL; neg=False means finding is a PASS if check.get("neg"): status = "FAIL" if found else "PASS" else: if check.get("optional"): status = "PASS" if found else "WARN" else: status = "PASS" if found else "WARN" results.append({ "check_id": check["id"], "description": check["desc"], "status": status, "principle": check["principle"], }) all_pass = all(r["status"] == "PASS" for r in results) return { "overall": "PASS" if all_pass else "FAIL", "results": results, "domains_checked": domains or ["core", "security"], "note": "Agentic validation beyond Wiz/Checkmarx/Mend — catches correctness, clarity, simplicity, observability gaps.", }