{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://lexega.com/schemas/v1/decision.schema.json",
  "definitions": {
    "AnalysisSummary": {
      "description": "Risk summary statistics",
      "type": "object",
      "required": [
        "control_operations",
        "critical_count",
        "cross_database",
        "cross_schema",
        "databases_accessed",
        "ddl_operations",
        "high_count",
        "info_count",
        "jinja_blocks",
        "low_count",
        "medium_count",
        "security_operations",
        "statements_analyzed",
        "statements_parsed",
        "statements_skipped",
        "tables_read",
        "tables_written",
        "total_reported_signals"
      ],
      "properties": {
        "analysis_confidence": {
          "description": "Overall analysis confidence based on placeholder impact",
          "default": "high",
          "allOf": [
            {
              "$ref": "#/definitions/ConfidenceLevel"
            }
          ]
        },
        "assumed_role": {
          "description": "Role assumed for analysis (from USE ROLE statement)",
          "type": [
            "string",
            "null"
          ]
        },
        "control_operations": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "critical_count": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "cross_database": {
          "description": "Cross-database access (different databases accessed)",
          "type": "boolean"
        },
        "cross_schema": {
          "description": "Cross-schema access (different schemas within same database)",
          "type": "boolean"
        },
        "databases_accessed": {
          "description": "Set of databases accessed (for reporting).",
          "type": "array",
          "items": {
            "type": "string"
          },
          "uniqueItems": true
        },
        "ddl_operations": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "high_count": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "info_count": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "jinja_blocks": {
          "description": "Jinja/template blocks that are NOT SQL ({{ config() }}, {% set %}, etc.)",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "low_count": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "medium_count": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "placeholders": {
          "description": "Aggregated placeholder summary (only present when render_completeness is Partial)",
          "anyOf": [
            {
              "$ref": "#/definitions/PlaceholderSummary"
            },
            {
              "type": "null"
            }
          ]
        },
        "procedure_bodies_analyzed": {
          "description": "Number of procedure/function bodies that were analyzed",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "render_completeness": {
          "description": "Render completeness: full (no placeholders) or partial (has placeholders)",
          "default": "full",
          "allOf": [
            {
              "$ref": "#/definitions/RenderCompleteness"
            }
          ]
        },
        "security_operations": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_analyzed": {
          "description": "Statements the analyzer recognized and evaluated — reads, writes, DDL, security, and procedural control flow.",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_in_bodies": {
          "description": "Total SQL statements found inside procedure/function bodies",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_parsed": {
          "description": "Total SQL statements seen, counted at every depth — top-level plus those inside procedure / function / block bodies. Equals `statements_analyzed + statements_skipped + jinja_blocks`.",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_partial": {
          "description": "Statements whose kind was recognized but whose payload could not be fully parsed — e.g. an `ALTER TABLE` action that fell through to `Unknown`, or a `GRANT`/`REVOKE` that degraded to an unparsed shape. These are a subset of `statements_analyzed` (the verb and target are known); a non-zero value lowers analysis confidence so silently-dropped payloads are visible. Omitted from serialization when zero.",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_skipped": {
          "description": "Statements the parser could not recognize, so they were not analyzed (unsupported or malformed syntax). A non-zero value lowers analysis confidence.",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "tables_read": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "tables_written": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "total_reported_signals": {
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        }
      }
    },
    "ConfidenceLevel": {
      "description": "Confidence level for analysis results",
      "oneOf": [
        {
          "description": "Low confidence - placeholders in critical zones",
          "type": "string",
          "enum": [
            "low"
          ]
        },
        {
          "description": "Medium confidence - some uncertainty",
          "type": "string",
          "enum": [
            "medium"
          ]
        },
        {
          "description": "High confidence - full resolution",
          "type": "string",
          "enum": [
            "high"
          ]
        }
      ]
    },
    "DecisionAnalysis": {
      "type": "object",
      "required": [
        "matched_rules",
        "risk_schema_version",
        "risk_summary"
      ],
      "properties": {
        "matched_rules": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/MatchedRule"
          }
        },
        "risk_schema_version": {
          "type": "integer",
          "format": "uint32",
          "minimum": 0.0
        },
        "risk_summary": {
          "$ref": "#/definitions/AnalysisSummary"
        }
      }
    },
    "DecisionArtifacts": {
      "type": "object",
      "properties": {
        "decision_path": {
          "type": [
            "string",
            "null"
          ]
        },
        "risk_report_path": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "DecisionInputs": {
      "type": "object",
      "required": [
        "env_context",
        "policy_id",
        "policy_sha256",
        "policy_version",
        "sql_sha256"
      ],
      "properties": {
        "env_context": {
          "$ref": "#/definitions/EnvContext"
        },
        "exceptions_sha256": {
          "type": [
            "string",
            "null"
          ]
        },
        "policy_id": {
          "type": "string"
        },
        "policy_sha256": {
          "type": "string"
        },
        "policy_version": {
          "type": "string"
        },
        "sql_sha256": {
          "type": "string"
        }
      }
    },
    "DecisionOutcome": {
      "type": "object",
      "required": [
        "allowed",
        "exceptions_used"
      ],
      "properties": {
        "allowed": {
          "type": "boolean"
        },
        "blocked_reason": {
          "type": [
            "string",
            "null"
          ]
        },
        "exceptions_used": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "EnvContext": {
      "type": "object",
      "required": [
        "env"
      ],
      "properties": {
        "change_id": {
          "type": [
            "string",
            "null"
          ]
        },
        "commit_sha": {
          "type": [
            "string",
            "null"
          ]
        },
        "env": {
          "type": "string"
        },
        "job_type": {
          "type": [
            "string",
            "null"
          ]
        },
        "path": {
          "description": "Optional file path (used for exception scoping)",
          "type": [
            "string",
            "null"
          ]
        },
        "repo": {
          "type": [
            "string",
            "null"
          ]
        },
        "role": {
          "description": "Snowflake execution role (from USE ROLE in SQL or --role flag) Used for role-based exception scoping",
          "type": [
            "string",
            "null"
          ]
        },
        "service": {
          "type": [
            "string",
            "null"
          ]
        },
        "team": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "MatchedRule": {
      "type": "object",
      "required": [
        "action",
        "matching_signals",
        "rule_id",
        "severity"
      ],
      "properties": {
        "action": {
          "$ref": "#/definitions/PolicyAction"
        },
        "exception_used": {
          "type": [
            "string",
            "null"
          ]
        },
        "matching_signals": {
          "description": "Indices into `risk_report.signals`",
          "type": "array",
          "items": {
            "type": "integer",
            "format": "uint",
            "minimum": 0.0
          }
        },
        "policy_description": {
          "description": "Why this org cares (from policy.yml, explains org's stance)",
          "type": [
            "string",
            "null"
          ]
        },
        "rule_description": {
          "description": "What the rule detects (from signal message, explains the pattern)",
          "type": [
            "string",
            "null"
          ]
        },
        "rule_id": {
          "type": "string"
        },
        "severity": {
          "description": "Effective severity (from signal or policy override)",
          "allOf": [
            {
              "$ref": "#/definitions/RiskLevel"
            }
          ]
        }
      }
    },
    "PlaceholderSummary": {
      "description": "Aggregated placeholder summary for a file or batch",
      "type": "object",
      "required": [
        "high_impact",
        "low_impact",
        "statements_impacted",
        "top_kinds",
        "top_sources",
        "total"
      ],
      "properties": {
        "high_impact": {
          "description": "High-impact placeholders (WHERE, JOIN, FROM, DML_TARGET, DDL_OBJECT)",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "low_impact": {
          "description": "Low-impact placeholders (SELECT, ORDER_BY, etc.)",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_impacted": {
          "description": "Statements that contain placeholders",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "top_kinds": {
          "description": "Top placeholder kinds (kind -> count)",
          "type": "array",
          "items": {
            "type": "array",
            "items": [
              {
                "type": "string"
              },
              {
                "type": "integer",
                "format": "uint",
                "minimum": 0.0
              }
            ],
            "maxItems": 2,
            "minItems": 2
          }
        },
        "top_sources": {
          "description": "Top placeholder sources (macro name -> count)",
          "type": "array",
          "items": {
            "type": "array",
            "items": [
              {
                "type": "string"
              },
              {
                "type": "integer",
                "format": "uint",
                "minimum": 0.0
              }
            ],
            "maxItems": 2,
            "minItems": 2
          }
        },
        "total": {
          "description": "Total placeholder count",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        }
      }
    },
    "PolicyAction": {
      "type": "string",
      "enum": [
        "allow",
        "block",
        "warn"
      ]
    },
    "RenderCompleteness": {
      "description": "Render completeness level",
      "oneOf": [
        {
          "description": "No placeholders, full resolution",
          "type": "string",
          "enum": [
            "full"
          ]
        },
        {
          "description": "Some placeholders inserted but only in low-impact zones (SELECT, ORDER BY, etc.)",
          "type": "string",
          "enum": [
            "partial_low_impact_only"
          ]
        },
        {
          "description": "Some placeholders inserted including high-impact zones (WHERE, JOIN, FROM, etc.)",
          "type": "string",
          "enum": [
            "partial"
          ]
        },
        {
          "description": "A template was present but could not be rendered — analysis ran on the template text itself, so the rendered shape of the SQL is unknown",
          "type": "string",
          "enum": [
            "not_rendered"
          ]
        }
      ]
    },
    "RiskLevel": {
      "description": "Risk severity levels",
      "oneOf": [
        {
          "type": "string",
          "enum": [
            "Low",
            "Medium",
            "High",
            "Critical"
          ]
        },
        {
          "description": "Informational - not a risk, just tracking/awareness",
          "type": "string",
          "enum": [
            "Info"
          ]
        }
      ]
    },
    "RunScope": {
      "description": "What a run measured. Keeps pre-merge gate history and repository posture history distinguishable in downstream consumers (dashboard, audit pipelines) when both kinds of artifacts share a storage location.",
      "oneOf": [
        {
          "description": "Pre-merge evaluation of a commit range (`review`, `diff`).",
          "type": "object",
          "required": [
            "kind"
          ],
          "properties": {
            "base": {
              "description": "Base ref or commit of the compared range, as given to the CLI.",
              "type": [
                "string",
                "null"
              ]
            },
            "change_id": {
              "description": "Stable identifier of the change under review (PR / MR number). From `--change-id` or detected from the CI environment. Lets consumers group repeated runs of the same change (each push to an open PR re-runs the review).",
              "type": [
                "string",
                "null"
              ]
            },
            "head": {
              "description": "Head ref or commit of the compared range, as given to the CLI.",
              "type": [
                "string",
                "null"
              ]
            },
            "kind": {
              "type": "string",
              "enum": [
                "change"
              ]
            }
          }
        },
        {
          "description": "Evaluation of the repository state as checked out (`analyze`).",
          "type": "object",
          "required": [
            "kind"
          ],
          "properties": {
            "commit": {
              "description": "Commit SHA of the analyzed state, when provided via `--commit`.",
              "type": [
                "string",
                "null"
              ]
            },
            "kind": {
              "type": "string",
              "enum": [
                "snapshot"
              ]
            }
          }
        },
        {
          "description": "Evaluation of a single statement at execution time.",
          "type": "object",
          "required": [
            "kind"
          ],
          "properties": {
            "kind": {
              "type": "string",
              "enum": [
                "runtime"
              ]
            }
          }
        }
      ]
    }
  },
  "title": "DecisionRecord",
  "type": "object",
  "required": [
    "analysis",
    "artifacts",
    "decision_id",
    "decision_schema_version",
    "inputs",
    "outcome",
    "timestamp"
  ],
  "properties": {
    "analysis": {
      "$ref": "#/definitions/DecisionAnalysis"
    },
    "artifacts": {
      "$ref": "#/definitions/DecisionArtifacts"
    },
    "decision_id": {
      "type": "string"
    },
    "decision_schema_version": {
      "type": "integer",
      "format": "uint32",
      "minimum": 0.0,
      "const": 1,
      "description": "Decision schema version (must be 1)"
    },
    "engine_version": {
      "description": "Version of the lexega-sql engine that produced this decision",
      "default": "",
      "type": "string"
    },
    "inputs": {
      "$ref": "#/definitions/DecisionInputs"
    },
    "outcome": {
      "$ref": "#/definitions/DecisionOutcome"
    },
    "run_id": {
      "description": "CI run identifier that produced this decision. Inherited from the risk report. Groups artifacts written by the same run.",
      "type": [
        "string",
        "null"
      ]
    },
    "run_scope": {
      "description": "What the evaluated run measured (commit range, repository snapshot, or runtime statement). Inherited from the risk report this decision was made against. Absent in decisions from older engine versions.",
      "anyOf": [
        {
          "$ref": "#/definitions/RunScope"
        },
        {
          "type": "null"
        }
      ]
    },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    }
  }
}