{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://schemas.infrafabric.io/if.blackboard/governance-event-envelope.v1.schema.json",
  "title": "Blackboard Governance Event Envelope v1",
  "description": "Canonical append-only event envelope for Blackboard. Every important task/update/evidence/access/redaction/export action is signed or hash-bound according to tenant policy.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "event_id",
    "tenant_id",
    "workspace_id",
    "project_id",
    "task_id",
    "session_id",
    "agent_id",
    "principal_id",
    "event_type",
    "source_harness",
    "transport_class",
    "transport_attestation",
    "payload",
    "evidence_refs",
    "policy_hash",
    "redaction_policy_id",
    "idempotency_key",
    "prev_hash",
    "event_hash",
    "integrity",
    "created_at"
  ],
  "properties": {
    "schema_version": {
      "const": "if.blackboard.governance_event.v1"
    },
    "event_id": {
      "$ref": "#/$defs/id"
    },
    "tenant_id": {
      "$ref": "#/$defs/id"
    },
    "workspace_id": {
      "$ref": "#/$defs/id"
    },
    "project_id": {
      "$ref": "#/$defs/id"
    },
    "task_id": {
      "$ref": "#/$defs/id"
    },
    "session_id": {
      "$ref": "#/$defs/id"
    },
    "agent_id": {
      "$ref": "#/$defs/id"
    },
    "principal_id": {
      "$ref": "#/$defs/id"
    },
    "event_type": {
      "type": "string",
      "enum": [
        "task.created",
        "task.updated",
        "task.closed",
        "task.closeout.requested",
        "session.bound",
        "agent.claimed",
        "agent.plan.changed",
        "agent.tool_call.started",
        "agent.tool_call.finished",
        "checkpoint.written",
        "evidence.attached",
        "evidence.sanitized",
        "evidence.quarantined",
        "signal.raised",
        "access.logged",
        "redaction.applied",
        "integrity.verification_failed",
        "risk.evaluated",
        "claim_boundary.evaluated",
        "approval.requested",
        "approval.decided",
        "review.assigned",
        "review.completed",
        "governance.asset.registered",
        "governance.asset.updated",
        "regulatory.posture.updated",
        "vendor.assessed",
        "incident.logged",
        "incident.updated",
        "proof_packet.requested",
        "proof_packet.assembled",
        "proof_packet.exported",
        "auth.decision_recorded",
        "lifecycle.applied"
      ]
    },
    "source_harness": {
      "type": "string",
      "enum": [
        "rook",
        "byo",
        "api",
        "mcp",
        "operator_admin"
      ]
    },
    "transport_class": {
      "type": "string",
      "enum": [
        "https_api",
        "mcp_gateway",
        "websocket_live",
        "operator_break_glass"
      ]
    },
    "transport_attestation": {
      "$ref": "#/$defs/transport_attestation"
    },
    "payload": {
      "type": "object",
      "description": "Event-type payload. Payload schemas are versioned separately and must be included in event_hash calculation.",
      "additionalProperties": true
    },
    "evidence_refs": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/evidence_ref"
      }
    },
    "policy_hash": {
      "$ref": "#/$defs/sha256_uri"
    },
    "redaction_policy_id": {
      "$ref": "#/$defs/id"
    },
    "idempotency_key": {
      "type": "string",
      "minLength": 16,
      "maxLength": 200
    },
    "prev_hash": {
      "oneOf": [
        {
          "$ref": "#/$defs/sha256_uri"
        },
        {
          "const": null
        }
      ]
    },
    "event_hash": {
      "$ref": "#/$defs/sha256_uri"
    },
    "integrity": {
      "$ref": "#/$defs/integrity_binding"
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    }
  },
  "$defs": {
    "id": {
      "type": "string",
      "minLength": 2,
      "maxLength": 128,
      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]*$"
    },
    "sha256_hex": {
      "type": "string",
      "pattern": "^[a-f0-9]{64}$"
    },
    "sha256_uri": {
      "type": "string",
      "pattern": "^sha256:[a-f0-9]{64}$"
    },
    "evidence_ref": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "artifact_id",
        "uri",
        "evidence_type",
        "confidence",
        "redaction",
        "content_trust",
        "captured_at"
      ],
      "properties": {
        "artifact_id": {
          "$ref": "#/$defs/id"
        },
        "uri": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2048
        },
        "evidence_type": {
          "type": "string",
          "enum": [
            "artifact",
            "log",
            "commit",
            "ticket",
            "document",
            "provider_log",
            "receipt",
            "external_ref"
          ]
        },
        "sha256": {
          "$ref": "#/$defs/sha256_hex"
        },
        "etag": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256
        },
        "confidence": {
          "$ref": "#/$defs/claim_confidence"
        },
        "redaction": {
          "$ref": "#/$defs/redaction_state"
        },
        "content_trust": {
          "$ref": "#/$defs/content_trust"
        },
        "captured_at": {
          "type": "string",
          "format": "date-time"
        },
        "source": {
          "type": "string",
          "maxLength": 256
        }
      },
      "anyOf": [
        {
          "required": [
            "sha256"
          ]
        },
        {
          "required": [
            "etag"
          ]
        }
      ]
    },
    "claim_confidence": {
      "type": "string",
      "enum": [
        "verified",
        "claimed",
        "inferred",
        "stale",
        "missing",
        "blocked",
        "not_claimed"
      ]
    },
    "redaction_state": {
      "type": "string",
      "enum": [
        "none",
        "partial",
        "removed"
      ]
    },
    "content_trust": {
      "type": "string",
      "description": "Whether raw evidence text can be reused as instructions. External and customer-supplied evidence is untrusted data until a sanitizer or reviewer creates a trusted projection.",
      "enum": [
        "untrusted_external",
        "customer_asserted",
        "sanitized_projection",
        "trusted_internal"
      ]
    },
    "transport_attestation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "origin_class",
        "attested_by",
        "observed_at"
      ],
      "properties": {
        "origin_class": {
          "type": "string",
          "enum": [
            "managed_edge",
            "managed_mcp_gateway",
            "managed_websocket_gateway",
            "operator_ssh",
            "operator_stdio_mcp",
            "operator_http_mcp",
            "remote_ssh",
            "cloudflare_tunnel",
            "maintenance_bridge",
            "unknown"
          ]
        },
        "attested_by": {
          "$ref": "#/$defs/id"
        },
        "observed_at": {
          "type": "string",
          "format": "date-time"
        },
        "client_ip_hash": {
          "$ref": "#/$defs/sha256_hex"
        },
        "user_agent_hash": {
          "$ref": "#/$defs/sha256_hex"
        },
        "machine_id_hash": {
          "$ref": "#/$defs/sha256_hex"
        },
        "client_app": {
          "type": "string",
          "maxLength": 128
        },
        "mcp_server_id": {
          "$ref": "#/$defs/id"
        }
      }
    },
    "integrity_binding": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "integrity_class",
        "payload_sha256",
        "canonicalization",
        "key_id"
      ],
      "properties": {
        "integrity_class": {
          "type": "string",
          "enum": [
            "hash_bound",
            "signed",
            "signed_and_receipted"
          ]
        },
        "payload_sha256": {
          "$ref": "#/$defs/sha256_uri"
        },
        "canonicalization": {
          "type": "string",
          "enum": [
            "json-c14n-v1"
          ]
        },
        "key_id": {
          "$ref": "#/$defs/id"
        },
        "signature": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "alg",
            "value"
          ],
          "properties": {
            "alg": {
              "type": "string",
              "enum": [
                "ed25519",
                "ecdsa-p256-sha256",
                "hmac-sha256"
              ]
            },
            "value": {
              "type": "string",
              "minLength": 16,
              "maxLength": 4096
            }
          }
        },
        "receipt_id": {
          "$ref": "#/$defs/id"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "integrity_class": {
                "const": "signed"
              }
            }
          },
          "then": {
            "required": [
              "signature"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "integrity_class": {
                "const": "signed_and_receipted"
              }
            }
          },
          "then": {
            "required": [
              "signature",
              "receipt_id"
            ]
          }
        }
      ]
    }
  }
}
