{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/andrewhuot/headless-chat-sdk/schemas/memory.schema.json",
  "title": "Memory",
  "description": "Long-term memory primitives. Mirrors packages/gecx-chat/src/memory/types.ts.",
  "definitions": {
    "MemorySource": {
      "type": "string",
      "enum": ["tool", "extraction", "user", "import"]
    },
    "MemoryScope": {
      "type": "object",
      "required": ["identityId"],
      "additionalProperties": false,
      "properties": {
        "identityId": { "type": "string", "minLength": 1 },
        "conversationId": { "type": "string" }
      }
    },
    "MemoryEntry": {
      "type": "object",
      "required": ["id", "scope", "text", "source", "createdAt", "updatedAt"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "scope": { "$ref": "#/definitions/MemoryScope" },
        "text": { "type": "string", "minLength": 1, "maxLength": 500 },
        "key": { "type": "string" },
        "source": { "$ref": "#/definitions/MemorySource" },
        "createdAt": { "type": "integer", "minimum": 0 },
        "updatedAt": { "type": "integer", "minimum": 0 },
        "expiresAt": { "type": "integer", "minimum": 0 },
        "archivedAt": { "type": "integer", "minimum": 0 },
        "tags": { "type": "array", "items": { "type": "string" } },
        "embedding": { "type": "array", "items": { "type": "number" } },
        "metadata": { "type": "object", "additionalProperties": true }
      }
    },
    "MemoryCandidate": {
      "type": "object",
      "required": ["id", "text", "scope", "source", "proposedAt"],
      "additionalProperties": false,
      "properties": {
        "id": { "type": "string" },
        "text": { "type": "string", "minLength": 1, "maxLength": 500 },
        "key": { "type": "string" },
        "scope": { "$ref": "#/definitions/MemoryScope" },
        "source": { "const": "extraction" },
        "proposedAt": { "type": "integer", "minimum": 0 },
        "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
        "rationale": { "type": "string" },
        "tags": { "type": "array", "items": { "type": "string" } }
      }
    },
    "MemoryReadConfig": {
      "oneOf": [
        {
          "type": "object",
          "required": ["mode"],
          "additionalProperties": false,
          "properties": {
            "mode": { "const": "inject" },
            "maxEntries": { "type": "integer", "minimum": 1 },
            "maxTokens": { "type": "integer", "minimum": 1 },
            "injection": { "type": "string", "enum": ["client", "server"] },
            "semantic": { "type": "boolean" }
          }
        },
        {
          "type": "object",
          "required": ["mode"],
          "additionalProperties": false,
          "properties": { "mode": { "const": "recall" } }
        },
        {
          "type": "object",
          "required": ["mode", "inject"],
          "additionalProperties": false,
          "properties": {
            "mode": { "const": "hybrid" },
            "inject": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "maxEntries": { "type": "integer", "minimum": 1 },
                "maxTokens": { "type": "integer", "minimum": 1 },
                "semantic": { "type": "boolean" }
              }
            }
          }
        },
        {
          "type": "object",
          "required": ["mode"],
          "additionalProperties": false,
          "properties": { "mode": { "const": "off" } }
        }
      ]
    },
    "MemoryWriteConfig": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "tool": { "type": "boolean" },
        "approvalPolicy": {
          "type": "string",
          "enum": ["auto", "user_confirm", "supervisor_approve", "denied", "async_pending"]
        },
        "requireUserApproval": { "type": "boolean" },
        "maxEntryChars": { "type": "integer", "minimum": 1 }
      }
    },
    "MemoryQuotaConfig": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "maxEntriesPerScope": { "type": "integer", "minimum": 1 },
        "maxTotalBytes": { "type": "integer", "minimum": 1 }
      }
    },
    "MemoryRetentionConfig": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "defaultTtlMs": { "type": "integer", "minimum": 0 }
      }
    },
    "MemoryConfig": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "write": { "$ref": "#/definitions/MemoryWriteConfig" },
        "read": { "$ref": "#/definitions/MemoryReadConfig" },
        "retention": { "$ref": "#/definitions/MemoryRetentionConfig" },
        "quota": { "$ref": "#/definitions/MemoryQuotaConfig" },
        "initialEnabled": { "type": "boolean" }
      }
    },
    "MemoryEvent": {
      "oneOf": [
        {
          "type": "object",
          "required": ["kind", "entry"],
          "properties": {
            "kind": { "const": "saved" },
            "entry": { "$ref": "#/definitions/MemoryEntry" }
          }
        },
        {
          "type": "object",
          "required": ["kind", "entry", "prev"],
          "properties": {
            "kind": { "const": "updated" },
            "entry": { "$ref": "#/definitions/MemoryEntry" },
            "prev": { "$ref": "#/definitions/MemoryEntry" }
          }
        },
        {
          "type": "object",
          "required": ["kind", "id"],
          "properties": { "kind": { "const": "deleted" }, "id": { "type": "string" } }
        },
        {
          "type": "object",
          "required": ["kind", "scope"],
          "properties": { "kind": { "const": "cleared" }, "scope": { "$ref": "#/definitions/MemoryScope" } }
        },
        {
          "type": "object",
          "required": ["kind", "entry", "supersededBy"],
          "properties": {
            "kind": { "const": "archived" },
            "entry": { "$ref": "#/definitions/MemoryEntry" },
            "supersededBy": { "type": "string" }
          }
        },
        {
          "type": "object",
          "required": ["kind", "candidates"],
          "properties": {
            "kind": { "const": "extraction.proposed" },
            "candidates": { "type": "array", "items": { "$ref": "#/definitions/MemoryCandidate" } }
          }
        },
        {
          "type": "object",
          "required": ["kind", "candidateId", "outcome"],
          "properties": {
            "kind": { "const": "extraction.resolved" },
            "candidateId": { "type": "string" },
            "outcome": { "type": "string", "enum": ["approved", "rejected"] },
            "entry": { "$ref": "#/definitions/MemoryEntry" }
          }
        },
        {
          "type": "object",
          "required": ["kind", "winner", "loser"],
          "properties": {
            "kind": { "const": "sync.conflict.resolved" },
            "winner": { "$ref": "#/definitions/MemoryEntry" },
            "loser": { "$ref": "#/definitions/MemoryEntry" }
          }
        },
        {
          "type": "object",
          "required": ["kind", "enabled"],
          "properties": {
            "kind": { "const": "enabled_changed" },
            "enabled": { "type": "boolean" }
          }
        }
      ]
    }
  }
}
