{
  "$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": "SQL statements successfully classified (DML_READ, DML_WRITE, DDL, SECURITY, CONTROL)",
          "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 entries in ledger (SQL + Jinja + Unknown)",
          "type": "integer",
          "format": "uint",
          "minimum": 0.0
        },
        "statements_skipped": {
          "description": "Entries that couldn't be classified (OpaqueContent, ClauseFragment)",
          "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"
          ]
        }
      ]
    },
    "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"
          ]
        }
      ]
    }
  },
  "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)"
    },
    "inputs": {
      "$ref": "#/definitions/DecisionInputs"
    },
    "outcome": {
      "$ref": "#/definitions/DecisionOutcome"
    },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    }
  }
}