{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://heartcortex.ai/schemas/1.0/card.schema.json",
  "title": "HEART Card",
  "type": "object",
  "required": [
    "system",
    "level",
    "bindings",
    "pulse"
  ],
  "properties": {
    "system": {
      "$ref": "common.schema.json#/$defs/system",
      "x-heart-privacy": "public"
    },
    "level": {
      "enum": [
        "basic",
        "connected",
        "full"
      ],
      "x-heart-privacy": "public"
    },
    "heartVersion": {
      "type": "string",
      "x-heart-privacy": "public"
    },
    "bindings": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "enum": [
          "http-server",
          "http-push",
          "unix-socket",
          "mqtt",
          "in-process"
        ]
      },
      "x-heart-privacy": "public"
    },
    "endpoints": {
      "type": "object",
      "x-heart-privacy": "public",
      "properties": {
        "api": {
          "type": "string",
          "format": "uri"
        },
        "gateway": {
          "description": "heart:// or https address of the system at its HEART Gateway.",
          "type": "string",
          "format": "uri"
        },
        "socket": {
          "description": "Local Unix socket path.",
          "type": "string",
          "pattern": "^/",
          "x-heart-privacy": "internal"
        },
        "mqtt": {
          "type": "string",
          "format": "uri"
        },
        "mcp": {
          "type": "string",
          "format": "uri"
        },
        "a2a": {
          "type": "string",
          "format": "uri"
        },
        "otlp": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "pulse": {
      "type": "object",
      "required": [
        "intervalSec"
      ],
      "x-heart-privacy": "public",
      "properties": {
        "intervalSec": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "capabilities": {
      "description": "Filtered per element: a caller sees a capability only if its clearance covers the capability's privacy level.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/capability"
      },
      "x-heart-privacy": "public"
    },
    "shares": {
      "description": "Minimum clearance needed to read each stream. Keys are message types without their heart. prefix, such as pulse or rhythm. never-share is not a valid value: no clearance reaches it, so such a stream is simply not offered. A stream at public still returns only the public view of each message.",
      "type": "object",
      "x-heart-privacy": "public",
      "additionalProperties": {
        "$ref": "common.schema.json#/$defs/messageLevel"
      },
      "propertyNames": {
        "enum": [
          "card",
          "pulse",
          "rhythm",
          "arrhythmia",
          "action",
          "receipt",
          "evolution",
          "component",
          "property",
          "config",
          "metric",
          "log",
          "diagnostic",
          "lifecycle",
          "software",
          "update",
          "artifact",
          "schedule",
          "control",
          "rule",
          "consent",
          "policy",
          "aipolicy",
          "memory",
          "lesson",
          "audit",
          "security",
          "platform",
          "peer",
          "fleet",
          "custom",
          "core",
          "proposal",
          "trial"
        ]
      }
    },
    "valve": {
      "type": "object",
      "x-heart-privacy": "public",
      "properties": {
        "llmCeiling": {
          "description": "Highest level that may reach any model provider.",
          "$ref": "common.schema.json#/$defs/messageLevel"
        },
        "classifications": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/classification"
          }
        }
      }
    },
    "ai": {
      "type": "object",
      "x-heart-privacy": "public",
      "properties": {
        "modes": {
          "type": "array",
          "items": {
            "enum": [
              "byok",
              "org-proxy"
            ]
          }
        },
        "providers": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "offline": {
          "enum": [
            "rules-only",
            "local-model"
          ]
        }
      }
    },
    "auth": {
      "type": "object",
      "x-heart-privacy": "public",
      "properties": {
        "issuer": {
          "type": "string",
          "format": "uri"
        },
        "jwksUri": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "identity": {
      "description": "The system's identity key, which signs the Card (Heart-Card-Signature header) and its TLS certificate (API Standard 10.1).",
      "type": "object",
      "x-heart-privacy": "public",
      "required": [
        "kid",
        "thumbprint"
      ],
      "properties": {
        "kid": {
          "type": "string",
          "maxLength": 200
        },
        "thumbprint": {
          "description": "JWK SHA-256 thumbprint (RFC 7638), base64url.",
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$"
        },
        "certificates": {
          "description": "Where to fetch the certificate chain.",
          "type": "string",
          "format": "uri"
        }
      }
    },
    "modules": {
      "description": "Optional modules this system implements.",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "$ref": "common.schema.json#/$defs/module"
      },
      "x-heart-privacy": "public"
    },
    "profiles": {
      "description": "Standard or reverse-DNS device profiles.",
      "type": "array",
      "items": {
        "type": "string"
      },
      "x-heart-privacy": "public"
    },
    "autonomy": {
      "description": "Promised Autonomy Level and scope (Part 2).",
      "type": "object",
      "x-heart-privacy": "public",
      "required": [
        "level"
      ],
      "properties": {
        "level": {
          "description": "Headline level, reached everywhere.",
          "type": "integer",
          "minimum": 1,
          "maximum": 5
        },
        "higher": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "level",
              "areas"
            ],
            "properties": {
              "level": {
                "type": "integer",
                "minimum": 2,
                "maximum": 5
              },
              "areas": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "$ref": "common.schema.json#/$defs/area"
                }
              }
            }
          }
        }
      }
    },
    "template": {
      "description": "The HEART template this system was built from, such as heart/embeddedstandard/rust/v1.2611.",
      "type": "string",
      "pattern": "^heart/embeddedstandard/[a-z0-9-]+/v[0-9]+\\.[0-9]+(\\.[0-9]+)?$",
      "x-heart-privacy": "public"
    },
    "labels": {
      "description": "Used by fleet selectors.",
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "x-heart-privacy": "internal"
    },
    "events": {
      "description": "Rhythm event names this system can emit beyond the standard ones.",
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "severity": {
            "$ref": "common.schema.json#/$defs/severity"
          }
        }
      },
      "x-heart-privacy": "public"
    },
    "limits": {
      "description": "For constrained systems.",
      "type": "object",
      "properties": {
        "maxBodyBytes": {
          "type": "integer",
          "minimum": 0
        },
        "maxBatch": {
          "type": "integer",
          "minimum": 0
        },
        "maxPageSize": {
          "type": "integer",
          "minimum": 0
        },
        "maxMaintenanceSec": {
          "type": "integer",
          "minimum": 60,
          "description": "Longest maintenance-on this system accepts. Default 86400."
        },
        "brainRefusalsPerHour": {
          "type": "integer",
          "minimum": 1,
          "description": "Proposals the gate may refuse in one hour before the Core cuts its own brain (API Standard 7.4 rule 11). Default 10."
        }
      },
      "x-heart-privacy": "public"
    },
    "core": {
      "type": "object",
      "required": [
        "class"
      ],
      "x-heart-privacy": "public",
      "properties": {
        "class": {
          "enum": [
            "core-s",
            "core-m",
            "core-l"
          ]
        },
        "tiers": {
          "type": "array",
          "items": {
            "$ref": "common.schema.json#/$defs/tier"
          }
        },
        "languages": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "lifecycle": {
      "type": "object",
      "x-heart-privacy": "internal",
      "description": "Module lifecycle (API Standard 13.2 rule 3).",
      "properties": {
        "operations": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "anyOf": [
              {
                "enum": [
                  "restart",
                  "shutdown",
                  "sleep",
                  "wake",
                  "drain",
                  "reload",
                  "power-cycle",
                  "safe-mode",
                  "maintenance-on",
                  "maintenance-off",
                  "reset-config",
                  "reset-network",
                  "clear-data",
                  "factory-reset",
                  "decommission"
                ]
              },
              {
                "type": "string",
                "pattern": "^x-[a-z0-9][a-z0-9-]*$"
              }
            ]
          },
          "description": "The lifecycle operations this system offers. Others answer 501 not-implemented."
        },
        "wakeSources": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "enum": [
              "timer",
              "button",
              "local",
              "wake-on-lan",
              "mqtt",
              "radio-pass",
              "none"
            ]
          },
          "description": "What can wake this system from sleep or shutdown. wake is offered only if one of these can reach a sleeping system. With none or only local, a remote shutdown is destructive."
        }
      }
    },
    "brain": {
      "type": "object",
      "x-heart-privacy": "internal",
      "description": "Module brain (API Standard 7.4, D36). Required at Autonomy Level 3 and above for a system with a brain.",
      "additionalProperties": false,
      "required": [
        "commandCenter"
      ],
      "properties": {
        "commandCenter": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "url",
            "key"
          ],
          "properties": {
            "url": {
              "type": "string",
              "format": "uri",
              "pattern": "^(https://|http://127\\.0\\.0\\.1(:[0-9]+)?(/|$))",
              "description": "The one Command Center this system trusts, pinned at registration. https only; plain http only to 127.0.0.1, for local tests."
            },
            "key": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{43}$",
              "description": "Its Ed25519 public key, base64url."
            }
          }
        },
        "restoreNeedsOwner": {
          "type": "boolean",
          "description": "true (the default for systems with any physical capability): after a cut (a brain-off or revoking signal, or the system's own self-cut, not a lease that merely ran out), a new lease is accepted only once its owner approved POST /heart/v1/brain/restore with proof of presence."
        },
        "maxLeaseSec": {
          "type": "integer",
          "minimum": 5,
          "maximum": 2592000,
          "description": "Longest lease it accepts. Default 300. A profile may set more, such as days for a rover with an onboard model (Part 8)."
        },
        "offline": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "maxSec"
          ],
          "description": "Auto mode limits. Without this, or with maxSec 0, the system has no auto mode.",
          "properties": {
            "maxSec": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2592000,
              "description": "Longest time a local model may be used with the link lost. At most what the system's Part 8 profile allows, such as minutes for a road vehicle, a shift for a mine truck, days for a rover. 0 for a profile that states no cap."
            }
          }
        }
      }
    },
    "presence": {
      "type": "object",
      "x-heart-privacy": "internal",
      "additionalProperties": false,
      "description": "Module presence (API Standard 13.2, rule 13): how people prove presence to this system.",
      "properties": {
        "methods": {
          "description": "The methods this system verifies. Enrolling any other answers 501 not-implemented.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "enum": [
              "webauthn",
              "ciba",
              "remote-site",
              "device-button"
            ]
          }
        },
        "rpId": {
          "description": "The WebAuthn relying party ID passkeys are registered for, such as ac-unit.example.com.",
          "type": "string",
          "maxLength": 253
        },
        "requireMethod": {
          "description": "true if this system has no other way for a person to prove presence (no button, no local interface), so its last enrolled method cannot be removed. Default false.",
          "type": "boolean",
          "default": false
        }
      }
    },
    "ext": {
      "$ref": "common.schema.json#/$defs/ext",
      "x-heart-privacy": "private"
    }
  },
  "$defs": {
    "capability": {
      "type": "object",
      "required": [
        "name",
        "description",
        "inputSchema",
        "risk",
        "privacy"
      ],
      "properties": {
        "name": {
          "$ref": "common.schema.json#/$defs/capabilityName"
        },
        "title": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "inputSchema": {
          "type": "object"
        },
        "outputSchema": {
          "type": "object"
        },
        "risk": {
          "$ref": "common.schema.json#/$defs/risk"
        },
        "privacy": {
          "description": "Level of the capability's results. Callers need this clearance to see or invoke it.",
          "$ref": "common.schema.json#/$defs/messageLevel"
        },
        "idempotent": {
          "type": "boolean"
        },
        "reversible": {
          "type": "boolean"
        },
        "callers": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "enum": [
              "human",
              "peer",
              "ai",
              "rule"
            ]
          }
        },
        "kind": {
          "enum": [
            "standard",
            "product",
            "custom"
          ],
          "default": "product"
        },
        "physical": {
          "description": "True if this can move, heat, power or otherwise affect the physical world.",
          "type": "boolean"
        },
        "guards": {
          "type": "object",
          "properties": {
            "whenStates": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "whenStatus": {
              "type": "array",
              "items": {
                "$ref": "common.schema.json#/$defs/status"
              }
            },
            "requiresMaintenance": {
              "type": "boolean"
            },
            "minIntervalSec": {
              "type": "integer",
              "minimum": 0
            },
            "maxPerHour": {
              "type": "integer",
              "minimum": 0
            },
            "interlocks": {
              "description": "Conditions that must hold immediately before sending, each a check (common check shape) read from the device at that moment. signal names a Signal Table signal or a property (properties module) of this system; nothing else may be named. A boolean reads as 1 (true) or 0 (false); an enum compares by its index in values. feature defaults to value; withinSec is not used here. An interlock that cannot be read or evaluated counts as failed (409 guard-failed).",
              "type": "array",
              "items": {
                "$ref": "common.schema.json#/$defs/check"
              }
            }
          },
          "x-heart-privacy": "internal"
        }
      }
    },
    "classification": {
      "type": "object",
      "required": [
        "path",
        "level"
      ],
      "properties": {
        "path": {
          "description": "<message>:<JSON Pointer into data>, where <message> is the message type without its heart. prefix, such as rhythm:/attributes/recordingPath.",
          "type": "string",
          "pattern": "^(card|pulse|rhythm|arrhythmia|action|receipt|evolution|component|property|config|metric|log|diagnostic|lifecycle|software|update|artifact|schedule|control|rule|consent|policy|aipolicy|memory|lesson|audit|security|platform|peer|fleet|custom|core|proposal|trial|brain|usage|export):(/.*)?$"
        },
        "level": {
          "$ref": "common.schema.json#/$defs/privacyLevel",
          "description": "The level the field gets. It may raise a field's level, never lower it (API Standard 4.2)."
        }
      },
      "additionalProperties": false
    }
  }
}
