{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://docs.northset.ai/artifacts/schemas/deployment-manifest-v1.schema.json",
  "title": "Northset public deployment manifest",
  "type": "object",
  "additionalProperties": false,
  "required": ["schema", "version", "chain", "currency", "contracts", "verifierFamilies", "configuration", "observation", "authority"],
  "properties": {
    "schema": { "const": "northset.deploymentManifest.v1" },
    "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
    "chain": {
      "type": "object",
      "additionalProperties": false,
      "required": ["name", "slug", "id"],
      "properties": {
        "name": { "type": "string" },
        "slug": { "type": "string" },
        "id": { "type": "integer", "minimum": 0 }
      }
    },
    "currency": {
      "type": "object",
      "additionalProperties": false,
      "required": ["symbol", "decimals", "address"],
      "properties": {
        "symbol": { "const": "USDC" },
        "decimals": { "const": 6 },
        "address": { "$ref": "#/$defs/address" }
      }
    },
    "contracts": {
      "type": "object",
      "additionalProperties": false,
      "required": ["hub", "verifierRegistry"],
      "properties": {
        "hub": { "$ref": "#/$defs/contract" },
        "verifierRegistry": { "$ref": "#/$defs/contract" }
      }
    },
    "verifierFamilies": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "verifierId", "publicValuesBytes", "wrapper", "active", "cryptographicFreshnessBinding"],
        "allOf": [
          {
            "if": {
              "properties": { "name": { "const": "STATS_V1" } },
              "required": ["name"]
            },
            "then": { "required": ["programKey"] }
          }
        ],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "verifierId": { "$ref": "#/$defs/bytes32" },
          "programKey": { "$ref": "#/$defs/bytes32" },
          "publicValuesBytes": { "type": "integer", "minimum": 96 },
          "wrapper": { "$ref": "#/$defs/contract" },
          "active": { "type": "boolean" },
          "cryptographicFreshnessBinding": { "type": ["boolean", "null"] }
        }
      }
    },
    "configuration": {
      "type": "object",
      "additionalProperties": false,
      "required": ["paused", "globalFeeBps", "globalMinBondUSDC"],
      "properties": {
        "paused": { "type": "boolean" },
        "globalFeeBps": { "type": "integer", "minimum": 0, "maximum": 2000 },
        "globalMinBondUSDC": { "$ref": "#/$defs/positiveUint256String" }
      }
    },
    "observation": {
      "type": "object",
      "additionalProperties": false,
      "required": ["blockNumber", "timestamp"],
      "properties": {
        "blockNumber": { "type": "integer", "minimum": 0 },
        "timestamp": { "type": "string", "format": "date-time" }
      }
    },
    "authority": {
      "type": "object",
      "additionalProperties": false,
      "required": ["settlementAuthority", "directRpcWinsOnConflict"],
      "properties": {
        "settlementAuthority": { "const": false },
        "directRpcWinsOnConflict": { "const": true }
      }
    }
  },
  "$defs": {
    "address": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
    "bytes32": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" },
    "uint256String": { "type": "string", "pattern": "^(?:0|[1-9][0-9]{0,76}|1(?:0[0-9]{76}|1(?:[0-4][0-9]{75}|5(?:[0-6][0-9]{74}|7(?:[0-8][0-9]{73}|9(?:[0-1][0-9]{72}|20(?:[0-7][0-9]{70}|8(?:[0-8][0-9]{69}|9(?:[0-1][0-9]{68}|2(?:[0-2][0-9]{67}|3(?:[0-6][0-9]{66}|7(?:[0-2][0-9]{65}|3(?:0[0-9]{64}|1(?:[0-5][0-9]{63}|6(?:0[0-9]{62}|1(?:[0-8][0-9]{61}|9(?:[0-4][0-9]{60}|5(?:[0-3][0-9]{59}|4(?:[0-1][0-9]{58}|2(?:[0-2][0-9]{57}|3(?:[0-4][0-9]{56}|5(?:[0-6][0-9]{55}|70(?:[0-8][0-9]{53}|9(?:[0-7][0-9]{52}|8(?:[0-4][0-9]{51}|500(?:[0-7][0-9]{48}|8(?:[0-5][0-9]{47}|6(?:[0-7][0-9]{46}|8(?:[0-6][0-9]{45}|7(?:[0-8][0-9]{44}|90(?:[0-6][0-9]{42}|7(?:[0-7][0-9]{41}|8(?:[0-4][0-9]{40}|5(?:[0-2][0-9]{39}|3(?:[0-1][0-9]{38}|2(?:[0-5][0-9]{37}|6(?:[0-8][0-9]{36}|9(?:[0-8][0-9]{35}|9(?:[0-7][0-9]{34}|8(?:[0-3][0-9]{33}|4(?:[0-5][0-9]{32}|6(?:[0-5][0-9]{31}|6(?:[0-4][0-9]{30}|5(?:[0-5][0-9]{29}|6(?:[0-3][0-9]{28}|40(?:[0-4][0-9]{26}|5(?:[0-5][0-9]{25}|6(?:[0-3][0-9]{24}|40(?:[0-2][0-9]{22}|3(?:[0-8][0-9]{21}|9(?:[0-3][0-9]{20}|4(?:[0-4][0-9]{19}|5(?:[0-6][0-9]{18}|7(?:[0-4][0-9]{17}|5(?:[0-7][0-9]{16}|8(?:[0-3][0-9]{15}|400(?:[0-6][0-9]{12}|7(?:[0-8][0-9]{11}|9(?:0[0-9]{10}|1(?:[0-2][0-9]{9}|3(?:0[0-9]{8}|1(?:[0-1][0-9]{7}|2(?:[0-8][0-9]{6}|9(?:[0-5][0-9]{5}|6(?:[0-2][0-9]{4}|3(?:[0-8][0-9]{3}|9(?:[0-8][0-9]{2}|9(?:[0-2][0-9]{1}|3(?:[0-4]|5)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))$", "maxLength": 78 },
    "positiveUint256String": {
      "allOf": [
        { "$ref": "#/$defs/uint256String" },
        { "not": { "const": "0" } }
      ]
    },
    "deployment": {
      "type": "object",
      "additionalProperties": false,
      "required": ["transactionHash", "blockNumber"],
      "properties": {
        "transactionHash": { "$ref": "#/$defs/bytes32" },
        "blockNumber": { "type": "integer", "minimum": 0 }
      }
    },
    "contract": {
      "type": "object",
      "additionalProperties": false,
      "required": ["address", "codehash", "deployment"],
      "properties": {
        "address": { "$ref": "#/$defs/address" },
        "codehash": { "$ref": "#/$defs/bytes32" },
        "deployment": { "$ref": "#/$defs/deployment" },
        "abi": { "type": "string", "pattern": "^/artifacts/abi/[a-z0-9-]+\\.json$" }
      }
    }
  }
}
