{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://agentcall.smartycode.com/schemas/agentcall-physical-observation-0.1.schema.json",
  "title": "AgentCall physical observation (0.1) - public NFC/photo profile",
  "description": "Public AgentCall 0.1 NFC/photo profile generated from canonical contracts. Only the reviewed dependency closure is published; see the release manifest and /ext/agentcall-agui/0.1 for negotiation and semantic validation duties.",
  "type": "object",
  "required": [
    "schemaVersion",
    "observationId",
    "capturedAt",
    "intent"
  ],
  "properties": {
    "schemaVersion": {
      "const": "0.1"
    },
    "observationId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "pattern": "^[A-Za-z0-9._:-]+$"
    },
    "capturedAt": {
      "type": "string",
      "format": "date-time",
      "maxLength": 64
    },
    "intent": {
      "enum": [
        "identify",
        "remember",
        "inspect",
        "act"
      ],
      "description": "The visible user-selected purpose. It never authorizes a consequential action by itself."
    },
    "object": {
      "$ref": "#/$defs/object"
    },
    "image": {
      "$ref": "#/$defs/image"
    }
  },
  "anyOf": [
    {
      "required": [
        "object"
      ]
    },
    {
      "required": [
        "image"
      ]
    }
  ],
  "$defs": {
    "object": {
      "type": "object",
      "required": [
        "objectRef",
        "carrier",
        "assurance",
        "payloadSha256"
      ],
      "properties": {
        "objectRef": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2048,
          "pattern": "^(urn:agentcall:object:[A-Za-z0-9][A-Za-z0-9._~-]{0,127}|https://[^\\u0000-\\u0020\\u007F]+)$",
          "description": "Opaque stable object reference. Receivers never fetch an HTTPS reference merely because a tag supplied it."
        },
        "carrier": {
          "enum": [
            "ndefUri",
            "localTag",
            "deepLink",
            "cameraAssociation"
          ],
          "description": "How the opaque reference was obtained. localTag is a device-local keyed alias derived on the client from a stable protocol identifier; the raw hardware identifier never crosses the client boundary."
        },
        "assurance": {
          "enum": [
            "unverifiedTag",
            "signedTag",
            "localCapture"
          ],
          "description": "Cheap writable tags are labels, not proof of identity. signedTag is reserved for a separately verified cryptographic carrier."
        },
        "payloadSha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$",
          "description": "Digest of the exact bounded carrier payload. For localTag this covers the opaque alias, never the raw hardware identifier. It is not an authentication signal."
        }
      }
    },
    "image": {
      "type": "object",
      "required": [
        "mediaType",
        "dataBase64",
        "sha256",
        "byteCount",
        "pixelWidth",
        "pixelHeight"
      ],
      "properties": {
        "mediaType": {
          "const": "image/jpeg"
        },
        "dataBase64": {
          "type": "string",
          "contentEncoding": "base64",
          "maxLength": 81920,
          "description": "Ephemeral JPEG bytes. Decoded payload is at most 60 KiB and is never retained by the client as diagnostics."
        },
        "sha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "byteCount": {
          "type": "integer",
          "minimum": 1,
          "maximum": 61440
        },
        "pixelWidth": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1024
        },
        "pixelHeight": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1024
        }
      }
    }
  }
}
