{
  "$defs": {
    "ArchiveService": {
      "additionalProperties": false,
      "description": "The archive (adds the snapshot directory and the log anchor).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "dev_seed": {
          "default": null,
          "description": "The development seed fixture.",
          "type": [
            "string",
            "null"
          ]
        },
        "log_timeout_ms": {
          "default": null,
          "description": "The log anchor timeout, milliseconds.",
          "format": "uint64",
          "minimum": 0,
          "type": [
            "integer",
            "null"
          ]
        },
        "log_token": {
          "default": null,
          "description": "The log's bearer token when the log is guarded.",
          "type": [
            "string",
            "null"
          ]
        },
        "log_url": {
          "default": null,
          "description": "The transparency log to anchor snapshots to.",
          "type": [
            "string",
            "null"
          ]
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "sign_seed": {
          "default": null,
          "description": "The snapshot signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "snapshot_dir": {
          "default": null,
          "description": "The snapshots directory.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "Branding": {
      "additionalProperties": false,
      "description": "The whitelabel surface.",
      "properties": {
        "footer": {
          "$ref": "#/$defs/Footer",
          "default": {
            "contact_url": null,
            "legal_url": null
          },
          "description": "Footer links."
        },
        "locale": {
          "default": "en",
          "description": "The console chrome's language (the whitelabel surface speaks\nthe tenant's language; adding one is a table entry in the\nconsole's i18n module, not a code change).",
          "type": "string"
        },
        "logo": {
          "default": null,
          "description": "A logo the console/explorer serve (path or data URI).",
          "type": [
            "string",
            "null"
          ]
        },
        "organization": {
          "default": "UniDPP",
          "description": "The operating organization's legal/display name.",
          "type": "string"
        },
        "product_name": {
          "default": "UniDPP Platform",
          "description": "The product name shown in chrome (login, titles, footers).",
          "type": "string"
        },
        "theme": {
          "$ref": "#/$defs/Theme",
          "default": {
            "accent": "#08bdba",
            "primary": "#0f62fe"
          },
          "description": "The theme (hex colors; validated)."
        }
      },
      "type": "object"
    },
    "ConsoleService": {
      "additionalProperties": false,
      "description": "The console (adds the manifest path it loads).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "manifest": {
          "default": null,
          "description": "The operator manifest the console loads and edits.",
          "type": [
            "string",
            "null"
          ]
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "Deployment": {
      "additionalProperties": false,
      "description": "The deployment identity and shape.",
      "properties": {
        "base_url": {
          "description": "The public base URL of the deployment's primary surface.",
          "type": "string"
        },
        "name": {
          "description": "The deployment's name (tenant name; unique per operator).",
          "type": "string"
        },
        "profile": {
          "$ref": "#/$defs/Profile",
          "description": "`reference` (the public one), `whitelabel` (an org's own), or\n`sovereign` (on-prem, jurisdiction-pinned)."
        }
      },
      "required": [
        "name",
        "profile",
        "base_url"
      ],
      "type": "object"
    },
    "EgressPolicy": {
      "description": "The egress policy.",
      "oneOf": [
        {
          "const": "none",
          "description": "Nothing leaves the box.",
          "type": "string"
        },
        {
          "const": "tsa-only",
          "description": "Only the RFC 3161 TSA submission.",
          "type": "string"
        },
        {
          "const": "external",
          "description": "Upstream fetches permitted (the reference deployment).",
          "type": "string"
        }
      ]
    },
    "Features": {
      "additionalProperties": false,
      "description": "Cross-cutting toggles (absent = the documented default).",
      "properties": {
        "cddal_negotiation": {
          "default": true,
          "description": "Serve the CDDAL dictionary form on content negotiation\n(default true).",
          "type": "boolean"
        },
        "presentation_render": {
          "default": true,
          "description": "Serve the presentation render on the projector (default true).",
          "type": "boolean"
        },
        "untp_ingest": {
          "default": true,
          "description": "Accept UNTP ingest on the gateway (default true).",
          "type": "boolean"
        }
      },
      "type": "object"
    },
    "FeedbackPolicy": {
      "additionalProperties": false,
      "description": "The consumer-report channel's deployment policy.",
      "properties": {
        "journal": {
          "default": null,
          "description": "Append-only JSONL journal path (absent = in-memory only).",
          "type": [
            "string",
            "null"
          ]
        },
        "rate_per_minute": {
          "default": 0,
          "description": "Per-identifier reports per minute (0 = permissive).",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "Footer": {
      "additionalProperties": false,
      "description": "Footer links (legal, contact).",
      "properties": {
        "contact_url": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "legal_url": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "type": "object"
    },
    "GatewayService": {
      "additionalProperties": false,
      "description": "The gateway (adds the upstream).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "feedback": {
          "$ref": "#/$defs/FeedbackPolicy",
          "default": {
            "journal": null,
            "rate_per_minute": 0
          },
          "description": "The consumer-report channel's knobs (TODO.impl 224): the\njournal path and the per-identifier rate window (absent/0 =\npermissive)."
        },
        "issuer_url": {
          "default": null,
          "description": "The issuer upstream whose passports the gateway renders.",
          "type": [
            "string",
            "null"
          ]
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "scan_policy": {
          "anyOf": [
            {
              "$ref": "#/$defs/ScanPolicy"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The scan-token policy (TODO.impl 224): short-TTL bearer scan\ntokens with issuance throttling, enforced at this edge tier.\nAbsent = open (public resolution is the default doctrine);\ndeployments under load opt in."
        },
        "timeout_ms": {
          "default": null,
          "description": "The upstream request timeout, milliseconds.",
          "format": "uint64",
          "minimum": 0,
          "type": [
            "integer",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "HubService": {
      "additionalProperties": false,
      "description": "The translation hub: a stateless signed relay whose only real\nknobs are its identity and its relay-signing seed. No state file\n(after a relay the hub holds nothing); no admin surface (no\nmutations to gate).",
      "properties": {
        "admin_token": {
          "default": null,
          "description": "Future-proof: the hub has no mutations to gate today.",
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "description": "`host:port` to bind.",
          "type": "string"
        },
        "hub_id": {
          "default": "unidpp-hub-1",
          "description": "The hub's trust-graph node id (what relay signatures name).",
          "type": "string"
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "seed": {
          "default": null,
          "description": "The relay-signing seed (an `${VAR}` reference in production;\nabsent = seeded-dev mode, which says so on every start).",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "IssuerService": {
      "additionalProperties": false,
      "description": "The issuer (adds the pack-suite policy).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "event_seed": {
          "default": null,
          "description": "The event-log signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "max_age": {
          "default": null,
          "description": "The maximum age of accepted upstream material, seconds.",
          "format": "uint64",
          "minimum": 0,
          "type": [
            "integer",
            "null"
          ]
        },
        "pack_seed": {
          "default": null,
          "description": "The pack signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "pack_suites": {
          "additionalProperties": false,
          "default": [
            "ecdsa-p256"
          ],
          "description": "The sovereign pack-signing policy: one suite or the\nco-signature set (e.g. `[\"ecdsa-p256\", \"sm2\"]`).",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "registry_token": {
          "default": null,
          "description": "The registry bearer token when the registry is guarded.",
          "type": [
            "string",
            "null"
          ]
        },
        "registry_url": {
          "default": null,
          "description": "The registry to forward registrations to.",
          "type": [
            "string",
            "null"
          ]
        },
        "seed": {
          "default": null,
          "description": "The service's general development seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "LogService": {
      "additionalProperties": false,
      "description": "The transparency log (adds the external anchor knob).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "external_tsa_url": {
          "default": null,
          "description": "RFC 3161 TSA endpoint; absent = no external anchoring.",
          "type": [
            "string",
            "null"
          ]
        },
        "log_id": {
          "default": "unidpp-log-1",
          "description": "The log's identity.",
          "type": "string"
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "seed": {
          "default": null,
          "description": "The tree-head signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "suite": {
          "default": null,
          "description": "The signature suite of the tree head (default ed25519).",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "Profile": {
      "description": "Deployment profiles.",
      "oneOf": [
        {
          "const": "reference",
          "description": "The hosted reference deployment.",
          "type": "string"
        },
        {
          "const": "whitelabel",
          "description": "An organization's own branded instance.",
          "type": "string"
        },
        {
          "const": "sovereign",
          "description": "On-prem, jurisdiction-pinned, external calls off.",
          "type": "string"
        }
      ]
    },
    "ProjectorService": {
      "additionalProperties": false,
      "description": "The projector (adds the resolution sources and the roll-up sealer).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "passports_dir": {
          "default": null,
          "description": "The pinned passports directory (absent = the built-in fixture).",
          "type": [
            "string",
            "null"
          ]
        },
        "primmel_dir": {
          "default": null,
          "description": "The pinned Primmel package directory.",
          "type": [
            "string",
            "null"
          ]
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "registry_token": {
          "default": null,
          "description": "The registry bearer token when the registry is guarded.",
          "type": [
            "string",
            "null"
          ]
        },
        "registry_url": {
          "default": null,
          "description": "The registry the lenses resolve against (absent = fixtures).",
          "type": [
            "string",
            "null"
          ]
        },
        "rollup_attester": {
          "default": null,
          "description": "The roll-up attester identity.",
          "type": [
            "string",
            "null"
          ]
        },
        "rollup_seed": {
          "default": null,
          "description": "The roll-up sealing seed (absent = roll-ups off).",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "RegistryService": {
      "additionalProperties": false,
      "description": "The registry (adds the seed knobs; absent = the service's own\ndefaults).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "seed_express": {
          "default": null,
          "description": "Seed the EXPRESS development corpus at start.",
          "type": [
            "boolean",
            "null"
          ]
        },
        "seed_on_demand": {
          "default": null,
          "description": "Seed the development corpus on demand (`POST /admin/seed`).",
          "type": [
            "boolean",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "ResolverService": {
      "additionalProperties": false,
      "description": "The resolver (the identifier-resolution service; its knobs are\nits own — the binary's env names are the generic UNIDPP_ ones it\nhas always read, unchanged).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "cache_ttl_secs": {
          "default": 300,
          "format": "int64",
          "type": "integer"
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "upstream": {
          "default": null,
          "description": "National-intermediary mode: the upstream resolver base URL.",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    },
    "ScanPolicy": {
      "additionalProperties": false,
      "description": "The scan-token policy (TODO.impl 224): the MobileQR bearer-token\npattern as declared deployment data — never per-service code.",
      "properties": {
        "issue_limit_per_minute": {
          "description": "Tokens issued per source per minute (the throttle).",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "token_ttl_secs": {
          "description": "Token time-to-live, seconds (a scan session's window).",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "token_ttl_secs",
        "issue_limit_per_minute"
      ],
      "type": "object"
    },
    "Services": {
      "additionalProperties": false,
      "description": "Every service block. Absent service = that service is not part of\nthis deployment.",
      "properties": {
        "archive": {
          "anyOf": [
            {
              "$ref": "#/$defs/ArchiveService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "console": {
          "anyOf": [
            {
              "$ref": "#/$defs/ConsoleService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "gateway": {
          "anyOf": [
            {
              "$ref": "#/$defs/GatewayService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "hub": {
          "anyOf": [
            {
              "$ref": "#/$defs/HubService"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The translation hub (stateless signed relay; no state file —\nnothing persists)."
        },
        "issuer": {
          "anyOf": [
            {
              "$ref": "#/$defs/IssuerService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "log": {
          "anyOf": [
            {
              "$ref": "#/$defs/LogService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "projector": {
          "anyOf": [
            {
              "$ref": "#/$defs/ProjectorService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "registry": {
          "anyOf": [
            {
              "$ref": "#/$defs/RegistryService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "resolver": {
          "anyOf": [
            {
              "$ref": "#/$defs/ResolverService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "trust": {
          "anyOf": [
            {
              "$ref": "#/$defs/TrustService"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        }
      },
      "type": "object"
    },
    "Sovereignty": {
      "additionalProperties": false,
      "description": "The sovereignty declaration: what may leave the box.",
      "properties": {
        "data_residency": {
          "default": null,
          "description": "The jurisdiction this deployment pins data to (`EU`, `JP`, ...).",
          "type": [
            "string",
            "null"
          ]
        },
        "egress_override_reason": {
          "default": null,
          "description": "Required when a sovereign profile permits egress: the recorded\nreason (auditable, not silent).",
          "type": [
            "string",
            "null"
          ]
        },
        "external_calls": {
          "$ref": "#/$defs/EgressPolicy",
          "default": "none",
          "description": "The egress policy: `none`, `tsa-only`, or `external`."
        }
      },
      "type": "object"
    },
    "Theme": {
      "additionalProperties": false,
      "description": "Theme colors (six-digit hex, `#`-prefixed).",
      "properties": {
        "accent": {
          "default": "#08bdba",
          "type": "string"
        },
        "primary": {
          "default": "#0f62fe",
          "type": "string"
        }
      },
      "type": "object"
    },
    "TrustService": {
      "additionalProperties": false,
      "description": "The trust service (adds the fixture and signing-seed knobs).",
      "properties": {
        "admin_token": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        },
        "bind": {
          "type": "string"
        },
        "dev_seed": {
          "default": null,
          "description": "The development seed fixture.",
          "type": [
            "string",
            "null"
          ]
        },
        "no_seed_fixtures": {
          "default": null,
          "description": "Run without the seed fixtures (the no-seed posture).",
          "type": [
            "boolean",
            "null"
          ]
        },
        "public_url": {
          "default": null,
          "description": "The service's public URL when a tunnel/ingress fronts it.",
          "type": [
            "string",
            "null"
          ]
        },
        "sign_seed": {
          "default": null,
          "description": "The operator keyring's Ed25519 signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "sign_seed_p256": {
          "default": null,
          "description": "The operator keyring's P-256 signing seed.",
          "type": [
            "string",
            "null"
          ]
        },
        "state_file": {
          "default": null,
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "bind"
      ],
      "type": "object"
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "A complete deployment declaration.",
  "properties": {
    "api_version": {
      "description": "Must equal [`API_VERSION`].",
      "type": "string"
    },
    "branding": {
      "$ref": "#/$defs/Branding",
      "default": {
        "footer": {
          "contact_url": null,
          "legal_url": null
        },
        "locale": "en",
        "logo": null,
        "organization": "UniDPP",
        "product_name": "UniDPP Platform",
        "theme": {
          "accent": "#08bdba",
          "primary": "#0f62fe"
        }
      },
      "description": "The whitelabel surface (organization identity, theme)."
    },
    "deployment": {
      "$ref": "#/$defs/Deployment",
      "description": "Which deployment this names."
    },
    "features": {
      "$ref": "#/$defs/Features",
      "default": {
        "cddal_negotiation": false,
        "presentation_render": false,
        "untp_ingest": false
      },
      "description": "Cross-cutting feature toggles."
    },
    "services": {
      "$ref": "#/$defs/Services",
      "default": {
        "archive": null,
        "console": null,
        "gateway": null,
        "hub": null,
        "issuer": null,
        "log": null,
        "projector": null,
        "registry": null,
        "resolver": null,
        "trust": null
      },
      "description": "Per-service configuration blocks."
    },
    "sovereignty": {
      "$ref": "#/$defs/Sovereignty",
      "default": {
        "data_residency": null,
        "egress_override_reason": null,
        "external_calls": "none"
      },
      "description": "The sovereignty declaration (what may leave the box)."
    }
  },
  "required": [
    "api_version",
    "deployment"
  ],
  "title": "UniDPP operator manifest (unidpp.org/v1)",
  "type": "object"
}
