{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.anguskit.com/schema/anguscopilot/1.0.0/memory.json",
  "title": "Memory Configuration",
  "description": "记忆系统配置（Working / Episodic / Semantic / Procedural）。W10 增量字段：recall（HyDE / Rerank）、outbox（跨后端最终一致性）、compaction.archiveBackend、compliance.forgetSlaHours / tombstoneRetentionYears。",
  "type": "object",
  "properties": {

    "working": {
      "description": "工作记忆（会话级）。 [stable]",
      "oneOf": [
        { "type": "boolean" },
        {
          "type": "object",
          "properties": {
            "enabled": { "type": "boolean", "default": true },
            "store": { "type": "string", "enum": ["redis", "caffeine"], "default": "redis" },
            "ttl": { "$ref": "common.json#/$defs/Duration", "default": "1h" },
            "maxItems": { "type": "integer", "minimum": 1 }
          },
          "patternProperties": { "^x-": true },
          "unevaluatedProperties": false
        }
      ]
    },

    "episodic": {
      "description": "情景记忆（事件流，长期持久化）。 [stable]",
      "type": "object",
      "properties": {
        "enabled": { "type": "boolean", "default": false },
        "ttlDays": { "type": "integer", "minimum": 1, "maximum": 3650 },
        "maxRecords": { "type": "integer", "minimum": 1 },
        "compactionStrategy": {
          "type": "string",
          "enum": ["lru", "lfu", "semantic-dedup", "llm-summarize"]
        }
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "semantic": {
      "description": "语义记忆（向量检索）。 [stable]",
      "type": "object",
      "properties": {
        "enabled": { "type": "boolean", "default": false },
        "vectorStore": {
          "description": "向量后端。pgvector 为推荐方案；外部向量库走独立 SPI 适配。 [stable]",
          "type": "string",
          "enum": ["pgvector", "milvus", "qdrant", "pinecone", "weaviate"]
        },
        "datasourceRef": {
          "description": "向量库连接配置引用（来自 Spring DataSource 或独立配置块）。 [stable]",
          "type": "string"
        },
        "embedding": {
          "type": "object",
          "required": ["provider", "model"],
          "properties": {
            "provider": { "type": "string" },
            "model": { "type": "string" },
            "dimensions": { "type": "integer", "minimum": 1 },
            "credentialRef": { "$ref": "common.json#/$defs/SecretRef" }
          },
          "patternProperties": { "^x-": true },
          "unevaluatedProperties": false
        },
        "index": {
          "type": "object",
          "properties": {
            "type": { "type": "string", "enum": ["ivfflat", "hnsw"] },
            "params": { "type": "object", "additionalProperties": true }
          },
          "patternProperties": { "^x-": true },
          "unevaluatedProperties": false
        },
        "topK": { "type": "integer", "minimum": 1, "default": 5 },
        "minScore": { "type": "number", "minimum": 0, "maximum": 1 },
        "ttlDays": { "type": "integer", "minimum": 1 }
      },
      "$comment": "B1/B2 跨字段约束：vectorStore=pgvector 时必须配置 datasourceRef；启用 semantic 时必须有 embedding。",
      "allOf": [
        {
          "if": { "properties": { "enabled": { "const": true } }, "required": ["enabled"] },
          "then": {
            "required": ["vectorStore", "embedding"]
          }
        },
        {
          "if": { "properties": { "vectorStore": { "const": "pgvector" } }, "required": ["vectorStore"] },
          "then": {
            "required": ["datasourceRef"]
          }
        }
      ],
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "procedural": {
      "description": "程序记忆（成功 SOP 版本化管理）。 [stable]",
      "type": "object",
      "properties": {
        "enabled": { "type": "boolean", "default": false },
        "store": { "type": "string", "enum": ["postgres", "mariadb"] }
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "tenantIsolation": {
      "description": "多租户隔离策略。 [stable]",
      "type": "object",
      "properties": {
        "tenantField": { "type": "string", "default": "tenantId" },
        "workspaceField": { "type": "string", "default": "workspaceId" },
        "enforcement": {
          "type": "string",
          "enum": ["row-level-security", "application-guard"],
          "default": "row-level-security"
        }
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "compliance": {
      "description": "合规配置（PII / GDPR / 个保法）。 [stable]",
      "type": "object",
      "properties": {
        "piiDetection": {
          "type": "string",
          "enum": ["off", "regex", "ner", "ner+regex"],
          "default": "regex"
        },
        "rightToBeForgotten": {
          "description": "是否启用 forget user 链路（与 §12.6 对齐）。 [stable]",
          "type": "boolean",
          "default": true
        },
        "auditCriticalOps": {
          "description": "rightToBeForgotten=true 时强制 true（W10 新增 B5 约束）。 [stable]",
          "type": "boolean",
          "default": true
        },
        "forgetSlaHours": {
          "description": "forget user 完成 SLA（小时；W10 新增 B7）。GDPR 要求 ≤ 720h（30 天）。 [beta]",
          "type": "integer",
          "minimum": 1,
          "maximum": 720,
          "default": 24
        },
        "tombstoneRetentionYears": {
          "description": "Tombstone 保留年限（W10 新增 B7）。 [beta]",
          "type": "integer",
          "minimum": 1,
          "maximum": 30,
          "default": 7
        }
      },
      "$comment": "B5 跨字段约束：rightToBeForgotten=true 时必须 auditCriticalOps=true。",
      "if": {
        "properties": { "rightToBeForgotten": { "const": true } },
        "required": ["rightToBeForgotten"]
      },
      "then": {
        "properties": {
          "auditCriticalOps": { "const": true }
        },
        "required": ["auditCriticalOps"]
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "recall": {
      "description": "召回链路配置（W10 新增；与 §12.7 对齐）。 [beta]",
      "type": "object",
      "properties": {
        "hyde": {
          "description": "HyDE（Hypothetical Document Embedding）。 [beta]",
          "type": "object",
          "properties": {
            "enabled": { "type": "boolean", "default": false },
            "modelRef": {
              "description": "用于生成假设文档的 LLM 引用（enabled=true 时必填，B3 约束）。 [beta]",
              "type": "string",
              "minLength": 1
            },
            "promptTemplate": { "type": "string" }
          },
          "patternProperties": { "^x-": true },
          "$comment": "B3 跨字段约束：hyde.enabled=true 时必须 modelRef。",
          "if": {
            "properties": { "enabled": { "const": true } },
            "required": ["enabled"]
          },
          "then": {
            "required": ["modelRef"]
          },
          "unevaluatedProperties": false
        },
        "rerank": {
          "description": "Cross-Encoder 重排。 [beta]",
          "type": "object",
          "properties": {
            "enabled": { "type": "boolean", "default": false },
            "modelRef": {
              "description": "Reranker 模型引用（enabled=true 时必填，B4 约束）。 [beta]",
              "type": "string",
              "minLength": 1
            },
            "topK": {
              "description": "粗排候选数（送入重排前的 TopK）。 [beta]",
              "type": "integer",
              "minimum": 1,
              "default": 30
            },
            "finalTopK": {
              "description": "最终返回 TopK；必须 ≤ topK。 [beta]",
              "type": "integer",
              "minimum": 1,
              "default": 8
            }
          },
          "patternProperties": { "^x-": true },
          "$comment": "B4 跨字段约束：rerank.enabled=true 时必须 modelRef，且 topK > finalTopK。",
          "allOf": [
            {
              "if": {
                "properties": { "enabled": { "const": true } },
                "required": ["enabled"]
              },
              "then": {
                "required": ["modelRef"]
              }
            }
          ],
          "unevaluatedProperties": false
        },
        "minScore": {
          "description": "默认召回最低分阈值（覆盖 semantic.minScore 时仅作用于 recall 路径）。 [beta]",
          "type": "number",
          "minimum": 0,
          "maximum": 1
        }
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "outbox": {
      "description": "关系表→向量库的 outbox 跨后端一致性配置（W10 新增；与 §12.8.3 对齐）。 [beta]",
      "type": "object",
      "properties": {
        "enabled": { "type": "boolean", "default": true },
        "lagAlertSeconds": {
          "description": "outbox lag 告警阈值（秒）。≥ 30s 强制（B7）。 [beta]",
          "type": "integer",
          "minimum": 30,
          "default": 60
        },
        "maxRetries": {
          "description": "失败重试上限（≥ 1，B7 约束）。 [beta]",
          "type": "integer",
          "minimum": 1,
          "maximum": 20,
          "default": 5
        },
        "backoff": {
          "description": "指数退避基线 Duration（如 '500ms'）。 [beta]",
          "$ref": "common.json#/$defs/Duration",
          "default": "500ms"
        }
      },
      "patternProperties": { "^x-": true },
      "unevaluatedProperties": false
    },

    "compaction": {
      "description": "记忆压缩 / 冷热分离策略（W10 新增；与 §12.5 对齐）。 [beta]",
      "type": "object",
      "properties": {
        "maxRecords": {
          "description": "Episodic 累计上限，超过后触发压缩。 [beta]",
          "type": "integer",
          "minimum": 1,
          "default": 10000
        },
        "warmThresholdDays": {
          "description": "Hot → Warm 的最近访问天数阈值。 [beta]",
          "type": "integer",
          "minimum": 1,
          "default": 7
        },
        "coldThresholdDays": {
          "description": "Warm → Cold 的最近访问天数阈值（必须 > warmThresholdDays，由 §12.5.3 兜底）。 [beta]",
          "type": "integer",
          "minimum": 1,
          "default": 30
        },
        "archiveBackend": {
          "description": "Archived 状态的归档后端（W10 新增 B6 约束：oss/s3 时必须 archiveCredentialRef）。 [beta]",
          "type": "string",
          "enum": ["none", "oss", "s3", "azure-blob", "gcs"]
        },
        "archiveCredentialRef": {
          "description": "归档后端凭证。archiveBackend ∈ {oss, s3, azure-blob, gcs} 时必填。 [beta]",
          "$ref": "common.json#/$defs/SecretRef"
        }
      },
      "patternProperties": { "^x-": true },
      "$comment": "B6 跨字段约束：archiveBackend ∈ {oss/s3/azure-blob/gcs} 时必须 archiveCredentialRef。",
      "if": {
        "properties": {
          "archiveBackend": {
            "type": "string",
            "enum": ["oss", "s3", "azure-blob", "gcs"]
          }
        },
        "required": ["archiveBackend"]
      },
      "then": {
        "required": ["archiveCredentialRef"]
      },
      "unevaluatedProperties": false
    }
  },
  "patternProperties": {
    "^x-": true
  },
  "unevaluatedProperties": false
}
