{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://federal.ai/docs/evidence-ledger.schema.json",
  "title": "Federal AI Evidence Ledger Event",
  "description": "Reference schema for one append-only evidence ledger event, v1.0 (August 2026). Every consequential step in a governed AI workflow — assignment, ingest, model call, recommendation, hold, approval, release, rollback — is recorded as one event conforming to this schema. Events are hash-chained: each event's ledger.prev_digest equals the previous event's ledger.digest, so removal or reordering is detectable. Published by Federal AI, free to reference with attribution. Cleared FDE™ is a trademark of Federal AI; U.S. trademark application pending.",
  "type": "object",
  "required": ["ledger", "event", "actor", "authority"],
  "additionalProperties": false,
  "properties": {
    "ledger": {
      "type": "object",
      "description": "Chain bookkeeping. Append-only; digests bind each event to its predecessor.",
      "required": ["chain_id", "seq", "prev_digest", "digest", "recorded_at", "hash_alg"],
      "additionalProperties": false,
      "properties": {
        "chain_id": { "type": "string", "description": "Identifier of the ledger chain, typically one per workflow deployment." },
        "seq": { "type": "integer", "minimum": 1, "description": "1-based position in the chain. Strictly increasing, no gaps." },
        "prev_digest": { "type": "string", "description": "Digest of the previous event's canonical form. For seq 1, the literal string \"genesis\".", "pattern": "^(genesis|[a-f0-9]{64})$" },
        "digest": { "type": "string", "description": "Digest of this event's canonical form, excluding this field.", "pattern": "^[a-f0-9]{64}$" },
        "recorded_at": { "type": "string", "format": "date-time", "description": "UTC timestamp when the event was appended." },
        "hash_alg": { "type": "string", "enum": ["sha-256"], "description": "Digest algorithm. v1.0 fixes sha-256 over RFC 8785 (JCS) canonical JSON." }
      }
    },
    "event": {
      "type": "object",
      "description": "What happened, in the vocabulary of the operating loop (Assign → Ingest → Reconcile → Hold → Release).",
      "required": ["type", "workflow_id", "summary"],
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "enum": ["assignment", "ingest", "reconcile", "model_call", "recommendation", "hold", "approval", "denial", "release", "rollback", "config_change", "integrity_check"],
          "description": "Event kind. Consequential actions (release, config_change, rollback) MUST be preceded in the chain by a matching approval event."
        },
        "workflow_id": { "type": "string", "description": "Stable identifier of the governed workflow this event belongs to." },
        "mission_question": { "type": "string", "description": "The recurring decision this workflow answers, stated in the mission owner's words. Recommended on assignment events; inherited otherwise." },
        "summary": { "type": "string", "maxLength": 500, "description": "One-sentence human-readable description of the event." }
      }
    },
    "actor": {
      "type": "object",
      "description": "Who (or what) performed the step. 'Who asked' is the actor of the originating assignment or command event.",
      "required": ["kind", "id"],
      "additionalProperties": false,
      "properties": {
        "kind": { "type": "string", "enum": ["human", "service", "model"], "description": "Humans approve; services and models never approve their own actions." },
        "id": { "type": "string", "description": "Stable identity from the customer's identity provider (human, service account, or model route id). Never a shared account." },
        "display_name": { "type": "string", "description": "Human-readable name for review boards and audits." },
        "on_behalf_of": { "type": "string", "description": "For service or model actors: the human or assignment event id under whose authority the action runs." }
      }
    },
    "authority": {
      "type": "object",
      "description": "The permission under which the step ran. 'Who approved' is answerable from approval_ref for every consequential event.",
      "required": ["scope"],
      "additionalProperties": false,
      "properties": {
        "scope": { "type": "string", "enum": ["read", "recommend", "write"], "description": "Maximum effect of this event. Write scope requires approval_ref." },
        "basis": { "type": "string", "description": "The named authority: contract clause, mission-owner role, or standing rule that permits this action." },
        "approval_ref": { "type": "string", "description": "Chain reference (chain_id#seq) of the approval event authorizing this action. REQUIRED when scope is 'write'." },
        "fail_state": { "type": "string", "enum": ["closed"], "description": "v1.0 admits only fail-closed workflows: on any authority ambiguity, the action holds." }
      }
    },
    "inputs": {
      "type": "array",
      "description": "Source records this event consumed. 'What changed' is reconstructed by diffing outputs against inputs across the chain.",
      "items": {
        "type": "object",
        "required": ["system", "record_ref", "digest"],
        "additionalProperties": false,
        "properties": {
          "system": { "type": "string", "description": "The authoritative system of record, by its deployment-map name (e.g., maintenance data system, flight scheduling system, supply records)." },
          "record_ref": { "type": "string", "description": "Reference to the source record inside that system. A pointer, never a copy of controlled data." },
          "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "Digest of the record content as read, for tamper-evidence and staleness checks." },
          "age_seconds": { "type": "integer", "minimum": 0, "description": "Age of the record at read time. Workflows declare a maximum acceptable age per source." }
        }
      }
    },
    "outputs": {
      "type": "array",
      "description": "Artifacts this event produced (a recommendation, a published plan, a config revision).",
      "items": {
        "type": "object",
        "required": ["kind", "digest"],
        "additionalProperties": false,
        "properties": {
          "kind": { "type": "string", "description": "Artifact kind, e.g. recommendation, report, plan, config_revision." },
          "digest": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "Digest of the artifact's canonical form." },
          "location_ref": { "type": "string", "description": "Where the artifact is stored, as a reference resolvable inside the customer environment." }
        }
      }
    },
    "model": {
      "type": "object",
      "description": "Present on model_call events: which route produced the answer, and against which evaluation baseline.",
      "required": ["route", "model_id"],
      "additionalProperties": false,
      "properties": {
        "route": { "type": "string", "description": "Deployment-profile route name (e.g., local-primary, local-alternate)." },
        "model_id": { "type": "string", "description": "The approved model identifier as recorded in the customer's approval documentation." },
        "params_digest": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "Digest of the full generation parameters, so the call is reproducible." },
        "eval_ref": { "type": "string", "description": "Reference to the evaluation case set this model version passed before release." }
      }
    }
  }
}
