{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://groma.ro/simon-g/method/decision-record-0.1.schema.json",
  "title": "Simon G. decision record",
  "description": "One business decision proposed by a person, an algorithm, an AI model or an agent: its evidence, the limit it was checked against, who signed, and what it was worth afterwards. Version 0.1, draft.",
  "type": "object",
  "required": ["record_id", "schema_version", "class", "charter_version", "subject", "proposer", "proposed", "evidence", "limit_check", "status", "created_at"],
  "additionalProperties": false,
  "properties": {
    "record_id": { "type": "string", "description": "Unique within the company. Never reused." },
    "schema_version": { "const": "0.1" },
    "class": { "type": "string", "description": "The decision class, as named in the charter." },
    "charter_version": { "type": "string", "description": "The version of the charter in force when the proposal was made." },
    "subject": { "type": "object", "description": "What the decision is about, for example a product and a location, a customer, a supplier." },
    "proposer": {
      "type": "object",
      "required": ["kind", "name"],
      "additionalProperties": false,
      "properties": {
        "kind": { "enum": ["person", "algorithm", "ai_model", "agent"] },
        "name": { "type": "string" },
        "version": { "type": "string", "description": "Version of the algorithm or model. Required unless kind is person." }
      }
    },
    "inputs": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "data_as_of": { "type": "string", "format": "date-time" },
        "sources": { "type": "array", "items": { "type": "string" } },
        "absent": {
          "type": "array",
          "description": "Inputs that were missing, and what each absence switched off. Absence is stated, never replaced by a default.",
          "items": {
            "type": "object",
            "required": ["input", "consequence"],
            "properties": { "input": { "type": "string" }, "consequence": { "type": "string" } }
          }
        }
      }
    },
    "current": { "description": "The value in force before the decision. Null when there is none." },
    "proposed": { "description": "The value proposed." },
    "evidence": {
      "type": "object",
      "required": ["reasoning"],
      "additionalProperties": false,
      "properties": {
        "reasoning": { "type": "string", "description": "Why this is proposed, in words a non-specialist can follow." },
        "steps": { "type": "array", "description": "The calculation, step by step, where there is one.", "items": { "type": "object" } },
        "expected_effect": { "$ref": "#/$defs/money_effect" },
        "limits": { "type": "array", "items": { "type": "string" }, "description": "What the proposal does not take into account." }
      }
    },
    "limit_check": {
      "type": "object",
      "required": ["within_limit"],
      "additionalProperties": false,
      "properties": {
        "within_limit": { "type": "boolean" },
        "limit_ref": { "type": "string", "description": "The signed limit that was applied." },
        "acted_alone": { "type": "boolean", "description": "True when the machine applied the decision inside its limit without a person." }
      }
    },
    "status": { "enum": ["proposed", "approved", "rejected", "applied", "verified", "underperforming", "rolled_back", "expired"] },
    "decisions": {
      "type": "array",
      "description": "Every human act on this record, in order. Entries are added, never changed.",
      "items": {
        "type": "object",
        "required": ["actor", "role", "action", "at"],
        "additionalProperties": false,
        "properties": {
          "actor": { "type": "string", "description": "A named person." },
          "role": { "type": "string" },
          "action": { "enum": ["approve", "reject", "apply", "roll_back", "verify", "comment"] },
          "at": { "type": "string", "format": "date-time" },
          "reason": { "type": "string", "description": "Required when the action is reject or roll_back." }
        }
      }
    },
    "baseline": {
      "type": "object",
      "description": "The figure the decision is meant to change, fixed before it is applied.",
      "required": ["metric", "value", "fixed_at"],
      "additionalProperties": false,
      "properties": {
        "metric": { "type": "string" },
        "value": { "type": "number" },
        "unit": { "type": "string" },
        "period": { "type": "string" },
        "fixed_at": { "type": "string", "format": "date-time" }
      }
    },
    "outcome": {
      "type": "object",
      "required": ["verdict", "measured_at"],
      "additionalProperties": false,
      "properties": {
        "verdict": { "enum": ["verified", "underperforming", "not_measurable"] },
        "measured_at": { "type": "string", "format": "date-time" },
        "value": { "type": "number", "description": "The baseline metric, measured the same way after the decision." },
        "measured_effect": { "$ref": "#/$defs/money_effect" },
        "note": { "type": "string" }
      }
    },
    "perimeter": {
      "type": "object",
      "required": ["data_left_perimeter"],
      "additionalProperties": false,
      "properties": {
        "data_left_perimeter": { "type": "boolean" },
        "destination": { "type": "string" },
        "what": { "type": "string" },
        "approved_by": { "type": "string" }
      }
    },
    "previous_record": { "type": "string", "description": "The record this one corrects or replaces." },
    "previous_hash": { "type": "string", "description": "Optional. Hash of the preceding record, so that a removed or altered entry can be detected." },
    "created_at": { "type": "string", "format": "date-time" }
  },
  "$defs": {
    "money_effect": {
      "type": "object",
      "required": ["amount", "currency", "basis"],
      "additionalProperties": false,
      "properties": {
        "amount": { "type": "number" },
        "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
        "per": { "type": "string", "description": "The period the amount refers to, for example year." },
        "basis": { "type": "string", "description": "How the amount was arrived at." }
      }
    }
  }
}
