{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://heartcortex.ai/schemas/1.0/brain-lease.schema.json",
  "title": "brain lease",
  "description": "A brain lease (API Standard 7.4, decision D36): the Command Center's signed statement that a system may consult the named models for the named uses until expiresAt. A system consults a brain only while it holds an unexpired lease it has checked. It never extends a lease by itself. The Command Center pulls the switch by not renewing.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "lease",
    "signature"
  ],
  "properties": {
    "lease": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "system",
        "lease",
        "models",
        "uses",
        "issuedAt",
        "expiresAt"
      ],
      "properties": {
        "system": {
          "$ref": "common.schema.json#/$defs/systemId",
          "description": "The one system this lease is for."
        },
        "lease": {
          "$ref": "common.schema.json#/$defs/uuid",
          "description": "The lease ID. A renewal has a new ID."
        },
        "models": {
          "type": "array",
          "minItems": 1,
          "maxItems": 16,
          "items": {
            "$ref": "common.schema.json#/$defs/brainModel"
          },
          "description": "The only models it may consult, each with its exact version."
        },
        "uses": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "$ref": "common.schema.json#/$defs/brainUse"
          }
        },
        "issuedAt": {
          "$ref": "common.schema.json#/$defs/timestamp"
        },
        "expiresAt": {
          "$ref": "common.schema.json#/$defs/timestamp",
          "description": "At most card.brain.maxLeaseSec (default 300) after issuedAt. The device counts the lease's length on its own monotonic clock from when it received it, so a wrong wall clock can only shorten a lease."
        },
        "restore": {
          "type": "boolean",
          "default": false,
          "description": "true on the first lease after a cut. A system with brain.restoreNeedsOwner accepts it only after its owner approved POST /heart/v1/brain/restore."
        },
        "countersign": {
          "type": "object",
          "description": "Per use: answer (the Command Center checks and signs each answer, so a cut takes effect at the next answer) or lease (a local model's answers are used without a round trip while the lease lasts). Default: answer for propose and plan, lease for the others. A cloud model's answers are always signed one by one.",
          "propertyNames": {
            "$ref": "common.schema.json#/$defs/brainUse"
          },
          "additionalProperties": {
            "enum": [
              "answer",
              "lease"
            ]
          }
        },
        "offline": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "maxSec",
            "uses"
          ],
          "description": "Auto mode (D36): what a local model may still do after the link to the Command Center is lost. Used only if the owner turned auto mode on (PUT /heart/v1/brain/offline), only after the link is lost, and only for maxSec counted from the loss. Never longer than card.brain.offline.maxSec. The first contact after the link returns ends it: the system renews before it consults the brain again.",
          "properties": {
            "maxSec": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2592000
            },
            "uses": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "common.schema.json#/$defs/brainUse"
              },
              "description": "At most the lease's uses. Answers are used without countersigning."
            },
            "stepDown": {
              "type": "array",
              "maxItems": 8,
              "description": "The uses narrow with time offline: from afterSec on, only these. Each step's uses are within the one before; after the last step, or maxSec, the system is brainless.",
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "afterSec",
                  "uses"
                ],
                "properties": {
                  "afterSec": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "uses": {
                    "type": "array",
                    "uniqueItems": true,
                    "items": {
                      "$ref": "common.schema.json#/$defs/brainUse"
                    }
                  }
                }
              }
            },
            "envelope": {
              "type": "string",
              "pattern": "^[a-z0-9][a-z0-9-]*$",
              "description": "The name of the tighter offline envelopes the Core applies to offline Proposals (card limits, Part 8 profile). hazardous targets (D33) are never proposed offline."
            }
          }
        }
      }
    },
    "signature": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{86}$",
      "description": "base64url Ed25519 signature over the RFC 8785 JSON of lease, with the Command Center key the system pinned."
    }
  }
}
