{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/phone-devices.schema.json",
  "title": "Phone device registry",
  "description": "<autopilot root>/phone/devices.json, mode 0600 in a 0700 directory, written only by phone-devices.mjs on this machine. Public keys only: a private key never reaches this file. contract-server.mjs reads it on every phone request, so a revocation or a launch toggle applies to the next request, and a file other users can write is treated as empty. A revoked device stays listed so its id is never reissued and the audit log still resolves.",
  "type": "object",
  "additionalProperties": false,
  "required": ["schemaVersion", "launchEnabled", "devices"],
  "properties": {
    "schemaVersion": { "const": "1.0.0", "x-sensitivity": "none" },
    "launchEnabled": {
      "type": "boolean",
      "description": "POST /v1/phone/launch is refused (launch-disabled) unless this is true, whatever scopes a device holds. Off by default; `phone-devices.mjs launch on|off` sets it.",
      "x-sensitivity": "none"
    },
    "devices": {
      "type": "array",
      "maxItems": 256,
      "x-sensitivity": "none",
      "items": { "$ref": "#/$defs/device" }
    }
  },
  "$defs": {
    "device": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "name", "publicKey", "scopes", "addedAt", "revokedAt"],
      "properties": {
        "id": { "type": "string", "pattern": "^d-[0-9a-f]{16}$", "x-sensitivity": "none" },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64,
          "description": "A label for a person reading `list`; never used for a decision.",
          "x-sensitivity": "local"
        },
        "publicKey": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$",
          "description": "The raw 32-byte Ed25519 public key, unpadded base64url.",
          "x-sensitivity": "local"
        },
        "scopes": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": { "enum": ["read", "answer", "launch"] },
          "description": "read: GET /v1/phone/runs and /v1/phone/runs/{id}. answer: POST /v1/phone/runs/{id}/answer. launch: POST /v1/phone/launch, and only while launchEnabled is true.",
          "x-sensitivity": "none"
        },
        "addedAt": { "type": "string", "format": "date-time", "x-sensitivity": "none" },
        "revokedAt": {
          "type": ["string", "null"],
          "format": "date-time",
          "description": "Set by `phone-devices.mjs revoke`; a revoked device is refused on its next request.",
          "x-sensitivity": "none"
        }
      }
    }
  }
}
