{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/Kucell/cortex-agent/schemas/memory.schema.json",
  "title": "Cortex Agent Memory Entry",
  "description": "Mode-agnostic cross-session distilled memory. Three types: episodic (specific events), semantic (stable facts), procedural (habits/preferences, deferred to v1.12). Per general-mode-design.md §6.4 memory/ tree.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "memory_id",
    "type",
    "content",
    "created_at"
  ],
  "properties": {
    "schema_version": { "const": 1 },
    "memory_id": {
      "type": "string",
      "pattern": "^MEM-[A-Za-z0-9][A-Za-z0-9._-]*$",
      "description": "Stable memory id, prefix MEM-."
    },
    "type": {
      "type": "string",
      "enum": ["episodic", "semantic", "procedural"],
      "description": "episodic = specific event (when X happened); semantic = stable fact (X is always Y); procedural = habit/preference (deferred to v1.12)."
    },
    "title": { "type": "string", "maxLength": 200 },
    "content": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4000,
      "description": "Memory body. episodic: prose event description; semantic: one canonical sentence; procedural: workflow recipe."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[a-z0-9_][a-z0-9_-]*$"
      },
      "maxItems": 10,
      "description": "Keywords for memory-recall (Phase 2)."
    },
    "source_conversation_id": {
      "type": ["string", "null"],
      "pattern": "^C-[A-Za-z0-9][A-Za-z0-9._-]*$"
    },
    "source_decision_id": {
      "type": ["string", "null"],
      "pattern": "^D-[A-Za-z0-9][A-Za-z0-9._-]*$"
    },
    "source_run_id": {
      "type": ["string", "null"]
    },
    "scope": {
      "type": "string",
      "enum": ["user", "project", "skill", "runtime", "global"],
      "description": "P-007 §3.1: user = private preferences; project = project context; skill = skill-owned (e.g. evaluator output); runtime = session/workflow state; global = cross-project. Old entries without scope default to 'project' on read for back-compat."
    },
    "expires_at": {
      "type": ["string", "null"],
      "format": "date",
      "description": "Optional expiry. semantic memories can be permanent; episodic memories typically expire after 90 days unless pinned."
    },
    "pinned": {
      "type": "boolean",
      "default": false,
      "description": "Pinned memories are not subject to automatic forget/cleanup."
    },
    "confidence": {
      "type": "number",
      "minimum": 0,
      "maximum": 1,
      "description": "Distillation confidence 0-1. semantic memories are typically 1.0; episodic memories may be lower."
    },
    "created_at": { "type": "string", "format": "date-time" },
    "updated_at": { "type": ["string", "null"], "format": "date-time" }
  }
}
