{
  "canonical_name": "smaramwbc/statewave",
  "compilation_id": "pack_140027e0e6c64e70b246dc244f631fa6",
  "created_at": "2026-05-14T15:12:35.006750+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=skill, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=skill, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `pip install statewave` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "pip install statewave",
      "sandbox_container_image": "python:3.12-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "deterministic_isolated_install",
      "sandbox_validation_id": "sbx_968016cc8dbf497b9cb78643d09f8afa"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_b26a8931ff89435971f628384405e8e3",
    "canonical_name": "smaramwbc/statewave",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/smaramwbc/statewave",
    "slug": "statewave",
    "source_packet_id": "phit_c21c5975d6ff484fbc49d5edaf419483",
    "source_validation_id": "dval_710ffdadb42e4d4ca81c22901be11584"
  },
  "merchandising": {
    "best_for": "需要软件开发与交付能力，并使用 local_cli的用户",
    "github_forks": 1,
    "github_stars": 217,
    "one_liner_en": "Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres.",
    "one_liner_zh": "Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres.",
    "primary_category": {
      "category_id": "software-development",
      "confidence": "medium",
      "name_en": "Software Development",
      "name_zh": "软件开发与交付",
      "reason": "matched_keywords:git, cli"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "statewave",
    "title_zh": "statewave 能力包",
    "visible_tags": [
      {
        "label_en": "MCP Tools",
        "label_zh": "MCP 工具",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-mcp-tools",
        "type": "product_domain"
      },
      {
        "label_en": "Knowledge Base Q&A",
        "label_zh": "知识库问答",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-knowledge-base-q-a",
        "type": "user_job"
      },
      {
        "label_en": "Workflow Automation",
        "label_zh": "流程自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-workflow-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Automated Workflow",
        "label_zh": "自动化工作流",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-automated-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Evaluation Suite",
        "label_zh": "评测体系",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-evaluation-suite",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_c21c5975d6ff484fbc49d5edaf419483",
  "page_model": {
    "artifacts": {
      "artifact_slug": "statewave",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "pip install statewave",
          "label": "Python / pip · 官方安装入口",
          "source": "https://github.com/smaramwbc/statewave#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "MCP 工具",
        "知识库问答",
        "流程自动化",
        "自动化工作流",
        "评测体系"
      ],
      "eyebrow": "软件开发与交付",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要软件开发与交付能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres."
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "skill, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | github_repo:1219923941 | https://github.com/smaramwbc/statewave | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": 2,
        "forks": 1,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": 217
      },
      "source_url": "https://github.com/smaramwbc/statewave",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres.",
      "title": "statewave 能力包",
      "trial_prompt": "# statewave - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 statewave 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres. 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. p-intro：Statewave 简介。围绕“Statewave 简介”模拟一次用户任务，不展示安装或运行结果。\n2. p-quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. p-arch-overview：系统架构概览。围绕“系统架构概览”模拟一次用户任务，不展示安装或运行结果。\n4. p-data-flow：数据流与生命周期。围绕“数据流与生命周期”模拟一次用户任务，不展示安装或运行结果。\n5. p-episodes：Episode 管理。围绕“Episode 管理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. p-intro\n输入：用户提供的“Statewave 简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. p-quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. p-arch-overview\n输入：用户提供的“系统架构概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. p-data-flow\n输入：用户提供的“数据流与生命周期”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. p-episodes\n输入：用户提供的“Episode 管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / p-intro：Step 1 必须围绕“Statewave 简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / p-quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / p-arch-overview：Step 3 必须围绕“系统架构概览”形成一个小中间产物，并等待用户确认。\n- Step 4 / p-data-flow：Step 4 必须围绕“数据流与生命周期”形成一个小中间产物，并等待用户确认。\n- Step 5 / p-episodes：Step 5 必须围绕“Episode 管理”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/smaramwbc/statewave\n- https://github.com/smaramwbc/statewave#readme\n- README.md\n- server/app.py\n- server/main.py\n- docker-compose.yml\n- DOCKER.md\n- .env.example\n- pyproject.toml\n- server/core/config.py\n- server/core/dependencies.py\n- server/api/__init__.py\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 statewave 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: policy_bundles: support cross-tenant bundle reuse via composite (tenant_（https://github.com/smaramwbc/statewave/issues/79）；github/github_release: v0.8.0（https://github.com/smaramwbc/statewave/releases/tag/v0.8.0）；github/github_release: v0.7.2（https://github.com/smaramwbc/statewave/releases/tag/v0.7.2）；github/github_release: v0.7.0: Admin Dashboard API（https://github.com/smaramwbc/statewave/releases/tag/v0.7.0）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "policy_bundles: support cross-tenant bundle reuse via composite (tenant_",
              "url": "https://github.com/smaramwbc/statewave/issues/79"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.8.0",
              "url": "https://github.com/smaramwbc/statewave/releases/tag/v0.8.0"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.7.2",
              "url": "https://github.com/smaramwbc/statewave/releases/tag/v0.7.2"
            },
            {
              "kind": "github_release",
              "source": "github",
              "title": "v0.7.0: Admin Dashboard API",
              "url": "https://github.com/smaramwbc/statewave/releases/tag/v0.7.0"
            }
          ],
          "status": "已收录 4 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "软件开发与交付",
      "desc": "Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres.",
      "effort": "安装已验证",
      "forks": 1,
      "icon": "code",
      "name": "statewave 能力包",
      "risk": "可发布",
      "slug": "statewave",
      "stars": 217,
      "tags": [
        "MCP 工具",
        "知识库问答",
        "流程自动化",
        "自动化工作流",
        "评测体系"
      ],
      "thumb": "gray",
      "type": "Skill Pack"
    },
    "manual": {
      "markdown": "# https://github.com/smaramwbc/statewave 项目说明书\n\n生成时间：2026-05-14 12:54:51 UTC\n\n## 目录\n\n- [Statewave 简介](#p-intro)\n- [快速开始](#p-quickstart)\n- [系统架构概览](#p-arch-overview)\n- [数据流与生命周期](#p-data-flow)\n- [Episode 管理](#p-episodes)\n- [编译器系统](#p-compiler)\n- [上下文检索与排名](#p-context-retrieval)\n- [API 路由参考](#p-api-routes)\n- [服务层实现](#p-services)\n- [数据库架构](#p-database)\n\n<a id='p-intro'></a>\n\n## Statewave 简介\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [快速开始](#p-quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n- [server/starter_packs/statewave-support-agent/manifest.json](https://github.com/smaramwbc/statewave/blob/main/server/starter_packs/statewave-support-agent/manifest.json)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [scripts/docs_loader.py](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n- [helm/statewave/README.md](https://github.com/smaramwbc/statewave/blob/main/helm/statewave/README.md)\n</details>\n\n# Statewave 简介\n\nStatewave 是一个专为 AI Agent 设计的**记忆管理系统**，帮助 Agent 从真实世界的各种数据源中构建、检索和利用持久化记忆。通过提供 Episode（事件片段）摄取、Memory（记忆片段）编译、上下文组装等功能，Statewave 使 Agent 能够在多轮对话和工作流程中保持一致性和连续性。\n\n资料来源：[README.md:1-20]()\n\n## 核心概念\n\nStatewave 的数据模型围绕以下核心实体构建：\n\n```mermaid\ngraph TD\n    A[Subject 主体] --> B[Episode 事件片段]\n    A --> C[Memory 记忆片段]\n    B --> D[Compilation 编译]\n    C --> E[Context 上下文]\n    F[Resolution 解决方案] --> A\n    G[Snapshot 快照] --> A\n```\n\n### Subject（主体）\n\nSubject 是最高层级的数据容器，代表一个特定的实体（如客户、项目、用户或任何需要记忆的抽象概念）。每个 Subject 拥有独立的 Episode 和 Memory 存储空间。\n\n资料来源：[server/starter_packs/statewave-support-agent/manifest.json:8]()\n\n### Episode（事件片段）\n\nEpisode 是 Statewave 中的基础数据单元，代表一次不可变的事件或交互记录。Episode 可以来源于：\n\n- 实时对话转录\n- GitHub Issues、Pull Requests\n- 文档变更\n- Slack 消息\n- MCP Server 事件\n- 任何自定义数据源\n\n每个 Episode 包含标题、正文内容、元数据以及来源信息，通过 `content_hash` 实现内容去重和增量更新。\n\n资料来源：[scripts/docs_loader.py:30-50]()\n\n### Memory（记忆片段）\n\nMemory 是经过编译（Compile）后的结构化记忆。编译过程从多个 Episode 中提取关键信息，生成包含以下属性的记忆单元：\n\n| 属性 | 说明 |\n|------|------|\n| `kind` | 记忆类型（如决策、偏好、问题等） |\n| `content` | 记忆内容 |\n| `summary` | 摘要信息 |\n| `confidence` | 置信度 |\n| `valid_from` | 有效起始时间 |\n| `valid_to` | 有效结束时间（可选） |\n| `source_episode_ids` | 来源 Episode ID 列表 |\n\n资料来源：[server/api/admin.py:50-80]()\n\n### Resolution（解决方案）\n\nResolution 用于跟踪会话级别的解决方案状态，支持 SLA 指标计算和响应时间追踪。\n\n资料来源：[server/api/timeline.py:60-90]()\n\n### Snapshot（快照）\n\nSnapshot 提供 Subject 的完整状态快照功能，包含 Episodes、Memories 和 Resolutions 的时间点副本，支持数据恢复和迁移场景。\n\n资料来源：[server/services/snapshots.py:20-80]()\n\n## 系统架构\n\nStatewave 采用现代化的微服务架构设计，主要组件包括：\n\n```mermaid\ngraph TD\n    subgraph 客户端层\n        A[Agent 应用]\n        B[Connectors]\n        C[SDK]\n    end\n    \n    subgraph API 网关层\n        D[FastAPI Server<br/>:8100]\n        E[OpenAPI / Swagger]\n    end\n    \n    subgraph 业务逻辑层\n        F[Episode Service]\n        G[Memory Service]\n        H[Context Service]\n        I[Timeline Service]\n    end\n    \n    subgraph 数据层\n        J[(PostgreSQL)]\n        K[(Embedding Store)]\n    end\n    \n    subgraph 外部服务\n        L[LiteLLM]\n        M[LLM Provider]\n    end\n    \n    A --> D\n    B --> D\n    C --> D\n    D --> F\n    D --> G\n    D --> H\n    D --> I\n    F --> J\n    G --> J\n    G --> K\n    H --> L\n    I --> J\n    L --> M\n```\n\n### 技术栈\n\n| 层级 | 技术选型 |\n|------|----------|\n| API 框架 | FastAPI |\n| 数据库 | PostgreSQL + asyncpg |\n| LLM 集成 | LiteLLM |\n| 向量嵌入 | 可配置（默认 LiteLLM） |\n| 部署方式 | Docker / Kubernetes Helm |\n\n资料来源：[README.md:50-70]()\n\n## API 参考\n\n### 健康检查端点\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活探针 |\n| `GET /readyz` 或 `GET /ready` | 就绪探针 |\n\n### Episode 管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄取单个 Episode（追加模式） |\n| `POST` | `/v1/episodes/batch` | 批量摄取最多 100 个 Episode |\n\n资料来源：[README.md:30-45]()\n\n### Memory 管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/memories/compile` | 编译 Memories（幂等操作） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n\n### Context 上下文组装\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/context` | 组装基于排序和 Token 限制的上下文包 |\n\n### Subject 主体管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `GET` | `/v1/subjects` | 列出已知主体及 Episode/Memory 计数 |\n| `DELETE` | `/v1/subjects/{id}` | 永久删除主体的所有数据 |\n| `GET` | `/v1/subjects/{id}/health` | 客户健康评分及可解释因素 |\n| `GET` | `/v1/subjects/{id}/sla` | SLA 指标（响应时间、解决时间、违反情况） |\n\n### 时间线与解决方案\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `GET` | `/v1/timeline` | 按时间顺序排列的主体时间线 |\n| `POST` | `/v1/resolutions` | 跟踪每个会话的解决方案状态 |\n| `GET` | `/v1/resolutions` | 列出主体的解决方案 |\n| `POST` | `/v1/handoff` | 生成紧凑的交接上下文包 |\n\n资料来源：[README.md:35-55]()\n\n## 编译模式\n\nStatewave 支持两种编译模式：\n\n### LLM 编译（默认）\n\n使用大型语言模型从 Episode 中提取结构化 Memory，提供更高的语义理解能力。需要配置 LLM API Key。\n\n### 启发式编译\n\n基于规则的编译模式，适用于演示环境或无 LLM 场景，性能更快但语义理解能力有限。\n\n配置方式：`STATEWAVE_COMPILER_TYPE=heuristic`\n\n资料来源：[helm/statewave/README.md:25-30]()\n\n## 连接器生态\n\nStatewave 提供了丰富的连接器（Connector）生态系统，用于从不同数据源摄取 Episode：\n\n| 数据源 | 功能 | 状态 |\n|--------|------|------|\n| MCP Server | Copilot/Claude/Cursor/Agent 记忆同步 | ✅ 已发布 |\n| GitHub | Issues、PRs、Reviews、Releases → Repo 记忆 | ✅ 已发布 |\n| Markdown | 本地文档、ADR、RFC → 决策记忆 | ✅ 已发布 |\n| Slack | 频道消息同步 | ✅ 已发布 |\n| n8n | 工作流事件集成 | ✅ 已发布 |\n| Zapier | Zapier 自动化集成 | ✅ 已发布 |\n\n安装方式（按需选择）：\n\n```bash\nnpm install @statewavedev/connectors-github\nnpm install @statewavedev/connectors-markdown\nnpm install @statewavedev/connectors-slack\nnpm install @statewavedev/connectors-n8n\nnpm install @statewavedev/connectors-zapier\nnpm install @statewavedev/mcp-server\n```\n\n资料来源：[README.md:80-110]()\n\n## 配置参考\n\n### 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接字符串（必填） |\n| `STATEWAVE_LITELLM_API_KEY` | — | LiteLLM API Key（LLM/嵌入必需） |\n| `STATEWAVE_LITELLM_BASE_URL` | — | LiteLLM 自定义基础 URL |\n| `STATEWAVE_EMBEDDING_PROVIDER` | `litellm` | 嵌入提供商 |\n| `STATEWAVE_COMPILER_TYPE` | `llm` | `llm` 或 `heuristic` |\n| `STATEWAVE_API_KEY` | — | API 认证密钥 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每分钟/IP 请求限制（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | `distributed`（Postgres）或 `memory` |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离 Header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 Header |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 上下文组装默认 Token 预算 |\n| `STATEWAVE_CORS_ORIGINS` | `[\"*\"]` | 允许的 CORS 来源列表 |\n\n资料来源：[README.md:100-120]()\n\n## 部署方式\n\n### Docker Compose 部署\n\n```yaml\nservices:\n  statewave:\n    image: statewavedev/statewave:latest\n    ports: [\"8100:8100\"]\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n\nvolumes:\n  pgdata:\n```\n\n```bash\ndocker compose up -d\ncurl http://localhost:8100/healthz\n```\n\n指定版本部署：\n\n```bash\nSTATEWAVE_VERSION=0.7.0 docker compose up -d\n```\n\n### Kubernetes Helm 部署\n\n```bash\nhelm install statewave ./helm/statewave \\\n  --set database.url='postgresql+asyncpg://...' \\\n  --set llm.apiKey='sk-...'\n```\n\nHelm 安装时会自动运行数据库迁移（Alembic）Job，确保在 API Pod 接收流量前完成 schema 初始化。\n\n资料来源：[DOCKER.md:1-50]()\n资料来源：[helm/statewave/README.md:1-30]()\n\n### Docker 镜像标签\n\n| 标签 | 含义 |\n|------|------|\n| `latest` | main 分支最新代码 |\n| `X.Y.Z` | 语义化版本发布 |\n| `X.Y` | 该 minor 版本的最新版本 |\n| `X` | 该 major 版本的最新版本 |\n| `sha-<7>` | 特定 Commit |\n\n资料来源：[DOCKER.md:30-40]()\n\n## 启动包\n\nStatewave 提供了开箱即用的 Starter Pack，其中包含预置的 Episodes 和 Memories：\n\n### statewave-support-agent\n\n预编译的支持代理启动包，包含 276 个 Episodes 和 364 个 Memories，涵盖：\n\n- 产品文档\n- 架构设计\n- 部署指南\n- 故障排除\n- 竞品对比\n\n版本：`1.2026.05.08`\n\n导入后可立即启用文档驱动的支持代理，无需额外引导步骤。\n\n资料来源：[server/starter_packs/statewave-support-agent/manifest.json:1-20]()\n\n## 当前限制\n\nStatewave 目前处于活跃开发阶段（v0.8.0），存在以下已知限制：\n\n### 速率限制\n\n- **速率限制按 IP 级别**：使用分布式（Postgres 后端）实现，但仅按 IP 键控，尚未支持按租户或 API Key 级别限制\n\n### 多租户\n\n- **多租户隔离在应用层**：通过查询作用域数据隔离（v0.5）+ 每租户配置/策略/收据包（v0.8）实现\n- **尚未支持 PostgreSQL RLS**（行级安全策略）\n\n资料来源：[README.md:130-140]()\n\n## 测试\n\n### 运行测试\n\n```bash\n# 单元测试（无需数据库）\npytest tests/test_*.py -v\n\n# 集成测试（需要 PostgreSQL）\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\npytest tests/integration/ -v\n\n# 全部测试\npytest tests/ -v\n```\n\n资料来源：[README.md:120-130]()\n\n## 相关资源\n\n- 官方文档：https://statewave.ai\n- 仓库地址：https://github.com/smaramwbc/statewave\n- 连接器生态：https://github.com/smaramwbc/statewave-connectors\n- API 契约文档：https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md\n\n---\n\n<a id='p-quickstart'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[Statewave 简介](#p-intro)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [docker-compose.yml](https://github.com/smaramwbc/statewave/blob/main/docker-compose.yml)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n- [.env.example](https://github.com/smaramwbc/statewave/blob/main/.env.example)\n- [pyproject.toml](https://github.com/smaramwbc/statewave/blob/main/pyproject.toml)\n</details>\n\n# 快速开始\n\n本页面提供 Statewave 的快速部署和基本使用指南，帮助你在本地环境快速启动服务并验证核心功能。\n\n## 系统要求\n\n| 组件 | 最低要求 | 推荐配置 |\n|------|----------|----------|\n| Docker | 20.10+ | 最新稳定版 |\n| Docker Compose | 2.0+ | v2.x |\n| PostgreSQL | 14+ | 15+ |\n| 内存 | 4GB | 8GB+ |\n| CPU | 2核 | 4核+ |\n\n资料来源：[docker-compose.yml:1-50]()\n\n## 快速启动（Docker Compose）\n\n### 1. 克隆仓库\n\n```bash\ngit clone https://github.com/smaramwbc/statewave.git\ncd statewave\n```\n\n### 2. 配置环境变量\n\nStatewave 通过环境变量进行配置。在项目根目录创建 `.env` 文件：\n\n```bash\ncp .env.example .env\n```\n\n基础配置项：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接字符串，必填 |\n| `STATEWAVE_LITELLM_API_KEY` | — | LLM API 密钥（用于编译功能） |\n| `STATEWAVE_API_KEY` | — | API 访问密钥 |\n| `STATEWAVE_PORT` | `8100` | 服务监听端口 |\n| `STATEWAVE_RATE_LIMIT_PER_MIN` | `60` | 每IP每分钟请求限制 |\n\n资料来源：[.env.example](https://github.com/smaramwbc/statewave/blob/main/.env.example)\n\n### 3. 启动服务\n\n```yaml\n# docker-compose.yml 核心配置\nservices:\n  app:\n    image: statewavedev/statewave:latest\n    ports:\n      - \"8100:8100\"\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n\nvolumes:\n  pgdata:\n```\n\n```bash\ndocker compose up -d\n```\n\n资料来源：[DOCKER.md:1-20]()\n\n### 4. 验证服务\n\n服务启动后，通过健康检查端点验证：\n\n```bash\ncurl http://localhost:8100/healthz\n```\n\n预期响应：`{\"status\":\"ok\"}`\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活检查 |\n| `GET /readyz` 或 `GET /ready` | 就绪检查 |\n\n资料来源：[README.md:50-55]()\n\n## 服务架构\n\n```mermaid\ngraph TD\n    A[客户端] --> B[Statewave API<br/>:8100]\n    B --> C[PostgreSQL<br/>Database]\n    B --> D[LLM Provider<br/>LiteLLM]\n    B --> E[Embedding Provider]\n    \n    F[Connectors] --> B\n    G[SDK] --> B\n    \n    style B fill:#e1f5fe\n    style C fill:#f3e5f5\n```\n\n## API 基础使用\n\n### 文档界面\n\n| 地址 | 说明 |\n|------|------|\n| `http://localhost:8100/docs` | OpenAPI (Swagger) 文档 |\n| `http://localhost:8100/redoc` | ReDoc 文档 |\n\n### 核心 API 端点\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄入单个事件（仅追加） |\n| `POST` | `/v1/episodes/batch` | 批量摄入最多 100 个事件 |\n| `POST` | `/v1/memories/compile` | 从事件编译记忆（幂等） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n| `POST` | `/v1/context` | 组装带 token 限制的上下文包 |\n| `GET` | `/v1/timeline` | 按时间线查看主题历史 |\n| `GET` | `/v1/subjects` | 列出已知主题及其事件/记忆计数 |\n| `DELETE` | `/v1/subjects/{id}` | 永久删除主题的所有数据 |\n\n资料来源：[README.md:40-45]()\n\n### 基本请求示例\n\n**摄入事件：**\n\n```bash\ncurl -X POST http://localhost:8100/v1/episodes \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-Tenant-ID: default\" \\\n  -d '{\n    \"subject_id\": \"user-123\",\n    \"source\": \"api\",\n    \"type\": \"conversation\",\n    \"payload\": {\n      \"role\": \"user\",\n      \"content\": \"如何部署 Statewave？\"\n    },\n    \"session_id\": \"session-001\"\n  }'\n```\n\n**搜索记忆：**\n\n```bash\ncurl \"http://localhost:8100/v1/memories/search?query=部署\" \\\n  -H \"X-Tenant-ID: default\"\n```\n\n## 版本管理\n\nStatewave 支持指定版本部署：\n\n```bash\nSTATEWAVE_VERSION=0.7.0 docker compose up -d\n```\n\n| 标签格式 | 含义 |\n|----------|------|\n| `latest` | main 分支最新代码 |\n| `X.Y.Z` | 语义化版本发布 |\n| `X.Y` | 所属小版本的最新版本 |\n| `X` | 所属大版本的最新版本 |\n| `sha-<7>` | 特定提交 |\n\n资料来源：[DOCKER.md:25-35]()\n\n## 运行测试\n\n```bash\n# 单元测试（无需数据库）\npytest tests/test_*.py -v\n\n# 集成测试（需要 PostgreSQL）\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\npytest tests/integration/ -v\n\n# 运行全部测试\npytest tests/ -v\n```\n\n资料来源：[README.md:180-190]()\n\n## 完整配置选项\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接 URL，必填 |\n| `STATEWAVE_PORT` | `8100` | 服务端口 |\n| `STATEWAVE_API_KEY` | — | API 密钥认证 |\n| `STATEWAVE_LITELLM_API_KEY` | — | LiteLLM API 密钥 |\n| `STATEWAVE_LITELLM_BASE_URL` | — | LiteLLM 基础 URL |\n| `STATEWAVE_EMBEDDING_PROVIDER` | `litellm` | 嵌入提供者（litellm/stub） |\n| `STATEWAVE_COMPILER_TYPE` | `llm` | 编译器类型（llm/heuristic） |\n| `STATEWAVE_RATE_LIMIT_PER_MIN` | `60` | 每IP每分钟请求限制（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略（distributed/memory） |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_WEBHOOK_TIMEOUT` | `5.0` | Webhook 超时时间（秒） |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离 Header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 Header |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 上下文组装默认 token 预算 |\n| `STATEWAVE_CORS_ORIGINS` | `[\"*\"]` | 允许的 CORS 来源 |\n\n资料来源：[README.md:155-175]()\n\n## 下一步\n\n- 查看 [API v1 完整契约](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n- 阅读[部署指南](https://github.com/smaramwbc/statewave-docs/blob/main/deployment/guide.md)\n- 了解 [Connectors 生态系统](https://github.com/smaramwbc/statewave-connectors)\n- 查看[架构文档](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/overview.md)\n\n---\n\n<a id='p-arch-overview'></a>\n\n## 系统架构概览\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [API 路由参考](#p-api-routes), [服务层实现](#p-services)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/app.py](https://github.com/smaramwbc/statewave/blob/main/server/app.py)\n- [server/core/config.py](https://github.com/smaramwbc/statewave/blob/main/server/core/config.py)\n- [server/core/dependencies.py](https://github.com/smaramwbc/statewave/blob/main/server/core/dependencies.py)\n- [server/api/__init__.py](https://github.com/smaramwbc/statewave/blob/main/server/api/__init__.py)\n- [server/db/engine.py](https://github.com/smaramwbc/statewave/blob/main/server/db/engine.py)\n- [README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n</details>\n\n# 系统架构概览\n\n## 1. 概述\n\nStatewave 是一个自托管的长期记忆管理系统，专为 AI Agent 设计，旨在帮助 Agents 跨越会话边界保持上下文连贯性。该系统通过摄取事件片段（Episodes）、编译记忆（Memories）、并提供智能检索上下文构建能力，使 AI Agent 能够在多轮对话中持续学习和适应。\n\n当前版本：v0.8.0，采用 AGPL-3.0 开源协议。资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n## 2. 核心设计理念\n\nStatewave 的架构围绕三个核心概念展开：\n\n| 概念 | 说明 |\n|------|------|\n| **Episode（事件片段）** | 原子化的输入单元，代表一次交互、一条消息或一个外部事件 |\n| **Memory（记忆）** | 从 Episodes 编译提取的结构化知识，具有时间有效性和置信度 |\n| **Subject（主体）** | 记忆归属的实体（如客户、用户、项目），实现数据隔离 |\n\n系统支持两种编译模式：LLM 编译（语义理解）和 Heuristic 编译（规则提取）。资料来源：[server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n## 3. 系统架构图\n\n```mermaid\ngraph TB\n    subgraph 接入层\n        API[REST API v1]\n        DOCS[OpenAPI / Swagger]\n        REDOC[ReDoc]\n    end\n\n    subgraph 应用层\n        EP[Episode 管理]\n        MEM[Memory 管理]\n        CTX[Context 构建]\n        TIMELINE[Timeline 服务]\n        SNAP[Snapshot 服务]\n        ADMIN[Admin API]\n    end\n\n    subgraph 服务层\n        COMPILER[编译引擎]\n        RANKER[排名服务]\n        SEARCH[搜索服务]\n    end\n\n    subgraph 数据层\n        DB[(PostgreSQL)]\n        CACHE[缓存层]\n    end\n\n    API --> EP\n    API --> MEM\n    API --> CTX\n    API --> TIMELINE\n    API --> SNAP\n    API --> ADMIN\n\n    EP --> COMPILER\n    MEM --> RANKER\n    CTX --> RANKER\n    CTX --> SEARCH\n\n    COMPILER --> DB\n    RANKER --> DB\n    SEARCH --> DB\n    TIMELINE --> DB\n    SNAP --> DB\n```\n\n## 4. 技术栈\n\n| 层级 | 技术选型 |\n|------|----------|\n| Web 框架 | FastAPI |\n| 数据库 | PostgreSQL + asyncpg |\n| ORM | SQLAlchemy (async) |\n| 编译后端 | LiteLLM (支持多种 LLM 提供商) |\n| 部署方式 | Docker Compose / Helm |\n| 认证 | API Key / X-Tenant-ID 多租户隔离 |\n\n资料来源：[DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n\n## 5. API 架构\n\n### 5.1 主要端点\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄入单个事件片段 |\n| `POST` | `/v1/episodes/batch` | 批量摄入事件片段（最多100个） |\n| `POST` | `/v1/memories/compile` | 编译记忆（幂等操作） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n| `POST` | `/v1/context` | 组装带排名的 token 受限上下文包 |\n| `GET` | `/v1/timeline` | 主体时间线 |\n| `GET` | `/v1/subjects` | 列出已知主体及事件/记忆计数 |\n| `DELETE` | `/v1/subjects/{id}` | 删除主体所有数据 |\n| `POST` | `/v1/resolutions` | 跟踪会话解决状态 |\n| `GET` | `/v1/resolutions` | 列出主体解决方案 |\n| `POST` | `/v1/handoff` | 生成紧凑的交接上下文包 |\n| `GET` | `/v1/subjects/{id}/health` | 健康评分及可解释因素 |\n| `GET` | `/v1/subjects/{id}/sla` | SLA 指标 |\n\n资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n### 5.2 健康检查端点\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活探针 |\n| `GET /readyz` 或 `GET /ready` | 就绪探针 |\n\n## 6. 数据模型\n\n### 6.1 核心实体关系\n\n```mermaid\nerDiagram\n    SUBJECT ||--o{ EPISODE : contains\n    SUBJECT ||--o{ MEMORY : owns\n    EPISODE ||--o{ MEMORY : contributes_to\n    SUBJECT ||--o{ RESOLUTION : tracks\n    SUBJECT ||--o| SNAPSHOT : preserves\n```\n\n### 6.2 Episode 数据结构\n\n事件片段是系统的原子输入单元，包含：\n\n```python\n{\n    \"id\": \"uuid\",\n    \"subject_id\": \"string\",\n    \"source\": \"string\",           # 来源标识 (e.g., \"api\", \"github\", \"slack\")\n    \"type\": \"string\",            # 类型 (e.g., \"chat\", \"issue\", \"doc_section\")\n    \"payload\": {\n        \"text\": \"string\",\n        \"messages\": [...],\n        \"event_time\": \"datetime\"  # 可选的显式时间戳\n    },\n    \"metadata\": {},\n    \"provenance\": {\n        \"content_hash\": \"string\",\n        \"pack_version\": \"int\"\n    },\n    \"occurred_at\": \"datetime\",\n    \"created_at\": \"datetime\",\n    \"session_id\": \"string | null\"\n}\n```\n\n资料来源：[server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n### 6.3 Memory 数据结构\n\n记忆从事件编译而来，具有时间有效性和置信度：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 唯一标识 |\n| `subject_id` | string | 归属主体 |\n| `kind` | string | 记忆类型（如 episode_summary, profile_fact） |\n| `content` | string | 记忆内容 |\n| `summary` | string | 内容摘要 |\n| `confidence` | float | 置信度 0.0-1.0 |\n| `valid_from` | datetime | 有效起始时间 |\n| `valid_to` | datetime | 有效结束时间（可选） |\n| `source_episode_ids` | list[UUID] | 来源事件片段 |\n| `status` | string | 状态（active, superseded） |\n| `sensitivity_labels` | list[string] | 敏感标签 |\n\n资料来源：[server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n## 7. 服务层架构\n\n### 7.1 编译引擎\n\n编译引擎负责将 Episodes 转换为 Memories，支持两种模式：\n\n```mermaid\ngraph LR\n    A[Episodes] --> B{编译模式}\n    B -->|Heuristic| C[规则提取]\n    B -->|LLM| D[语义理解]\n    C --> E[Memories]\n    D --> E\n```\n\n**Heuristic 编译**：基于规则提取摘要和配置事实\n\n- `episode_summary`：从文本提取摘要，置信度 0.8\n- `profile_fact`：提取配置类事实，置信度 0.6\n\n资料来源：[server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n### 7.2 上下文构建服务\n\n上下文构建服务（Context Service）负责根据查询组装最优上下文：\n\n```mermaid\ngraph TB\n    Q[用户查询] --> S[搜索相关Memories和Episodes]\n    S --> SC[评分计算]\n    SC --> R[相关性评分]\n    R --> RANK[排名服务]\n    RANK --> TB[Token预算约束]\n    TB --> CTX[组装上下文包]\n```\n\nContext Service 内部使用 `_ScoredItem` 类管理评分：\n\n```python\nclass _ScoredItem:\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n资料来源：[server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n\n### 7.3 快照服务\n\n快照服务支持主体的完整备份和恢复：\n\n| 操作 | 说明 |\n|------|------|\n| 创建快照 | 导出主体的所有 Episodes、Memories、Resolutions |\n| 恢复快照 | 支持时间偏移重放，可重建历史状态 |\n| 增量更新 | 保留 `restored_from_snapshot` 元数据 |\n\n资料来源：[server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n## 8. 时间线服务\n\n时间线服务（Timeline Service）提供会话视图的事件合并展示：\n\n```mermaid\ngraph TB\n    subgraph 事件类型\n        EE[Episode Event]\n        RE[Resolution Event]\n    end\n    \n    subgraph 时间线事件\n        TEE[TimelineEpisodeEvent]\n        TRE[TimelineResolutionEvent]\n    end\n    \n    EE --> TEE\n    RE --> TRE\n    TEE --> MERGE[合并排序]\n    TRE --> MERGE\n    MERGE --> RESP[SessionTimelineResponse]\n```\n\n关键指标计算：\n- `first_response_seconds`：首次响应时间\n- `resolution_seconds`：解决时间\n- `first_response_breached`：是否超出 SLA 首次响应阈值\n- `resolution_breached`：是否超出 SLA 解决时间阈值\n\n资料来源：[server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n## 9. 多租户架构\n\nStatewave 采用应用层多租户隔离：\n\n| 配置项 | 默认值 | 说明 |\n|--------|--------|------|\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 租户隔离 header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 header |\n| 隔离方式 | 查询作用域 | 基于 tenant_id 的数据过滤 |\n\n**当前限制**：\n- 限流基于 IP 地址，未实现 per-tenant 或 per-API-key 限流\n- 多租户采用应用层隔离，非 PostgreSQL Row-Level Security (RLS)\n\n资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n## 10. 配置管理\n\n### 10.1 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接串（必需） |\n| `STATEWAVE_LITELLM_API_KEY` | — | LLM API 密钥 |\n| `STATEWAVE_API_KEY` | — | 服务认证密钥 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每 IP 每分钟请求数 |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略 |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认上下文 token 预算 |\n\n### 10.2 编译模式配置\n\n| 模式 | 配置值 | 适用场景 |\n|------|--------|----------|\n| LLM 编译 | `compiler.type=llm` | 生产环境，语义理解 |\n| Heuristic 编译 | `compiler.type=heuristic` | Demo/无 LLM 模式 |\n\n资料来源：[helm/statewave/README.md](https://github.com/smaramwbc/statewave/blob/main/helm/statewave/README.md)\n\n## 11. 部署架构\n\n### 11.1 Docker 部署\n\n```yaml\nservices:\n  statewave:\n    image: statewavedev/statewave:latest\n    ports: [\"8100:8100\"]\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n```\n\n### 11.2 Kubernetes 部署\n\n使用 Helm Chart 部署，包含：\n- Pre-install Job：运行数据库迁移（`alembic upgrade head`）\n- Pre-upgrade Job：升级时重复迁移\n- 支持 `existingSecret` 引用敏感配置\n\n资料来源：[DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n\n## 12. 启动流程\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant API as FastAPI App\n    participant DB as PostgreSQL\n    participant Migrator as Alembic\n    \n    Client->>API: 启动请求\n    API->>Migrator: alembic upgrade head\n    Migrator->>DB: 执行迁移\n    DB-->>Migrator: 迁移完成\n    Migrator-->>API: 就绪\n    API-->>Client: 服务可用\n```\n\n## 13. 外部集成\n\n### 13.1 连接器生态\n\nStatewave 提供官方连接器将外部数据源摄入为 Episodes：\n\n| 来源 | 记忆形态 | 状态 |\n|------|----------|------|\n| MCP Server | Agent 记忆 | ✅ 已发布 |\n| GitHub | Issues, PRs, Releases | ✅ 已发布 |\n| Markdown | 文档/决策记忆 | ✅ 已发布 |\n| Slack | 对话记忆 | ✅ 已发布 |\n\n### 13.2 SDK 支持\n\n提供 Python SDK 支持自定义摄入路径，连接器独立安装：\n\n```bash\nnpm install @statewavedev/connectors-github\nnpm install @statewavedev/connectors-markdown\nnpm install @statewavedev/mcp-server\n```\n\n## 14. 安全特性\n\n| 特性 | 说明 |\n|------|------|\n| API Key 认证 | 通过 `Authorization: Bearer <key>` |\n| 多租户隔离 | 基于 `X-Tenant-ID` header |\n| 敏感标签 | Memory 支持 `sensitivity_labels` |\n| 数据删除 | DELETE `/v1/subjects/{id}` 永久删除 |\n\n## 15. 测试架构\n\n| 测试类型 | 命令 | 依赖 |\n|----------|------|------|\n| 单元测试 | `pytest tests/test_*.py -v` | 无 DB |\n| 集成测试 | `pytest tests/integration/ -v` | PostgreSQL |\n| 全部测试 | `pytest tests/ -v` | PostgreSQL |\n\n集成测试数据库配置：\n```bash\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\n```\n\n## 16. 总结\n\nStatewave 采用分层架构设计，从底层的 PostgreSQL 数据持久化，到服务层的编译引擎、上下文构建、排名服务，再到 API 接入层，构成了一个完整的 AI Agent 记忆管理系统。其核心优势包括：\n\n1. **事件驱动的摄入**：支持多种来源（API、连接器、Webhook）\n2. **灵活的编译引擎**：兼容 LLM 和 Heuristic 两种模式\n3. **智能上下文组装**：基于 token 预算的排名检索\n4. **企业级功能**：多租户、快照、SLA 追踪\n5. **可观测性**：健康检查、Webhook 回调\n\n系统当前处于活跃开发状态（v0.8.0），建议生产环境使用语义版本号固定部署。\n\n---\n\n<a id='p-data-flow'></a>\n\n## 数据流与生命周期\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [Episode 管理](#p-episodes), [编译器系统](#p-compiler), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py)\n- [server/api/memories.py](https://github.com/smaramwbc/statewave/blob/main/server/api/memories.py)\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/compiler.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compiler.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/db/tables.py](https://github.com/smaramwbc/statewave/blob/main/server/db/tables.py)\n</details>\n\n# 数据流与生命周期\n\nStatewave 是一个长期记忆管理系统，其核心功能围绕 **Episode（事件）** → **Memory（记忆）** → **Context（上下文）** 的数据流展开。本页详细说明这三个核心实体的生命周期、数据转换过程，以及系统如何管理时间敏感信息的有效性。\n\n---\n\n## 系统架构概览\n\nStatewave 的数据流遵循经典的 ETL（Extract-Transform-Load）模式，但增加了时间维度的管理。系统接收外部事件作为 Episode，经过编译器（Compiler）处理后生成 Memory，最终通过 Context 服务组装为可供 AI Agent 使用的上下文包。\n\n```mermaid\ngraph TD\n    subgraph 数据源\n        E1[聊天/对话]\n        E2[GitHub Events]\n        E3[Slack 消息]\n        E4[MCP Server]\n        E5[Markdown 文档]\n    end\n    \n    subgraph 摄入层\n        EP[Episode 输入]\n    end\n    \n    subgraph 存储层\n        DB[(PostgreSQL)]\n    end\n    \n    subgraph 处理层\n        HC[Heuristic 编译器]\n        LC[LLM 编译器]\n    end\n    \n    subgraph 查询层\n        CTX[Context 上下文服务]\n        SCH[记忆搜索]\n        TLM[时间线查询]\n    end\n    \n    E1 --> EP\n    E2 --> EP\n    E3 --> EP\n    E4 --> EP\n    E5 --> EP\n    \n    EP --> DB\n    HC --> DB\n    LC --> DB\n    DB --> CTX\n    DB --> SCH\n    DB --> TLM\n```\n\n---\n\n## Episode 生命周期\n\n### 什么是 Episode\n\nEpisode 是 Statewave 中的**原始事件单元**，代表一次不可变的事实记录。它可以是客户对话、代码提交、文档更新、问题报告等任何有意义的事件。资料来源：[server/services/compilers/heuristic.py:1-50]()\n\n### Episode 的数据结构\n\n每个 Episode 包含以下核心字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 全局唯一标识符 |\n| `subject_id` | UUID | 所属主体 ID |\n| `session_id` | UUID | 关联的会话 ID（可选） |\n| `source` | string | 来源标识（mcp, github, slack 等） |\n| `type` | string | 事件类型（message, issue, pr 等） |\n| `payload` | JSON | 原始载荷数据 |\n| `provenance` | JSON | 来源元数据（内容哈希等） |\n| `occurred_at` | datetime | 事件发生时间 |\n| `created_at` | datetime | 记录创建时间 |\n\n资料来源：[server/db/tables.py]() 中的 `EpisodeRow` 定义\n\n### Episode 的时间锚定\n\n时间锚定（Temporal Anchoring）是 Episode 处理的关键环节。系统按以下优先级确定记忆的 `valid_from` 时间：\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"Return the best-effort temporal anchor for memories derived from\n    this episode.\n\n    Priority:\n      1. `payload.event_time` — explicit override set by the client\n         (e.g. a connector replaying historical data sets this to the\n         actual event date, not the POST date).\n      2. `payload.messages[0].timestamp` — the first-message timestamp\n         on chat-shaped payloads. This is what LoCoMo, Slack, Zendesk\n         etc emit naturally; preserving it as `valid_from`\"\"\"\n```\n\n资料来源：[server/services/compilers/heuristic.py:80-95]()\n\n这种设计确保了：\n- 连接器回放历史数据时使用真实事件时间\n- 实时聊天数据保留消息时间戳\n- 没有明确时间戳时回退到记录创建时间\n\n### Episode 的创建与批量摄入\n\n```mermaid\nsequenceDiagram\n    participant C as 客户端\n    participant API as /v1/episodes\n    participant DB as 数据库\n    \n    C->>API: POST /v1/episodes (单个)\n    API->>DB: Insert EpisodeRow\n    DB-->>API: 返回 ID\n    API-->>C: 201 Created\n    \n    Note over C,API: 批量摄入\n    C->>API: POST /v1/episodes/batch (最多100个)\n    API->>DB: Batch Insert\n    DB-->>API: 返回 ID 列表\n    API-->>C: 201 Created\n```\n\nAPI 支持单条和批量（最多 100 条）摄入。批量接口保证原子性——要么全部成功，要么全部回滚。资料来源：[README.md:API 文档]()\n\n---\n\n## Memory 生命周期\n\n### 编译过程概述\n\nMemory 是从 Episode 编译而来的**派生数据**，代表从原始事件中提取的结构化知识。编译过程可以是：\n\n1. **Heuristic 编译器**：基于规则的内容提取，速度快，适合结构化数据\n2. **LLM 编译器**：基于语言模型的语义理解，适合非结构化对话\n\n```mermaid\ngraph LR\n    subgraph 输入\n        EP1[Episode 1]\n        EP2[Episode 2]\n        EP3[Episode N]\n    end\n    \n    subgraph 编译\n        CMP[Compiler]\n        EP1 --> CMP\n        EP2 --> CMP\n        EP3 --> CMP\n    end\n    \n    subgraph 输出\n        MEM1[episode_summary]\n        MEM2[profile_fact]\n        MEM3[decision]\n        MEM4[preference]\n    end\n    \n    CMP --> MEM1\n    CMP --> MEM2\n    CMP --> MEM3\n    CMP --> MEM4\n```\n\n资料来源：[server/services/compiler.py]()\n\n### Heuristic 编译器的提取规则\n\nHeuristic 编译器从 Episode 内容中提取以下类型的 Memory：\n\n| Memory 类型 | 说明 | 置信度 |\n|-------------|------|--------|\n| `episode_summary` | 事件摘要 | 0.8 |\n| `profile_fact` | 用户画像事实 | 0.6 |\n| `decision` | 关键决策记录 | 0.7 |\n| `preference` | 用户偏好 | 0.6 |\n\n资料来源：[server/services/compilers/heuristic.py:40-70]()\n\n### Memory 的时间有效性\n\n每个 Memory 都有 `valid_from` 和 `valid_to` 字段定义其有效时间范围：\n\n```python\nvalid_to=compute_valid_to(\"episode_summary\", ep_valid_from, ttl)\n```\n\n资料来源：[server/services/compilers/heuristic.py:55]()\n\n时间有效性的设计支持：\n- **时间衰减**：过期的记忆自动降低相关性\n- **快照隔离**：历史时间点的记忆可以被完整保留\n- **状态追踪**：偏好和事实的变化可追溯\n\n### Memory 的来源追溯\n\nMemory 通过 `source_episode_ids` 字段维护与源 Episode 的关联关系：\n\n```python\nsource_episode_ids=[ep.id]\n```\n\n资料来源：[server/services/compilers/heuristic.py:45]()\n\n这种设计支持：\n- **反向查询**：从 Memory 找到原始 Episode\n- **归因分析**：了解记忆的来源\n- **一致性验证**：确保记忆与源事件一致\n\n```mermaid\ngraph LR\n    MEM[Memory] -->|source_episode_ids| EP1[Episode]\n    MEM -->|source_episode_ids| EP2[Episode]\n    \n    API[\"/subjects/{id}/episodes/{episode_id}/citing-memories\"]\n    EP1 -->|反向查找| API\n    API -->|返回| M1[引用该Episode的Memories]\n```\n\n资料来源：[server/api/admin.py:list_citing_memories]()\n\n### 编译的幂等性\n\nMemory 编译是**幂等操作**——重复编译不会产生重复记忆。系统通过内容哈希（`provenance.content_hash`）识别已存在的记忆。资料来源：[scripts/docs_loader.py:60-70]()\n\n---\n\n## Context 上下文组装\n\n### Context 的作用\n\nContext 是最终交付给 AI Agent 的**上下文包**，它从多个 Memory 和 Episode 中组装出满足以下约束的内容：\n\n- **Token 受限**：总长度不超过配置的 token 上限\n- **相关性排序**：最相关的内容优先包含\n- **时间范围**：覆盖指定的时间窗口\n- **多样性**：避免内容重复\n\n资料来源：[server/services/context.py]()\n\n### Context 组装流程\n\n```mermaid\ngraph TD\n    START[POST /v1/context] --> Q[解析查询参数]\n    Q --> TS[时间范围过滤]\n    TS --> TK[Token 预算分配]\n    TK --> SR[语义搜索 Memory]\n    SR --> SC[得分排序]\n    SC --> TR[时间线补充 Episode]\n    TR --> AS[组装最终上下文]\n    AS --> END[返回 Context Bundle]\n```\n\n### Context 响应结构\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n    \n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n资料来源：[server/services/context.py:80-90]()\n\n响应包含：\n- `episodes`：相关时间线事件\n- `memories`：相关记忆\n- `score_breakdown`：评分明细\n\n---\n\n## Subject 主体管理\n\n### Subject 的作用\n\nSubject 是 Episode 和 Memory 的**拥有者**，代表一个独立的实体（如用户、企业、仓库等）。所有数据流都发生在 Subject 的作用域内。\n\n### Subject 的数据删除\n\n删除 Subject 会级联删除其所有关联数据：\n\n| 删除内容 | 影响 |\n|----------|------|\n| Episodes | 永久删除 |\n| Memories | 永久删除 |\n| Resolutions | 永久删除 |\n| Snapshots | 永久删除 |\n\n资料来源：[README.md:DELETE /v1/subjects/{id}]()\n\n---\n\n## Snapshot 快照机制\n\n### Snapshot 的用途\n\nSnapshot 提供了 Subject 状态的**时间点快照**，用于：\n\n- 灾难恢复\n- 状态迁移\n- 版本回滚\n- 测试数据准备\n\n资料来源：[server/services/snapshots.py]()\n\n### Snapshot 的创建流程\n\n```mermaid\ngraph TD\n    CREATE[创建 Snapshot] --> Q[查询 Subject 数据]\n    Q --> SE[收集 Episodes]\n    Q --> SM[收集 Memories]\n    Q --> SR[收集 Resolutions]\n    SE --> CPY[复制数据到快照主体]\n    SM --> CPY\n    SR --> CPY\n    CPY --> META[记录快照元数据]\n    META --> DONE[返回 Snapshot ID]\n```\n\n### Snapshot 的时间偏移\n\n恢复快照时，系统支持时间偏移（time_shift）以适应不同的目标环境：\n\n```python\nvalid_from=(mem_valid_from + time_shift) if mem_valid_from else None,\nvalid_to=(mem_valid_to + time_shift) if mem_valid_to else None,\ncreated_at=mem_created + time_shift,\nupdated_at=mem_updated + time_shift,\n```\n\n资料来源：[server/services/snapshots.py:restore_snapshot]()\n\n---\n\n## 数据导入导出\n\n### 导入流程\n\n```mermaid\ngraph LR\n    JSON[\"JSONL 格式数据\"] --> VAL{验证}\n    VAL -->|通过| EPI[导入 Episodes]\n    VAL -->|通过| MEM[导入 Memories]\n    EPI --> REMAP[重映射 Episode ID]\n    MEM --> REMAP\n    REMAP --> COMMIT[提交事务]\n    COMMIT --> DONE[返回导入结果]\n```\n\n### ID 保留策略\n\n导入时可以选择是否保留原始 ID：\n\n| 策略 | 说明 |\n|------|------|\n| `preserve_ids=True` | 保留原始 UUID |\n| `preserve_ids=False` | 生成新 UUID |\n\n资料来源：[server/services/backup.py:subject_import]()\n\n---\n\n## 状态流转总览\n\n```mermaid\nstateDiagram-v2\n    [*] --> Episodes: 摄入\n    Episodes --> Compilation: 触发编译\n    Compilation --> Memories: 生成记忆\n    Memories --> Context: 组装上下文\n    Context --> [*]: 交付 Agent\n    \n    Episodes --> Snapshot: 创建快照\n    Snapshot --> [*]: 备份\n    \n    [*] --> Import: 导入数据\n    Import --> Episodes: 恢复 Episodes\n    Import --> Memories: 恢复 Memories\n```\n\n---\n\n## 核心配置参数\n\n| 参数 | 位置 | 说明 |\n|------|------|------|\n| `valid_from` | Memory | 有效起始时间 |\n| `valid_to` | Memory | 有效结束时间 |\n| `confidence` | Memory | 置信度 (0.0-1.0) |\n| `status` | Memory | 状态 (active/inactive) |\n| `time_shift` | Snapshot restore | 时间偏移量 |\n\n---\n\n## 总结\n\nStatewave 的数据流设计体现了以下核心原则：\n\n1. **不可变性优先**：Episode 作为原始事实永不修改\n2. **派生透明**：Memory 明确记录来源 Episode\n3. **时间感知**：所有实体都携带时间维度信息\n4. **幂等操作**：编译和导入操作可安全重复\n5. **原子性保证**：批量操作的事务完整性\n\n这种设计使得系统能够可靠地追踪信息来源、恢复历史状态，并在保持高性能的同时支持复杂的时间范围查询。\n\n---\n\n<a id='p-episodes'></a>\n\n## Episode 管理\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py) *(未在上下文中获取)*\n- [server/schemas/requests.py](https://github.com/smaramwbc/statewave/blob/main/server/schemas/requests.py) *(未在上下文中获取)*\n- [server/schemas/responses.py](https://github.com/smaramwbc/statewave/blob/main/server/schemas/responses.py) *(未在上下文中获取)*\n- [server/domain/models.py](https://github.com/smaramwbc/statewave/blob/main/server/domain/models.py) *(未在上下文中获取)*\n\n**补充参考文件（已在上下文中获取）：**\n\n- [scripts/docs_loader.py](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n- [scripts/bootstrap_docs_pack.py](https://github.com/smaramwbc/statewave/blob/main/scripts/bootstrap_docs_pack.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n</details>\n\n# Episode 管理\n\n## 概述\n\nEpisode（事件）是 Statewave 记忆系统的**原子数据单元**，代表与特定主题（Subject）相关的每一次交互或事件记录。Episode 采用**仅追加（append-only）**模式写入，不可直接修改，确保了事件溯源的完整性。\n\nStatewave 通过 Connectors 从多种数据源收集 Episodes，这些事件随后被编译（Compile）为结构化的 Memory（记忆），供 Agent 在推理时检索。\n\n**核心职责：**\n\n| 职责 | 说明 |\n|------|------|\n| 事件采集 | 接收并持久化来自各类 Connector 的事件数据 |\n| 溯源追踪 | 记录每个 Episode 的来源、类型和元数据 |\n| 时间锚定 | 支持显式事件时间和隐式时间戳 |\n| 关系映射 | 为后续 Memory 编译建立来源关联 |\n\n资料来源：[README.md:1-50](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## Episode 数据模型\n\n### 基本结构\n\n```python\n@dataclass(frozen=True)\nclass DocSection:\n    \"\"\"One ingestible unit. Maps 1:1 to an episode.\"\"\"\n    doc_path: str\n    title: str\n    heading_path: tuple[str, ...]\n    body: str\n    content_hash: str\n    url: str\n```\n\n### Episode 载荷格式\n\n```json\n{\n  \"title\": \"事件标题\",\n  \"heading_path\": [\"父标题\", \"子标题\"],\n  \"breadcrumb\": \"父标题 › 子标题 › 事件标题\",\n  \"doc_path\": \"architecture/overview.md\",\n  \"url\": \"https://statewave.ai/docs/...\",\n  \"text\": \"事件完整文本内容\",\n  \"messages\": [\n    {\n      \"role\": \"user|assistant|system\",\n      \"content\": \"消息内容\",\n      \"timestamp\": \"2024-01-15T10:30:00Z\"\n    }\n  ],\n  \"event_time\": \"2024-01-15T09:00:00Z\"\n}\n```\n\n### Provenance（溯源信息）\n\n每个 Episode 携带不可变的溯源元数据，用于去重和数据一致性校验：\n\n```python\n{\n    \"doc_path\": \"architecture/overview.md\",\n    \"content_hash\": \"sha256:abc123...\",  # 内容确定性哈希\n    \"pack_version\": 1\n}\n```\n\n资料来源：[scripts/docs_loader.py:30-60](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n\n---\n\n## API 端点\n\n### Episode 写入\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 写入单个 Episode（仅追加） |\n| `POST` | `/v1/episodes/batch` | 批量写入最多 100 个 Episodes |\n\n### Episode 查询\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/v1/subjects/{id}/episodes` | 获取主题的所有 Episodes |\n| `GET` | `/v1/subjects/{id}/episodes/{episode_id}` | 获取单个 Episode 详情 |\n| `GET` | `/v1/subjects/{id}/episodes/{episode_id}/citing-memories` | 反向查询：引用此 Episode 的所有 Memories |\n\n### Episode 删除\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `DELETE` | `/v1/subjects/{id}` | 删除主题及其所有关联 Episodes |\n\n资料来源：[README.md:50-80](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## Episode 类型与来源\n\nStatewave 支持多种 Episode 来源（Connector），每种来源定义了不同的 Memory 形状：\n\n| 来源 | 类型 | 说明 | 状态 |\n|------|------|------|------|\n| MCP server | `agent_memory` | Copilot / Claude / Cursor / agent 记忆 | ✅ 已发布 |\n| GitHub | `repo_memory` | Issues, PRs, reviews, releases | ✅ 已发布 |\n| Markdown | `doc_section` | 本地文档、ADR、RFC | ✅ 已发布 |\n| Slack | `channel_event` | 频道消息事件 | ✅ 已发布 |\n\n资料来源：[README.md:80-95](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## 时间锚定机制\n\nEpisode 编译为 Memory 时需要确定有效时间范围（valid_from / valid_to）。系统按以下优先级确定时间锚点：\n\n```mermaid\ngraph TD\n    A[Episode 时间锚定] --> B{存在 payload.event_time?}\n    B -->|是| C[使用 event_time]\n    B -->|否| D{存在 messages[0].timestamp?}\n    D -->|是| E[使用首条消息时间戳]\n    D -->|否| F[使用 Episode 创建时间]\n    \n    C --> G[计算 valid_to]\n    E --> G\n    F --> G\n    \n    G --> H[基于 kind 确定 TTL]\n    H --> I[Memory 有效时间范围]\n```\n\n**TTL 计算规则：**\n\n| Memory Kind | 默认 TTL |\n|-------------|----------|\n| `episode_summary` | 较长（持久化知识） |\n| `profile_fact` | 中等（用户偏好） |\n| 其他 | 根据配置 |\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"Return the best-effort temporal anchor for memories derived from\n    this episode.\n\n    Priority:\n      1. `payload.event_time` — explicit override set by the client\n      2. `payload.messages[0].timestamp` — first-message timestamp\n      3. Episode creation timestamp (fallback)\n    \"\"\"\n```\n\n资料来源：[server/services/compilers/heuristic.py:80-100](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n---\n\n## Episode 编译流程\n\nEpisode 本身是不可变的原始数据。通过编译过程，系统从中提取结构化记忆：\n\n```mermaid\ngraph LR\n    A[Episode] --> B[Heuristic Compiler]\n    B --> C[Episode Summary]\n    B --> D[Profile Facts]\n    B --> E[Custom Extractions]\n    \n    C --> F[Memory Row]\n    D --> F\n    E --> F\n    \n    F --> G[source_episode_ids = [ep.id]]\n```\n\n**编译结果写入 MemoryRow：**\n\n```python\nMemoryRow(\n    id=uuid.uuid4(),\n    subject_id=ep.subject_id,\n    kind=\"episode_summary\",      # 记忆类型\n    content=text[:500],          # 完整内容（截断）\n    summary=text[:200],          # 摘要\n    confidence=0.8,              # 置信度\n    valid_from=ep_valid_from,\n    valid_to=compute_valid_to(...),\n    source_episode_ids=[ep.id], # 溯源关联\n    metadata_={},\n    status=\"active\",\n)\n```\n\n资料来源：[server/services/compilers/heuristic.py:50-75](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n---\n\n## Snapshot 与 Episode 迁移\n\nSnapshot 功能允许完整导出/恢复 Subject 的 Episodes 和 Memories：\n\n```mermaid\ngraph TD\n    A[Snapshot 创建] --> B[克隆 Episodes]\n    B --> C[克隆 Memories]\n    C --> D[克隆 Resolutions]\n    D --> E[保存 Snapshot 元数据]\n    \n    F[Snapshot 恢复] --> G[时间偏移调整]\n    G --> H[重建 Episode 关系]\n    H --> I[更新 source_episode_ids 映射]\n```\n\n**Snapshot 中的 Episode 克隆：**\n\n```python\n# Episode 克隆时保留原始 session_id 和时间戳\nEpisodeRow(\n    id=uuid.uuid4(),\n    subject_id=snapshot_subject,\n    session_id=ep.session_id,\n    source=ep.source,\n    type=ep.type,\n    payload=ep.payload,\n    metadata_=ep.metadata_,\n    provenance=ep.provenance,\n    occurred_at=ep.occurred_at + time_shift,  # 时间偏移\n    created_at=ep_created + time_shift,\n)\n```\n\n**Snapshot 恢复标记：**\n\n```python\nmetadata_={\n    \"restored_from_snapshot\": str(snapshot_id),\n    # ...\n}\n```\n\n资料来源：[server/services/snapshots.py:100-150](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n---\n\n## 管理 API\n\n### 引用关系查询\n\n```python\n@router.get(\n    \"/subjects/{subject_id}/episodes/{episode_id}/citing-memories\",\n    response_model=MemoryListResponse,\n)\nasync def list_citing_memories(\n    subject_id: str,\n    episode_id: str,\n    tenant_id: str | None = Query(None),\n    limit: int = Query(50, ge=1, le=200),\n    offset: int = Query(0, ge=0),\n):\n    \"\"\"List memories that cite (were derived from) a specific episode.\n    \n    This enables reverse provenance lookup: from an episode, find all\n    memories that list it in their source_episode_ids.\n    \"\"\"\n```\n\n**查询逻辑：**\n\n```python\n# 验证 episode_id 格式\nepisode_uuid = uuid_module.UUID(episode_id)\n\n# 查询 source_episode_ids 数组包含该 episode_id 的所有 memories\nbase = select(MemoryRow).where(\n    func.array_contains(MemoryRow.source_episode_ids, episode_id)\n)\n```\n\n资料来源：[server/api/admin.py:1-50](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n\n---\n\n## Bootstrap 与批量导入\n\nStatewave 提供脚本工具将外部文档批量转换为 Episodes：\n\n### docs_loader.py\n\n将 Markdown 文档按标题层级（H1/H2/H3）拆分为独立的 DocSection，每个 Section 对应一个 Episode：\n\n```python\nMANIFEST: tuple[str, ...] = (\n    \"README.md\",\n    \"getting-started.md\",\n    \"product.md\",\n    \"architecture/overview.md\",\n    \"architecture/repo-map.md\",\n    # ... 更多文档\n)\n```\n\n**特性：**\n\n- 使用 SHA256 内容哈希实现幂等性\n- 每个 Section 生成确定性 slug 用于 URL 生成\n- 支持 re-run 检测未变更内容\n\n### bootstrap_docs_pack.py\n\n```bash\n# 基本用法\npython -m scripts.bootstrap_docs_pack\n\n# 指定文档路径\npython -m scripts.bootstrap_docs_pack --docs-path /path/to/docs\n\n# 清空重建\npython -m scripts.bootstrap_docs_pack --purge\n\n# 仅解析不写入\npython -m scripts.bootstrap_docs_pack --dry-run\n```\n\n**环境变量：**\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_URL` | `http://localhost:8100` | API 地址 |\n| `STATEWAVE_API_KEY` | — | 可选认证密钥 |\n| `STATEWAVE_DOCS_PATH` | sibling `statewave-docs` | 文档目录 |\n\n资料来源：[scripts/bootstrap_docs_pack.py:1-80](https://github.com/smaramwbc/statewave/blob/main/scripts/bootstrap_docs_pack.py)\n\n---\n\n## Episode 响应模型\n\n```python\nclass EpisodeResponse(BaseModel):\n    id: str\n    subject_id: str\n    source: str           # 来源：slack, github, mcp, docs 等\n    type: str             # 类型：doc_section, message, event 等\n    payload: dict         # 原始载荷\n    metadata: dict        # 额外元数据\n    provenance: dict      # 溯源信息\n    occurred_at: datetime # 事件发生时间\n    created_at: datetime  # 记录创建时间\n    session_id: str | None # 会话标识（可选）\n```\n\n资料来源：[server/api/timeline.py:20-35](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n---\n\n## 最佳实践\n\n### 1. 事件时间 vs 创建时间\n\n对于回放历史数据（如 Connectors 重放旧事件），应显式设置 `payload.event_time` 为实际事件发生时间：\n\n```json\n{\n  \"event_time\": \"2023-12-01T08:00:00Z\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"历史消息内容\",\n      \"timestamp\": \"2023-12-01T08:00:00Z\"\n    }\n  ]\n}\n```\n\n### 2. 批量写入优化\n\n单次批量写入限制为 100 个 Episodes，较大导入应分批处理：\n\n```python\nBATCH_SIZE = 50  # 推荐批次大小\n\nfor i in range(0, len(episodes), BATCH_SIZE):\n    batch = episodes[i:i + BATCH_SIZE]\n    await client.post(\"/v1/episodes/batch\", json=batch)\n```\n\n### 3. 内容哈希用于去重\n\n创建 Episodes 时包含确定性内容哈希，支持增量刷新：\n\n```python\ncontent_hash = hashlib.sha256(text.encode(\"utf-8\")).hexdigest()\n\nprovenance = {\n    \"content_hash\": content_hash,\n    \"pack_version\": PACK_VERSION\n}\n```\n\n资料来源：[scripts/docs_loader.py:70-90](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n\n---\n\n## 相关文档\n\n- [Memory 管理](./memory-management.md)\n- [Context 组装](./context-assembly.md)\n- [Connector 架构](./connector-architecture.md)\n- [Snapshot 功能](./snapshot-feature.md)\n\n---\n\n<a id='p-compiler'></a>\n\n## 编译器系统\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/services/compiler.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compiler.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/services/compilers/llm.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/llm.py)\n- [server/services/compile_jobs.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compile_jobs.py)\n- [server/services/compile_jobs_durable.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compile_jobs_durable.py)\n- [server/services/conflicts.py](https://github.com/smaramwbc/statewave/blob/main/server/services/conflicts.py)\n</details>\n\n# 编译器系统\n\n## 概述\n\n编译器系统（Compiler System）是 Statewave 的核心子系统，负责将原始的对话事件（Episodes）转化为结构化的记忆（Memories）。当新的对话片段被摄入系统后，编译器会分析这些事件，提取有价值的信息，生成可供后续检索和推理使用的记忆条目。\n\n编译过程是**幂等操作**（idempotent），这意味着对同一批事件重复编译不会产生副作用或重复数据。系统会追踪每个记忆的来源事件（`source_episode_ids`），确保记忆与原始事件之间的可追溯性。\n\n| 特性 | 说明 |\n|------|------|\n| 触发方式 | API 调用 `POST /v1/memories/compile` 或自动触发 |\n| 编译模式 | 启发式（heuristic）和 LLM 驱动两种模式 |\n| 输出产物 | MemoryRow 记录，包含多种记忆类型 |\n| 幂等性 | 重复编译安全，不会产生重复记忆 |\n\n资料来源：[README.md:1-30]()\n\n## 架构设计\n\n### 编译器类型\n\nStatewave 支持两种编译策略，可根据部署环境和技术要求选择合适的模式：\n\n| 编译模式 | 配置值 | 适用场景 | 依赖 |\n|----------|--------|----------|------|\n| 启发式编译 | `heuristic` | 演示环境、无 LLM 需求、本地开发 | 无外部依赖 |\n| LLM 编译 | `llm` | 生产环境、需要深度语义理解 | LLM API Key |\n\n```yaml\n# Helm 部署配置示例\ncompiler:\n  type: llm  # 或 heuristic\n```\n\n资料来源：[helm/statewave/README.md:1-20]()\n\n### 核心组件\n\n```\ngraph TD\n    A[Episode 摄入] --> B{编译模式选择}\n    B -->|heuristic| C[HeuristicCompiler]\n    B -->|llm| D[LLMCompiler]\n    C --> E[提取概要信息]\n    C --> F[提取 Profile Facts]\n    D --> G[语义分析与总结]\n    D --> H[关系抽取]\n    E --> I[MemoryRow 生成]\n    F --> I\n    G --> I\n    H --> I\n    I --> J[冲突检测]\n    J --> K[记忆合并/去重]\n    K --> L[持久化存储]\n```\n\n**主要组件职责：**\n\n| 组件 | 文件位置 | 职责 |\n|------|----------|------|\n| `Compiler` | `server/services/compiler.py` | 编译调度、模式路由 |\n| `HeuristicCompiler` | `server/services/compilers/heuristic.py` | 规则驱动的记忆提取 |\n| `LLMCompiler` | `server/services/compilers/llm.py` | 大语言模型驱动的语义理解 |\n| `CompileJob` | `server/services/compile_jobs.py` | 编译任务管理与队列 |\n| `CompileJobDurable` | `server/services/compile_jobs_durable.py` | 持久化编译任务支持 |\n| `ConflictResolver` | `server/services/conflicts.py` | 记忆冲突检测与消解 |\n\n## 编译流程\n\n### 完整工作流\n\n```\ngraph LR\n    A[收集未编译 Episodes] --> B{遍历 Episodes}\n    B --> C[确定时间锚点]\n    C --> D{编译模式}\n    D -->|heuristic| E[提取概要 + Facts]\n    D -->|llm| F[LLM 分析总结]\n    E --> G[生成 MemoryRows]\n    F --> G\n    G --> H[冲突检测]\n    H --> I{存在冲突?}\n    I -->|是| J[冲突消解]\n    I -->|否| K[直接写入]\n    J --> K\n    K --> L[更新编译状态]\n    L --> M{还有更多 Episodes?}\n    M -->|是| B\n    M -->|否| N[编译完成]\n```\n\n### 触发方式\n\n编译可以通过以下方式触发：\n\n1. **手动触发**：调用 `POST /v1/memories/compile` API\n2. **自动触发**：在摄入新 Episode 后自动启动编译\n3. **批量触发**：通过 `POST /v1/episodes/batch` 摄入多集后统一编译\n\n资料来源：[README.md:30-45]()\n\n## 启发式编译器\n\n### 概述\n\n启发式编译器（HeuristicCompiler）是一种基于规则的信息提取引擎，无需外部 LLM 依赖即可运行。它通过正则表达式和启发式算法从文本中提取结构化信息。\n\n### 记忆类型\n\n启发式编译器生成以下类型的记忆：\n\n| 记忆类型 | 置信度 | 描述 | TTL 配置 |\n|----------|--------|------|----------|\n| `episode_summary` | 0.8 | 对话片段的概要摘要 | 基于 `episode_summary` TTL |\n| `profile_fact` | 0.6 | 从对话中提取的用户 profile 事实 | 基于 `profile_fact` TTL |\n\n资料来源：[server/services/compilers/heuristic.py:1-80]()\n\n### 时间锚点计算\n\n编译器使用以下优先级确定记忆的时间锚点（`valid_from`）：\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"返回派生记忆的最佳努力时间锚点\"\"\"\n    # 优先级 1: payload.event_time — 客户端显式设置\n    # 优先级 2: payload.messages[0].timestamp — 首条消息时间戳\n    # 优先级 3: ep.created_at — 系统记录时间\n```\n\n**时间锚点优先级：**\n\n| 优先级 | 来源字段 | 说明 |\n|--------|----------|------|\n| 1 | `payload.event_time` | 显式覆盖时间，适用于历史数据回放 |\n| 2 | `payload.messages[0].timestamp` | 聊天类载荷的首条消息时间戳 |\n| 3 | `ep.created_at` | 系统自动记录的时间 |\n\n资料来源：[server/services/compilers/heuristic.py:80-100]()\n\n### Profile Facts 提取\n\nProfile Facts 提取器从对话文本中识别用户相关的结构化信息，包括：\n\n- 用户姓名、职位、公司等基本信息\n- 用户偏好和习惯\n- 技术栈和技能水平\n- 过往交互历史摘要\n\n提取后的 facts 会被封装为独立的 MemoryRow，置信度为 0.6，source_episode_ids 指向原始 Episode。\n\n### TTL 计算\n\n每种记忆类型都有预设的存活时间（TTL），通过 `compute_valid_to()` 函数计算：\n\n```python\ndef compute_valid_to(kind: str, valid_from: datetime, ttl: dict) -> datetime | None:\n    \"\"\"根据记忆类型计算过期时间\"\"\"\n    # 返回 valid_from + 对应类型的 TTL\n```\n\n## LLM 编译器\n\n### 概述\n\nLLM 编译器使用大语言模型进行深度语义分析，能够：\n\n- 理解对话意图和情感\n- 提取隐含的关系和依赖\n- 生成更准确的摘要和总结\n- 识别实体和事件之间的关联\n\n### 配置要求\n\n```yaml\nllm:\n  apiKey: sk-...  # 必须配置\n  # 可选配置项\n  model: gpt-4    # 指定模型\n  temperature: 0.3\n```\n\n### 提示词策略\n\nLLM 编译器使用精心设计的提示词模板，引导模型生成符合 Statewave 数据模型的记忆结构。提示词设计考虑：\n\n- 记忆类型的严格分类\n- 置信度评分的指导\n- 时间范围的有效期设定\n- 避免幻觉和重复提取\n\n## 记忆数据结构\n\n### MemoryRow 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 记忆唯一标识符 |\n| `subject_id` | UUID | 所属主体 ID |\n| `kind` | string | 记忆类型（如 episode_summary、profile_fact） |\n| `content` | text | 记忆内容正文 |\n| `summary` | string | 内容摘要（前 200 字符） |\n| `confidence` | float | 置信度 0.0-1.0 |\n| `valid_from` | datetime | 记忆起始时间 |\n| `valid_to` | datetime | 记忆过期时间（None 表示永不过期） |\n| `source_episode_ids` | list[UUID] | 源 Episodes ID 列表 |\n| `metadata_` | dict | 扩展元数据 |\n| `status` | string | 状态（active、superseded 等） |\n| `embedding` | vector | 向量嵌入（用于语义搜索） |\n| `sensitivity_labels` | list[string] | 敏感标签 |\n| `created_at` | datetime | 创建时间 |\n| `updated_at` | datetime | 更新时间 |\n\n### 记忆状态流转\n\n```mermaid\nstateDiagram-v2\n    [*] --> active: 新建记忆\n    active --> superseded: 被新记忆替代\n    active --> redacted: 策略过滤\n    active --> inactive: 过期\n    superseded --> [*]\n    redacted --> [*]\n    inactive --> [*]\n```\n\n## 冲突检测与消解\n\n### 冲突类型\n\n| 冲突类型 | 描述 | 检测方式 |\n|----------|------|----------|\n| 内容重复 | 新记忆与现有记忆内容高度相似 | 文本相似度 > 0.7 |\n| 时间冲突 | 新旧记忆的时间范围重叠 | valid_from/valid_to 区间重叠 |\n| 事实矛盾 | 同一事实的描述相互矛盾 | 实体提取比对 |\n| 覆盖冲突 | 新记忆应替代而非追加 | 置信度对比 |\n\n### 消解策略\n\n| 策略 | 触发条件 | 处理方式 |\n|------|----------|----------|\n| 合并 | 内容高度相似 | 合并 source_episode_ids |\n| 替代 | 新记忆置信度更高 | 将旧记忆标记为 superseded |\n| 保留 | 两者互补 | 同时保留 |\n| 丢弃 | 新记忆信息量不足 | 忽略新记忆 |\n\n资料来源：[server/services/conflicts.py:1-50]()\n\n## 编译任务管理\n\n### 同步编译\n\n适用于小批量 Episodes 的实时编译：\n\n```python\nresult = await compile_job.execute(episode_ids)\n```\n\n### 持久化任务\n\n对于大批量编译需求，系统提供持久化任务支持：\n\n```python\njob = await compile_job_durable.create(\n    episode_ids=episode_ids,\n    mode=\"llm\",\n    priority=\"normal\"\n)\n```\n\n| 任务状态 | 说明 |\n|----------|------|\n| `pending` | 等待执行 |\n| `running` | 执行中 |\n| `completed` | 成功完成 |\n| `failed` | 执行失败 |\n| `cancelled` | 已取消 |\n\n### 重试机制\n\n编译任务失败后自动重试，默认策略：\n\n- 最大重试次数：3\n- 重试间隔：指数退避（1s, 4s, 16s）\n- 永久失败：记录错误日志，标记任务状态\n\n## 配置参考\n\n### 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `STATEWAVE_COMPILER_TYPE` | `llm` | 编译模式：llm 或 heuristic |\n| `STATEWAVE_COMPILER_LLM_MODEL` | - | LLM 模型名称 |\n| `STATEWAVE_COMPILER_MAX_RETRIES` | `3` | 最大重试次数 |\n\n### Helm Chart 配置\n\n```yaml\ncompiler:\n  type: llm  # 或 heuristic\n  timeout: 300  # 编译超时时间（秒）\n  batchSize: 50  # 每批处理 Episodes 数\n```\n\n## 最佳实践\n\n### 编译模式选择指南\n\n```mermaid\nflowchart TD\n    A[选择编译模式] --> B{有 LLM 需求?}\n    B -->|是| C[生产环境]\n    B -->|否| D{需要深度语义理解?}\n    D -->|是| C\n    D -->|否| E[开发/演示环境]\n    C --> F[LLM 编译器]\n    E --> G[Heuristic 编译器]\n```\n\n### 性能优化建议\n\n1. **批量摄入**：使用 `POST /v1/episodes/batch` 批量摄入，减少编译次数\n2. **合理选择模式**：非必要场景使用 Heuristic 模式降低延迟\n3. **配置 TTL**：根据业务需求调整各记忆类型的 TTL，减少存储压力\n4. **监控编译状态**：通过 API 监控编译任务的执行情况\n\n### 调试编译问题\n\n```bash\n# 检查编译状态\ncurl http://localhost:8100/v1/memories/search?subject_id=xxx\n\n# 查看编译任务详情\ncurl http://localhost:8100/admin/jobs?status=failed\n```\n\n## 相关文档\n\n- [架构概述](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/overview.md)\n- [编译器模式对比](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/compiler-modes.md)\n- [隐私与数据流](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/privacy-and-data-flow.md)\n- [API v1 契约](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n\n---\n\n<a id='p-context-retrieval'></a>\n\n## 上下文检索与排名\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [编译器系统](#p-compiler), [Episode 管理](#p-episodes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/health.py](https://github.com/smaramwbc/statewave/blob/main/server/services/health.py)\n- [server/services/sla.py](https://github.com/smaramwbc/statewave/blob/main/server/services/sla.py)\n- [server/services/embeddings/litellm.py](https://github.com/smaramwbc/statewave/blob/main/server/services/embeddings/litellm.py)\n- [server/services/embeddings/query_cache.py](https://github.com/smaramwbc/statewave/blob/main/server/services/embeddings/query_cache.py)\n</details>\n\n# 上下文检索与排名\n\n## 概述\n\n上下文检索与排名（Context Retrieval and Ranking）是 Statewave 的核心子系统，负责从海量的记忆（Memory）和事件（Episode）数据中筛选出最相关的内容，并将其组装成符合令牌预算限制的上下文包，供下游 AI 代理使用。\n\n该系统的设计目标包括：\n\n- **相关性优先**：基于语义相似度、类型匹配、时间衰减等多维度评分机制\n- **令牌约束**：自动裁剪结果以满足 `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` 配置的令牌预算\n- **幂等性**：同一查询在相同数据状态下产生一致的上下文输出\n- **多租户隔离**：通过 `X-Tenant-ID` header 确保跨租户数据的严格隔离\n\n资料来源：[server/services/context.py:1-50]()\n\n## 核心概念\n\n### 上下文项（Context Item）\n\n在 Statewave 中，所有可被纳入上下文的实体都被抽象为 **Context Item**。系统支持两类主要实体：\n\n| 实体类型 | 数据模型 | 说明 |\n|---------|---------|------|\n| Memory | `MemoryRow` | 编译后的记忆条目，包含摘要、置信度、时间范围等信息 |\n| Episode | `EpisodeRow` | 原始事件记录，包含完整载荷和来源元数据 |\n\n每项实体都关联一个 **评分（Score）**，用于排名决策。\n\n### 评分项（ScoredItem）\n\n`ScoredItem` 是上下文组装过程中的内部数据结构，用于封装已评分的条目：\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `score` | `float` | 计算得出的相关性分数 |\n| `kind` | `str` | 条目类型（memory 或 episode） |\n| `memory_row` | `Any` | 关联的 MemoryRow（若 kind 为 memory） |\n| `episode_row` | `Any` | 关联的 EpisodeRow（若 kind 为 episode） |\n| `text` | `str` | 用于语义检索的文本内容 |\n| `section` | `str` | 条目所属的语义分区 |\n\n资料来源：[server/services/context.py:50-68]()\n\n## 系统架构\n\n```mermaid\ngraph TD\n    subgraph \"上下文检索与排名系统\"\n        A[POST /v1/context] --> B[Query Parser]\n        B --> C[语义检索模块]\n        C --> D[混合评分引擎]\n        D --> E[Token Budget Controller]\n        E --> F[上下文组装器]\n        F --> G[返回 Context Bundle]\n    end\n\n    subgraph \"数据存储层\"\n        H[(Memory Table)]\n        I[(Episode Table)]\n        J[(Embedding Cache)]\n    end\n\n    C --> H\n    C --> I\n    C --> J\n```\n\n## 检索流程\n\n### 1. 查询解析与参数验证\n\n客户端通过 `POST /v1/context` 端点提交上下文请求，请求参数包括：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `subject_id` | `string` | 是 | - | 目标主题 ID |\n| `query` | `string` | 是 | - | 检索查询文本 |\n| `k` | `integer` | 否 | `10` | 返回的 top-k 结果数 |\n| `max_tokens` | `integer` | 否 | `4000` | 上下文令牌预算上限 |\n\n系统首先验证租户隔离（`STATEWAVE_TENANT_HEADER`），确保查询仅访问授权数据。\n\n### 2. 语义检索\n\n系统通过嵌入服务（Embedding Service）将查询文本转换为向量表示：\n\n```python\n# 嵌入服务配置\nembedding_provider = \"litellm\"  # 或 \"stub\" 用于演示模式\n```\n\n嵌入向量随后用于在向量数据库中执行相似度搜索。Statewave 支持两种嵌入模式：\n\n| 模式 | 配置值 | 说明 |\n|------|--------|------|\n| LiteLLM | `litellm` | 调用外部 LLM API 生成嵌入向量 |\n| Stub | `stub` | 返回占位符向量，用于无 API Key 的演示场景 |\n\n资料来源：[server/services/embeddings/litellm.py:1-30]()\n\n### 3. 查询缓存\n\n为降低嵌入 API 调用成本，系统实现了查询缓存机制：\n\n```python\n# 缓存键生成逻辑\ncache_key = hashlib.sha256(\n    f\"{query_text}:{k}:{include_episodes}\".encode()\n).hexdigest()\n```\n\n缓存有效期由 `STATEWAVE_EMBEDDING_CACHE_TTL` 配置控制。\n\n资料来源：[server/services/embeddings/query_cache.py:1-40]()\n\n## 评分与排名机制\n\n### 混合评分算法\n\n系统在多个维度上计算相关性分数：\n\n| 评分维度 | 权重 | 数据来源 |\n|---------|------|---------|\n| 语义相似度 | 0.4 | 嵌入向量余弦相似度 |\n| 类型匹配度 | 0.2 | 查询类型与条目类型的匹配程度 |\n| 时间衰减 | 0.2 | 基于 `valid_from` 的指数衰减 |\n| 置信度 | 0.2 | 条目自身的 `confidence` 字段 |\n\n最终分数计算公式：\n\n```\nfinal_score = 0.4 × semantic_score + 0.2 × type_match + 0.2 × time_decay + 0.2 × confidence\n```\n\n### 排名策略\n\n1. **Primary Sort**：按 `final_score` 降序排列\n2. **Secondary Sort**：相同分数时，按 `created_at` 降序排列（优先新条目）\n3. **Diversity Boost**：对类型多样的结果给予小幅加分，避免结果过度集中\n\n### Memory 类型权重\n\n不同类型的记忆在检索时享有不同的基础权重：\n\n| 记忆类型 | 基础权重 | 说明 |\n|---------|---------|------|\n| `episode_summary` | 0.9 | 事件摘要，高信息密度 |\n| `profile_fact` | 0.8 | 用户画像事实 |\n| `decision` | 0.85 | 决策记录 |\n| `default` | 0.7 | 默认类型 |\n\n资料来源：[server/services/context.py:70-120]()\n\n## Token 预算控制\n\n### 预算分配策略\n\n系统采用 **分层预算分配** 策略：\n\n```mermaid\ngraph LR\n    A[总预算<br/>max_tokens] --> B[Memory 层<br/>60%]\n    A --> C[Episode 层<br/>30%]\n    A --> D[元数据层<br/>10%]\n```\n\n### 裁剪算法\n\n当候选条目总 token 数超过预算时，系统按以下顺序裁剪：\n\n1. 移除分数最低的 Episode 条目\n2. 合并低置信度的 Memory 摘要\n3. 截断单个 Memory 的 content 字段至 `max_tokens_per_item` 限制\n4. 若仍超预算，返回部分结果并设置 `truncated: true` 标志\n\n### 配置参数\n\n| 环境变量 | 默认值 | 说明 |\n|---------|--------|------|\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认上下文令牌预算 |\n| `STATEWAVE_MAX_TOKENS_PER_ITEM` | `1000` | 单条目最大 token 数 |\n\n## API 端点\n\n### POST /v1/context\n\n**功能**：组装并返回上下文包\n\n**请求示例**：\n\n```bash\ncurl -X POST http://localhost:8100/v1/context \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-Tenant-ID: tenant-123\" \\\n  -d '{\n    \"subject_id\": \"user-001\",\n    \"query\": \"最近的产品需求讨论\",\n    \"k\": 10,\n    \"max_tokens\": 4000\n  }'\n```\n\n**响应结构**：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | `string` | 主题 ID |\n| `items` | `array` | 上下文字条目数组 |\n| `total_tokens` | `integer` | 实际使用的 token 数 |\n| `truncated` | `boolean` | 是否因预算限制被截断 |\n| `citations` | `array` | 引用的原始条目 ID |\n\n### GET /v1/timeline\n\n**功能**：获取主题的时间线视图\n\n**查询参数**：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | `string` | 主题 ID |\n| `since` | `datetime` | 起始时间（ISO 8601） |\n| `until` | `datetime` | 结束时间（ISO 8601） |\n\n资料来源：[server/api/context.py:1-80]()\n\n## 与 SLA/健康检查的集成\n\n### 健康评分上下文\n\n上下文检索系统与健康服务（Health Service）共享数据访问层：\n\n```python\n# 健康评分的上下文因子\nhealth_factors = {\n    \"recent_memories\": memory_count_last_7d,\n    \"resolution_rate\": resolutions.resolved / resolutions.total,\n    \"avg_response_time\": sla_metrics.avg_response_time,\n    \"sla_breaches\": sla_metrics.breach_count\n}\n```\n\n系统通过 `/v1/subjects/{id}/health` 端点暴露综合健康评分，该评分依赖上下文检索获取近期记忆和 SLA 指标。\n\n资料来源：[server/services/health.py:1-60]()\n\n### SLA 指标上下文\n\nSLA 服务在计算响应时间和解决时间时，会向上下文检索模块请求相关 Episode 数据：\n\n```python\n# SLA 计算的数据依赖链\ntimeline_episodes → context_retrieval → \nsla_metrics → health_score\n```\n\n| SLA 指标 | 计算方式 | 上下文依赖 |\n|---------|---------|-----------|\n| `first_response_time` | 首条回复距首条消息的时间差 | `/v1/timeline` 数据 |\n| `resolution_time` | 问题解决距首条消息的时间差 | Resolution Episode |\n| `breach_count` | SLA 违规次数 | 时间窗口内的所有 Episode |\n\n资料来源：[server/services/sla.py:1-80]()\n\n## 性能优化\n\n### 向量检索优化\n\n1. **批处理嵌入**：将多个短查询合并为单次 API 调用\n2. **HNSW 索引**：使用 pgvector 的 HNSW 索引加速近似最近邻搜索\n3. **结果缓存**：语义相似的结果在短时间窗口内被缓存\n\n### 缓存策略\n\n| 缓存类型 | TTL | 键生成策略 |\n|---------|-----|-----------|\n| 嵌入结果 | `STATEWAVE_EMBEDDING_CACHE_TTL` | SHA256(query + k) |\n| 上下文包 | 60 秒 | query hash + subject_id |\n| 排名结果 | 300 秒 | 相同 |\n\n## 错误处理\n\n| 错误码 | 场景 | 处理策略 |\n|-------|------|---------|\n| `400` | 无效查询参数 | 返回参数校验错误详情 |\n| `401` | 缺少/无效 API Key | 要求认证 |\n| `403` | 租户 ID 不匹配 | 拒绝访问 |\n| `404` | 主题不存在 | 返回空上下文包 |\n| `429` | 速率限制 | 按 `X-RateLimit-Reset` 重试 |\n| `500` | 嵌入服务不可用 | 降级至关键词检索 |\n\n## 配置参考\n\n完整的上下文检索相关配置项：\n\n```bash\n# 令牌预算\nSTATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS=4000\n\n# 嵌入服务\nSTATEWAVE_EMBEDDING_PROVIDER=litellm\nSTATEWAVE_EMBEDDING_MODEL=text-embedding-3-small\nSTATEWAVE_EMBEDDING_CACHE_TTL=3600\n\n# 多租户\nSTATEWAVE_TENANT_HEADER=X-Tenant-ID\nSTATEWAVE_REQUIRE_TENANT=false\n```\n\n## 扩展阅读\n\n- [API v1 契约规范](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n- [排名算法详解](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/ranking.md)\n- [隐私与数据流](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/privacy-and-data-flow.md)\n\n---\n\n<a id='p-api-routes'></a>\n\n## API 路由参考\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [服务层实现](#p-services)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py)\n- [server/api/memories.py](https://github.com/smaramwbc/statewave/blob/main/server/api/memories.py)\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/api/subjects.py](https://github.com/smaramwbc/statewave/blob/main/server/api/subjects.py)\n- [server/api/resolutions.py](https://github.com/smaramwbc/statewave/blob/main/server/api/resolutions.py)\n- [server/api/handoff.py](https://github.com/smaramwbc/statewave/blob/main/server/api/handoff.py)\n- [server/api/health.py](https://github.com/smaramwbc/statewave/blob/main/server/api/health.py)\n- [server/api/sla.py](https://github.com/smaramwbc/statewave/blob/main/server/api/sla.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n</details>\n\n# API 路由参考\n\n本文档提供 Statewave API v1 的完整路由参考，涵盖所有可用端点、请求/响应格式及使用场景。\n\n## 概览\n\nStatewave API 基于 FastAPI 构建，提供 RESTful 接口用于管理 **Subject（主体）**、**Episode（事件）**、**Memory（记忆）**、**Resolution（解决方案）** 等核心实体。API 支持多租户隔离、速率限制和可配置的上下文组装策略。\n\n### 基础信息\n\n| 项目 | 值 |\n|------|-----|\n| 基础 URL | `http://localhost:8100` |\n| API 版本 | v1 |\n| 认证方式 | `X-API-Key` 请求头 |\n| 租户隔离 | `X-Tenant-ID` 请求头 |\n| 数据格式 | JSON |\n\n### 可用文档界面\n\n| 界面 | URL |\n|------|-----|\n| Swagger UI | `http://localhost:8100/docs` |\n| ReDoc | `http://localhost:8100/redoc` |\n\n---\n\n## 健康检查路由\n\n### 存活性检查\n\n```\nGET /healthz\nGET /health\n```\n\n返回服务存活性状态。\n\n**响应示例：**\n\n```json\n{\n  \"status\": \"ok\"\n}\n```\n\n### 就绪检查\n\n```\nGET /readyz\nGET /ready\n```\n\n返回服务就绪状态（依赖项检查通过后返回）。\n\n---\n\n## Episode 路由\n\nEpisode 是 Statewave 中的原子事件单元，支持追加写入。\n\n### 摄入单个 Episode\n\n```\nPOST /v1/episodes\n```\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"session_id\": \"string (optional)\",\n  \"source\": \"string\",\n  \"type\": \"string\",\n  \"payload\": {\n    \"messages\": [\n      {\n        \"role\": \"user|assistant|system\",\n        \"content\": \"string\",\n        \"timestamp\": \"ISO8601 (optional)\"\n      }\n    ],\n    \"event_time\": \"ISO8601 (optional)\"\n  },\n  \"metadata\": {},\n  \"provenance\": {}\n}\n```\n\n### 批量摄入 Episodes\n\n```\nPOST /v1/episodes/batch\n```\n\n**请求体：**\n\n```json\n{\n  \"episodes\": [\n    {\n      \"subject_id\": \"string\",\n      \"session_id\": \"string\",\n      \"source\": \"string\",\n      \"type\": \"string\",\n      \"payload\": {},\n      \"metadata\": {},\n      \"provenance\": {}\n    }\n  ]\n}\n```\n\n**限制：** 单次请求最多 100 条 Episodes\n\n### 查询 Episodes\n\n```\nGET /v1/episodes\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `subject_id` | string | - | 按主体 ID 过滤 |\n| `session_id` | string | - | 按会话 ID 过滤 |\n| `source` | string | - | 按来源过滤 |\n| `limit` | int | 50 | 返回条数 (1-200) |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Episode 详情\n\n```\nGET /v1/episodes/{episode_id}\n```\n\n### 获取 Episode 引用关系\n\n```\nGET /v1/subjects/{subject_id}/episodes/{episode_id}/citing-memories\n```\n\n列出引用特定 Episode 的所有 Memory，支持反向溯源查询。\n\n**响应包含字段：**\n\n- `id` - Memory ID\n- `kind` - Memory 类型\n- `content` - Memory 内容\n- `relationship` - 关系类型 (`sibling`)\n\n---\n\n## Memory 路由\n\nMemory 是从 Episode 编译提取的结构化知识单元。\n\n### 编译 Memories\n\n```\nPOST /v1/memories/compile\n```\n\n触发 Memory 编译流程，将指定主体的 Episodes 转换为 Memories。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"mode\": \"heuristic|llm (optional)\",\n  \"force\": false\n}\n```\n\n### 搜索 Memories\n\n```\nGET /v1/memories/search\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `kind` | string | Memory 类型 |\n| `query` | string | 语义搜索文本 |\n| `limit` | int | 返回条数 |\n| `offset` | int | 偏移量 |\n\n### 列出 Memories\n\n```\nGET /v1/memories\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `subject_id` | string | - | 按主体 ID 过滤 |\n| `kind` | string | - | 按类型过滤 |\n| `status` | string | - | 按状态过滤 |\n| `limit` | int | 50 | 返回条数 |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Memory 详情\n\n```\nGET /v1/memories/{memory_id}\n```\n\n### 获取 Memory 演化链\n\n```\nGET /v1/memories/{memory_id}/evolution\n```\n\n返回 Memory 的版本演化信息，包括：\n\n- `superseding_memory` - 替代当前 Memory 的新版本\n- `superseded_memories` - 被当前 Memory 替代的旧版本\n- `sibling_memories` - 同源 Memory（源自同一 Episode）\n\n### 删除 Memory\n\n```\nDELETE /v1/memories/{memory_id}\n```\n\n---\n\n## Context 路由\n\n### 组装上下文包\n\n```\nPOST /v1/context\n```\n\n根据查询条件组装满足 Token 限制的上下文束。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"query\": \"string (optional)\",\n  \"k\": 10,\n  \"max_tokens\": 4000,\n  \"include_episodes\": false,\n  \"include_memories\": true,\n  \"memory_kinds\": [\"profile_fact\", \"episode_summary\"]\n}\n```\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"query\": \"string\",\n  \"episodes\": [],\n  \"memories\": [],\n  \"total_tokens\": 1234,\n  \"truncated\": false\n}\n```\n\n---\n\n## Subject 路由\n\nSubject 是 Statewave 中的顶级实体，代表一个需要记忆的\"主体\"（用户、实体或概念）。\n\n### 列出 Subjects\n\n```\nGET /v1/subjects\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `limit` | int | 50 | 返回条数 |\n| `offset` | int | 0 | 偏移量 |\n\n### 创建 Subject\n\n```\nPOST /v1/subjects\n```\n\n**请求体：**\n\n```json\n{\n  \"id\": \"string (optional)\",\n  \"name\": \"string (optional)\",\n  \"metadata\": {}\n}\n```\n\n### 获取 Subject 详情\n\n```\nGET /v1/subjects/{id}\n```\n\n### 删除 Subject\n\n```\nDELETE /v1/subjects/{id}\n```\n\n永久删除指定主体的所有数据（包含 Episodes、Memories、Resolutions）。\n\n### 导出 Subject\n\n```\nGET /v1/subjects/{id}/export\n```\n\n导出主体的完整数据为归档包。\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `include_snapshots` | bool | false | 包含快照数据 |\n| `preserve_ids` | bool | false | 保留原始 ID |\n\n### 导入 Subject\n\n```\nPOST /v1/subjects/import\n```\n\n**请求体：**\n\n```json\n{\n  \"archive\": {},\n  \"conflict_strategy\": \"create_copy|merge|cancel\"\n}\n```\n\n**冲突处理策略：**\n\n| 策略 | 说明 |\n|------|------|\n| `create_copy` | 创建新主体并分配新 ID |\n| `merge` | 合并到已存在主体 |\n| `cancel` | 目标主体已存在则报错 |\n\n---\n\n## Timeline 路由\n\n### 获取 Subject 时间线\n\n```\nGET /v1/timeline\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `since` | ISO8601 | 起始时间 |\n| `until` | ISO8601 | 结束时间 |\n| `limit` | int | 返回条数 |\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"episodes\": [],\n  \"memories\": []\n}\n```\n\n### 获取 Session 时间线\n\n```\nGET /v1/timeline/sessions/{session_id}\n```\n\n返回会话内的所有事件（Episodes 和 Resolutions）按时间顺序合并。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `session_id` | string | 会话 ID |\n| `status` | string | 会话状态 |\n| `first_message_at` | string | 首条消息时间 |\n| `first_response_at` | string | 首次响应时间 |\n| `resolved_at` | string | 解决时间 |\n| `first_response_seconds` | float | 首次响应耗时 |\n| `resolution_seconds` | float | 解决耗时 |\n| `first_response_breached` | bool | 是否超过首次响应 SLA |\n| `resolution_breached` | bool | 是否超过解决 SLA |\n| `events` | array | 时间线事件列表 |\n\n---\n\n## Resolution 路由\n\nResolution 用于跟踪问题解决状态。\n\n### 记录 Resolution\n\n```\nPOST /v1/resolutions\n```\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"session_id\": \"string\",\n  \"status\": \"pending|resolved|escalated\",\n  \"resolution_summary\": \"string\",\n  \"resolved_at\": \"ISO8601 (optional)\",\n  \"metadata\": {}\n}\n```\n\n### 列出 Resolutions\n\n```\nGET /v1/resolutions\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `session_id` | string | 会话 ID |\n| `status` | string | 按状态过滤 |\n\n---\n\n## Handoff 路由\n\n### 生成 Handoff 上下文包\n\n```\nPOST /v1/handoff\n```\n\n生成紧凑的交接上下文，用于在代理/会话之间传递状态。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"handoff_type\": \"agent_transfer|shift_change|escalation\",\n  \"max_tokens\": 2000,\n  \"include_recent_episodes\": true,\n  \"include_active_memories\": true\n}\n```\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"handoff_type\": \"string\",\n  \"context\": {\n    \"summary\": \"string\",\n    \"key_points\": [],\n    \"pending_items\": [],\n    \"recent_episodes\": [],\n    \"relevant_memories\": []\n  },\n  \"total_tokens\": 1234\n}\n```\n\n---\n\n## Health 路由\n\n### 获取 Customer Health Score\n\n```\nGET /v1/subjects/{id}/health\n```\n\n返回主体的健康评分及可解释因子。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `health_score` | float | 健康分 (0-100) |\n| `factors` | array | 影响因素 |\n| `breakdown` | object | 详细分解 |\n\n---\n\n## SLA 路由\n\n### 获取 SLA 指标\n\n```\nGET /v1/subjects/{id}/sla\n```\n\n返回 SLA 相关指标。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `response_time` | object | 响应时间统计 |\n| `resolution_time` | object | 解决时间统计 |\n| `breaches` | object | SLA 违约情况 |\n| `period` | string | 统计周期 |\n\n---\n\n## Admin 路由\n\nAdmin 路由提供系统管理功能。\n\n### 列出 Subject Episodes（分页）\n\n```\nGET /v1/admin/subjects/{subject_id}/episodes\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `limit` | int | 50 | 返回条数 (1-200) |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Snapshot 详情\n\n```\nGET /v1/admin/snapshots/{snapshot_id}\n```\n\n### 恢复 Snapshot\n\n```\nPOST /v1/admin/snapshots/{snapshot_id}/restore\n```\n\n**请求体：**\n\n```json\n{\n  \"target_subject_id\": \"string (optional)\",\n  \"time_shift\": \"duration string (optional)\",\n  \"preserve_metadata\": true\n}\n```\n\n### 导入 Memory Pack\n\n```\nPOST /v1/memory-packs/import\n```\n\n**请求体：**\n\n```json\n{\n  \"pack_url\": \"string\",\n  \"pack_data\": {},\n  \"conflict_strategy\": \"create_copy|merge|cancel\"\n}\n```\n\n---\n\n## 架构流程图\n\n### Episode → Memory 编译流程\n\n```mermaid\ngraph TD\n    A[Episode 摄入] --> B{编译模式}\n    B -->|Heuristic| C[启发式编译器]\n    B -->|LLM| D[LLM 编译器]\n    C --> E[提取 Profile Facts]\n    C --> F[生成 Episode Summary]\n    D --> G[结构化知识提取]\n    E --> H[MemoryRow 存储]\n    F --> H\n    G --> H\n    H --> I[Memory 索引完成]\n```\n\n### Context 组装流程\n\n```mermaid\ngraph TD\n    A[Context 请求] --> B[查询 Episodes]\n    A --> C[查询 Memories]\n    B --> D[相关性评分]\n    C --> D\n    D --> E[Token 预算检查]\n    E -->|超出限制| F[按分数排序裁剪]\n    E -->|未超出| G[返回完整结果]\n    F --> G\n```\n\n### 主体数据流\n\n```mermaid\ngraph LR\n    A[Subject 创建] --> B[Episodes 摄入]\n    B --> C[Memories 编译]\n    C --> D[Context 组装]\n    B --> E[Resolutions 记录]\n    D --> F[Timeline 查询]\n    E --> F\n```\n\n---\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | - | PostgreSQL 连接串 |\n| `STATEWAVE_API_KEY` | - | API 认证密钥 |\n| `STATEWAVE_LITELLM_API_KEY` | - | LLM API 密钥 |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离头 |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制租户头 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每 IP 请求限流 |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略 |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认 Token 预算 |\n\n---\n\n## 速率限制\n\nStatewave 支持两种速率限制策略：\n\n| 策略 | 说明 |\n|------|------|\n| `distributed` | 基于 PostgreSQL 的分布式限流 |\n| `memory` | 进程内内存限流 |\n\n**当前限制：** 限流按 IP 维度，未实现按租户或 API Key 的细粒度限流。\n\n---\n\n## 错误响应格式\n\n```json\n{\n  \"detail\": \"错误描述信息\"\n}\n```\n\n常见 HTTP 状态码：\n\n| 状态码 | 说明 |\n|--------|------|\n| `400` | 请求参数错误 |\n| `401` | 认证失败 |\n| `403` | 权限不足 |\n| `404` | 资源不存在 |\n| `413` | 请求体过大 |\n| `429` | 速率限制 |\n| `500` | 服务器内部错误 |\n\n---\n\n<a id='p-services'></a>\n\n## 服务层实现\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [API 路由参考](#p-api-routes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/services/backup.py](https://github.com/smaramwbc/statewave/blob/main/server/services/backup.py)\n- [server/services/handoff.py](https://github.com/smaramwbc/statewave/blob/main/server/services/handoff.py)\n- [server/services/memory_packs.py](https://github.com/smaramwbc/statewave/blob/main/server/services/memory_packs.py)\n- [server/services/receipts.py](https://github.com/smaramwbc/statewave/blob/main/server/services/receipts.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/webhooks.py](https://github.com/smaramwbc/statewave/blob/main/server/services/webhooks.py)\n- [server/services/ratelimit.py](https://github.com/smaramwbc/statewave/blob/main/server/services/ratelimit.py)\n</details>\n\n# 服务层实现\n\n## 概述\n\nStatewave 的服务层是业务逻辑的核心载体，负责处理记忆编译、上下文组装、快照管理、内存包操作、交接（handoff）处理、Webhook 通知、速率限制等关键功能。服务层位于 API 路由层与数据库持久层之间，封装了所有复杂的数据处理流程，确保 API 端点保持简洁。\n\n服务层采用异步架构设计，充分利用 Python 的 `asyncio` 特性处理 I/O 密集型操作。所有服务模块均支持多租户隔离，通过 `tenant_id` 参数实现数据层面的访问控制。\n\n---\n\n## 服务模块架构\n\n```mermaid\ngraph TD\n    subgraph \"服务层 (server/services)\"\n        A[context.py<br/>上下文组装服务]\n        B[snapshots.py<br/>快照管理服务]\n        C[memory_packs.py<br/>内存包服务]\n        D[handoff.py<br/>交接服务]\n        E[receipts.py<br/>回执服务]\n        F[webhooks.py<br/>Webhook服务]\n        G[ratelimit.py<br/>速率限制服务]\n        H[backup.py<br/>备份导出服务]\n    end\n    \n    subgraph \"API 层 (server/api)\"\n        I[episodes.py]\n        J[memories.py]\n        K[context.py]\n        L[handoff.py]\n        M[admin.py]\n    end\n    \n    subgraph \"数据层\"\n        N[(PostgreSQL)]\n    end\n    \n    I --> A\n    J --> A\n    K --> A\n    L --> D\n    M --> B\n    M --> C\n    A --> N\n    B --> N\n    C --> N\n    D --> E\n    D --> F\n    G --> N\n    H --> N\n```\n\n---\n\n## 上下文组装服务\n\n### 核心职责\n\n`context.py` 模块负责从主题的记忆库中检索相关记忆和事件，并组装成符合 token 预算限制的上下文束。该服务是 Statewave 记忆系统对外暴露的核心能力之一。\n\n### 内部类型设计\n\n**`_ScoredItem` 类** — 评分项封装\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `score` | `float` | 计算后的相关性评分 |\n| `kind` | `str` | 项目类型：`\"memory\"` 或 `\"episode\"` |\n| `memory_row` | `Any` | 关联的 MemoryRow 对象（可选） |\n| `episode_row` | `Any` | 关联的 EpisodeRow 对象（可选） |\n| `text` | `str` | 用于检索的文本内容 |\n| `section` | `str` | 内容所属的逻辑分区 |\n\n### 上下文组装流程\n\n```mermaid\ngraph LR\n    A[请求上下文] --> B[查询记忆库]\n    B --> C[相关性评分]\n    C --> D[Token 预算计算]\n    D --> E[内容裁剪]\n    E --> F[返回上下文束]\n```\n\n### 响应格式化\n\n服务提供 `_episode_response` 工厂函数，将数据库行转换为标准 API 响应格式：\n\n```python\ndef _episode_response(row: Any) -> EpisodeResponse:\n    return EpisodeResponse(\n        id=row.id,\n        subject_id=row.subject_id,\n        source=row.source,\n        type=row.type,\n        payload=row.payload,\n        metadata=row.metadata_,\n        provenance=row.provenance,\n        occurred_at=row.occurred_at,\n        created_at=row.created_at,\n        session_id=getattr(row, \"session_id\", None),\n    )\n```\n\n资料来源：[server/services/context.py:1-30]()\n\n---\n\n## 快照管理服务\n\n### 核心职责\n\n`snapshots.py` 模块提供主题快照的创建、恢复和管理功能。快照是主题在某一时点的完整状态镜像，包含事件、记忆和解决方案数据。\n\n### 快照创建流程\n\n```mermaid\ngraph TD\n    A[创建快照请求] --> B[验证源主题存在]\n    B --> C{快照主题冲突检测}\n    C -->|冲突| D[生成候选主题ID]\n    C -->|无冲突| E[读取源主题数据]\n    E --> F[遍历事件并创建快照副本]\n    F --> G[遍历记忆并创建快照副本]\n    G --> H[遍历解决方案并创建快照副本]\n    H --> I[创建 SubjectSnapshotRow 元数据]\n    I --> J[提交事务]\n    J --> K[返回快照信息]\n```\n\n### 时间戳偏移处理\n\n恢复快照时，服务支持时间戳偏移（`time_shift`），允许在不影响原始数据的情况下重建历史状态：\n\n```python\nmem_created = mem.created_at\nif mem_created.tzinfo is None:\n    mem_created = mem_created.replace(tzinfo=timezone.utc)\nmem_updated = mem.updated_at\nif mem_updated.tzinfo is None:\n    mem_updated = mem_updated.replace(tzinfo=timezone.utc)\n```\n\n| 参数 | 说明 |\n|------|------|\n| `time_shift` | 时间偏移量，用于调整恢复后数据的时间戳 |\n| `target_subject_id` | 恢复的目标主题 ID |\n| `snapshot_id` | 快照唯一标识符 |\n\n### 快照元数据结构\n\n创建快照时记录以下元数据：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | `UUID` | 快照唯一标识 |\n| `name` | `str` | 快照名称 |\n| `version` | `str` | 快照版本 |\n| `source_subject_id` | `UUID` | 源主题 ID |\n| `episode_count` | `int` | 包含的事件数量 |\n| `memory_count` | `int` | 包含的记忆数量 |\n| `metadata_` | `dict` | 自定义元数据 |\n\n资料来源：[server/services/snapshots.py:1-80]()\n\n---\n\n## 内存包服务\n\n### 核心职责\n\n`memory_packs.py` 提供了内存包的克隆、导入、导出等高级操作，支持在主题之间迁移数据或基于现有主题创建新的种子包。\n\n### 克隆作用域\n\n服务定义了四种克隆范围：\n\n| 作用域 | 说明 | 包含内容 |\n|--------|------|----------|\n| `episodes` | 仅事件 | 源主题的全部事件 |\n| `memories` | 仅记忆 | 源主题的全部记忆 |\n| `episodes_and_memories` | 事件+记忆 | 事件和记忆，不含来源引用 |\n| `episodes_memories_sources` | 完整克隆 | 事件、记忆及完整的来源引用链 |\n\n### 冲突解决策略\n\n| 策略 | 说明 | 行为 |\n|------|------|------|\n| `create_copy` | 创建副本（默认） | 为新导入的主题生成新 ID |\n| `merge` | 合并 | 复用原始主题 ID |\n| `cancel` | 取消 | 目标已存在时中止操作 |\n\n### 导入流程\n\n```mermaid\ngraph TD\n    A[导入内存包请求] --> B[验证主题数量限制]\n    B --> C[遍历源主题列表]\n    C --> D[解析原始主题ID]\n    D --> E{冲突策略检测}\n    E -->|create_copy| F[生成新主题ID]\n    E -->|merge| G[复用原始ID]\n    E -->|cancel| H[检查目标存在]\n    H -->|存在| I[抛出错误]\n    H -->|不存在| G\n    F --> J[按类型分组数据]\n    J --> K[创建新主题及数据]\n    K --> L[提交事务]\n```\n\n### 标识符映射机制\n\n导入过程中，服务维护 `id_map` 字典，将原始主题 ID 映射到最终目标主题 ID：\n\n```python\nid_map: dict[str, str] = {}\nfor s in subjects:\n    original = s.get(\"original_subject_id\")\n    _validate_subject_id(original, field=\"subjects[].original_subject_id\", allow_reserved=True)\n    final = await _resolve_target_subject(\n        explicit=original if conflict_strategy != \"create_copy\" else None,\n        suggested=original,\n        conflict_strategy=conflict_strategy,\n    )\n    id_map[original] = final\n```\n\n### 来源验证\n\n服务对来源标识符有严格的验证规则：\n\n- `create_copy` 模式下允许保留前缀的 ID（如 `demo_web_*`）\n- `merge` 和 `cancel` 模式不接受保留前缀的 ID\n- 导入后自动将目标 ID 重写为 `imported-*` 前缀\n\n资料来源：[server/services/memory_packs.py:1-100]()\n\n---\n\n## 交接服务\n\n### 核心职责\n\n`handoff.py` 模块负责生成紧凑的交接上下文包，用于在不同代理或会话之间传递上下文信息。交接包含请求者的身份信息、任务标识和会话状态。\n\n### 交接请求参数\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `subject_id` | `str` | 是 | 主题 ID |\n| `session_id` | `str` | 否 | 会话 ID |\n| `reason` | `str` | 否 | 交接原因 |\n| `max_tokens` | `int` | 否 | 最大 token 数 |\n| `emit_receipt` | `bool` | 否 | 是否生成回执 |\n| `query_id` | `str` | 否 | 查询 ID |\n| `task_id` | `str` | 否 | 任务 ID |\n| `parent_receipt_id` | `str` | 否 | 父回执 ID |\n| `caller_id` | `str` | 条件必填 | 调用者 ID（部分配置下必填） |\n| `caller_type` | `str` | 条件必填 | 调用者类型（部分配置下必填） |\n\n### 租户配置验证\n\n某些配置下，系统要求每个交接请求必须包含 `caller_id` 和 `caller_type`：\n\n```python\nif tenant_config_requires_caller and (not body.caller_id or not body.caller_type):\n    raise HTTPException(\n        status_code=401,\n        detail=(\n            \"tenant config requires caller_id and caller_type on every \"\n            \"handoff call\"\n        ),\n    )\n```\n\n资料来源：[server/services/handoff.py:1-50]()\n\n---\n\n## 回执服务\n\n### 核心职责\n\n`receipts.py` 模块负责生成和管理操作回执（Receipt）。回执是操作的不可变审计记录，包含操作的输入、输出和元数据。\n\n### 回执数据结构\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | `UUID` | 回执唯一标识 |\n| `tenant_id` | `str` | 租户 ID |\n| `operation_type` | `str` | 操作类型 |\n| `query_id` | `str` | 关联的查询 ID |\n| `task_id` | `str` | 关联的任务 ID |\n| `parent_receipt_id` | `str` | 父回执 ID（用于追溯） |\n| `input_data` | `dict` | 操作输入数据 |\n| `output_data` | `dict` | 操作输出数据 |\n| `metadata` | `dict` | 额外元数据 |\n| `created_at` | `datetime` | 创建时间 |\n\n### 层级关系\n\n回执支持父子层级结构，允许追踪复杂操作链：\n\n```mermaid\ngraph TD\n    A[根回执] --> B[子回执 1]\n    A --> C[子回执 2]\n    B --> D[孙回执 1.1]\n    C --> E[孙回执 2.1]\n```\n\n---\n\n## Webhook 服务\n\n### 核心职责\n\n`webhooks.py` 模块提供异步事件通知能力，允许外部系统在特定事件发生时接收通知。\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL（空则禁用） |\n| `STATEWAVE_WEBHOOK_TIMEOUT` | `5.0` | HTTP 请求超时时间（秒） |\n\n### 事件类型\n\n| 事件类型 | 触发时机 |\n|----------|----------|\n| `episode.created` | 新事件创建时 |\n| `memory.compiled` | 记忆编译完成时 |\n| `memory.evolved` | 记忆演进时 |\n| `snapshot.created` | 快照创建时 |\n| `snapshot.restored` | 快照恢复时 |\n| `handoff.issued` | 交接发起时 |\n\n### 重试机制\n\nWebhook 投递采用指数退避策略，配置最大重试次数确保最终一致性。\n\n---\n\n## 速率限制服务\n\n### 核心职责\n\n`ratelimit.py` 模块实现请求速率控制，保护系统免受滥用和过载。\n\n### 速率限制策略\n\n| 策略 | 说明 | 存储后端 |\n|------|------|----------|\n| `distributed` | 分布式模式 | PostgreSQL |\n| `memory` | 内存模式 | 进程内内存 |\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_RATE_LIMIT` | `0` | 每分钟请求/IP（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略选择 |\n\n### 限流维度\n\n当前版本按 IP 地址进行速率限制，尚未支持按租户或 API Key 的细粒度控制。\n\n资料来源：[README.md:1-50]()\n\n---\n\n## 备份导出服务\n\n### 核心职责\n\n`backup.py` 模块提供主题数据的导出功能，生成标准化的备份格式供导入或迁移使用。\n\n### 导出数据结构\n\n导出的 JSON 文档包含以下顶级字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subjects` | `list` | 主题列表 |\n| `episodes` | `list` | 事件列表 |\n| `memories` | `list` | 记忆列表 |\n| `resolutions` | `list` | 解决方案列表 |\n| `exported_at` | `datetime` | 导出时间戳 |\n| `version` | `str` | 导出格式版本 |\n\n### 与导入的互操作性\n\n导出格式与内存包导入端点完全兼容，确保数据可以在不同 Statewave 实例间自由迁移：\n\n```python\nfrom server.services.backup import export_subject\nsource_doc = await export_subject(source_subject_id, tenant_id=None)\n```\n\n资料来源：[server/services/memory_packs.py:50-60]()\n\n---\n\n## 服务层公共模式\n\n### 多租户隔离\n\n所有服务方法都接受可选的 `tenant_id` 参数，用于数据层面的租户隔离：\n\n```python\nasync def some_service_method(..., tenant_id: str | None = None):\n    \"\"\"Service method with multi-tenant support.\"\"\"\n    pass\n```\n\n### 事务管理\n\n服务层通过 SQLAlchemy 的异步会话管理事务：\n\n```python\nasync with engine_module.get_session_factory()() as session:\n    # 业务逻辑\n    await session.commit()\n```\n\n### 日志记录\n\n服务层采用结构化日志记录关键操作：\n\n```python\nlogger.info(\n    \"snapshot_created\", name=name, version=version, \n    episodes=len(eps), memories=len(mems)\n)\n```\n\n---\n\n## 服务间依赖关系\n\n```mermaid\ngraph LR\n    A[API 层] --> B[Context 服务]\n    A --> C[Snapshot 服务]\n    A --> D[Memory Pack 服务]\n    A --> E[Handoff 服务]\n    \n    B --> F[Receipt 服务]\n    B --> G[Webhook 服务]\n    \n    E --> F\n    E --> G\n    \n    D --> H[Backup 服务]\n    \n    I[RateLimit 服务] --> A\n```\n\n---\n\n## 总结\n\nStatewave 的服务层通过模块化设计实现了业务逻辑的清晰分离。各服务专注于单一职责，同时通过标准化的接口相互协作。异步架构确保了高并发场景下的性能表现，而多租户支持则满足了企业级部署的需求。\n\n---\n\n<a id='p-database'></a>\n\n## 数据库架构\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/db/tables.py](https://github.com/smaramwbc/statewave/blob/main/server/db/tables.py)\n- [server/db/repositories.py](https://github.com/smaramwbc/statewave/blob/main/server/db/repositories.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n</details>\n\n# 数据库架构\n\n## 概述\n\nStatewave 采用 **PostgreSQL** 作为主数据库，通过 `asyncpg` 异步驱动实现高性能数据访问。数据库架构围绕三个核心实体构建：**Episode（事件）**、**Memory（记忆）** 和 **Subject（主体）**，支持多租户隔离、快照恢复和时间线查询等高级功能。\n\n资料来源：[DOCKER.md:8]()\n\n## 核心数据模型\n\n### Entity-Relationship 概览\n\n```mermaid\nerDiagram\n    Subject ||--o{ Episode : contains\n    Subject ||--o{ Memory : contains\n    Episode ||--o{ Memory : generates\n    Subject ||--o{ Resolution : tracks\n    Subject ||--o{ SubjectSnapshot : snapshots\n    Memory }o--o{ Memory : supersedes\n```\n\n### 主要数据表\n\n| 表名 | 用途 | 核心字段 |\n|------|------|----------|\n| `episodes` | 不可变事件记录 | id, subject_id, session_id, source, type, payload, occurred_at |\n| `memories` | 从事件编译的记忆 | id, subject_id, kind, content, summary, source_episode_ids |\n| `resolutions` | 问题解决状态跟踪 | id, subject_id, session_id, status, resolved_at |\n| `subject_snapshots` | 主题时间点快照 | id, source_subject_id, episode_count, memory_count |\n\n资料来源：[server/services/snapshots.py:1-100]()\n\n## 表结构详解\n\n### EpisodeRow（事件表）\n\n事件是 Statewave 的基础数据单元，代表主体（Subject）的任意活动记录。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 事件唯一标识符 |\n| `subject_id` | String | 关联的主体 ID |\n| `session_id` | String | 所属会话标识 |\n| `tenant_id` | String | 多租户隔离标识 |\n| `source` | String | 事件来源（api, github, slack 等） |\n| `type` | String | 事件类型（message, issue, pr 等） |\n| `payload` | JSONB | 事件完整负载 |\n| `metadata_` | JSONB | 附加元数据 |\n| `provenance` | JSONB | 数据溯源信息 |\n| `occurred_at` | DateTime | 事件实际发生时间 |\n| `created_at` | DateTime | 记录创建时间 |\n\n```python\n# 事件创建示例（server/services/snapshots.py:51-65）\nEpisodeRow(\n    id=uuid.uuid4(),\n    subject_id=snapshot_subject,\n    session_id=ep.session_id,\n    tenant_id=ep.tenant_id,\n    source=ep.source,\n    type=ep.type,\n    payload=ep.payload,\n    metadata_=ep.metadata_,\n    provenance=ep.provenance,\n    occurred_at=ep.occurred_at,\n    created_at=ep.created_at,\n)\n```\n\n资料来源：[server/services/snapshots.py:51-65]()\n\n### MemoryRow（记忆表）\n\n记忆是从事件编译的提炼数据，支持多种类型和有效期管理。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 记忆唯一标识符 |\n| `subject_id` | String | 关联的主体 ID |\n| `kind` | String | 记忆类型（episode_summary, profile_fact 等） |\n| `content` | Text | 完整记忆内容 |\n| `summary` | String | 摘要（200字符） |\n| `confidence` | Float | 置信度（0-1） |\n| `valid_from` | DateTime | 有效期起始 |\n| `valid_to` | DateTime | 有效期结束（可选） |\n| `source_episode_ids` | Array[UUID] | 源事件 ID 列表 |\n| `status` | String | 状态（active, superseded 等） |\n| `sensitivity_labels` | Array[String] | 敏感度标签 |\n\n```python\n# 记忆创建示例（server/services/compilers/heuristic.py:1-50）\nMemoryRow(\n    id=uuid.uuid4(),\n    subject_id=ep.subject_id,\n    kind=\"episode_summary\",\n    content=text[:500],\n    summary=text[:200],\n    confidence=0.8,\n    valid_from=ep_valid_from,\n    valid_to=compute_valid_to(\"episode_summary\", ep_valid_from, ttl),\n    source_episode_ids=[ep.id],\n    metadata_={},\n    status=\"active\",\n)\n```\n\n资料来源：[server/services/compilers/heuristic.py:1-50]()\n\n### SubjectSnapshotRow（快照表）\n\n快照用于备份和恢复主体在特定时间点的完整状态。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 快照唯一标识符 |\n| `name` | String | 快照名称 |\n| `version` | String | 版本标识 |\n| `source_subject_id` | UUID | 源主体 ID |\n| `episode_count` | Integer | 事件数量 |\n| `memory_count` | Integer | 记忆数量 |\n| `metadata_` | JSONB | 快照元数据 |\n\n```python\n# 快照创建示例（server/services/snapshots.py:85-95）\nSubjectSnapshotRow(\n    name=name,\n    version=version,\n    source_subject_id=snapshot_subject,\n    episode_count=len(eps),\n    memory_count=len(mems),\n    metadata_=metadata or {},\n)\n```\n\n资料来源：[server/services/snapshots.py:85-95]()\n\n## 异步数据库访问模式\n\n### 引擎与会话管理\n\nStatewave 使用 SQLAlchemy 2.0 异步引擎，结合 `asyncpg` 驱动实现非阻塞 IO。\n\n```python\n# 异步会话获取模式（server/api/timeline.py:100-120）\nfrom server.db import engine as engine_module\n\nasync with engine_module.get_session_factory()() as session:\n    base = select(MemoryRow)\n    # ... 查询操作\n```\n\n### 查询构建示例\n\n```python\n# 复杂查询：查找引用特定事件的记忆（server/api/timeline.py:130-150）\nbase = select(MemoryRow).where(\n    MemoryRow.tenant_id == tenant_id,\n    MemoryRow.subject_id == subject_id,\n    func.any_(MemoryRow.source_episode_ids) == episode_uuid\n)\n```\n\n资料来源：[server/api/timeline.py:100-150]()\n\n## 仓储层设计\n\n### Repository 模式\n\n数据访问通过 Repository 模式封装，提供统一的 CRUD 操作接口。\n\n```mermaid\ngraph TD\n    A[API Layer] --> B[Service Layer]\n    B --> C[Repository Layer]\n    C --> D[(PostgreSQL)]\n    \n    E[Memory Repository] --> C\n    F[Episode Repository] --> C\n    G[Resolution Repository] --> C\n```\n\n### 核心仓储操作\n\n| 操作类型 | 方法 | 说明 |\n|----------|------|------|\n| 创建 | `write_receipt()` | 写入收据记录 |\n| 读取 | `get_session_factory()` | 获取异步会话 |\n| 更新 | `compile_memories()` | 编译新记忆 |\n| 删除 | 批量删除 | 按主体 ID 删除 |\n\n资料来源：[server/db/repositories.py](https://github.com/smaramwbc/statewave/blob/main/server/db/repositories.py)\n\n## 多租户数据隔离\n\n### 隔离策略\n\nStatewave 采用应用层多租户隔离，通过 `tenant_id` 字段实现数据分区。\n\n```mermaid\ngraph LR\n    A[Request] --> B{X-Tenant-ID Header}\n    B -->|有租户ID| C[按 tenant_id 过滤]\n    B -->|无租户ID| D[拒绝请求]\n    \n    C --> E[WHERE tenant_id = ?]\n```\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 租户标识头 |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户头 |\n\n```python\n# 租户过滤查询示例\nbase = select(MemoryRow).where(\n    MemoryRow.tenant_id == tenant_id,\n    MemoryRow.subject_id == subject_id\n)\n```\n\n资料来源：[README.md:1-50]()\n\n## 时间线与快照管理\n\n### 时间线查询\n\n支持按时间顺序检索主体的事件和记忆，支持事件合并展示。\n\n```python\n# 时间线响应模型（server/api/admin.py:50-80）\nclass SessionTimelineResponse(BaseModel):\n    session_id: str\n    status: str\n    first_message_at: str | None\n    resolved_at: str | None\n    episode_count: int\n    events: list[TimelineEvent]\n```\n\n### 快照恢复\n\n快照恢复支持时间偏移（Time Shift），确保恢复后时间戳的连续性。\n\n```python\n# 时间偏移处理（server/services/snapshots.py:130-160）\ntime_shift = target_created_at - snapshot_created_at\n\n# 记忆时间戳偏移\ncreated_at=mem_created + time_shift,\nupdated_at=mem_updated + time_shift,\nvalid_from=mem_valid_from + time_shift if mem_valid_from else None,\n```\n\n资料来源：[server/services/snapshots.py:130-160]()\n\n## 索引与性能优化\n\n### 推荐索引策略\n\n| 表名 | 推荐索引 | 用途 |\n|------|----------|------|\n| `memories` | `(subject_id, kind)` | 记忆类型查询 |\n| `memories` | `(source_episode_ids)` | 事件溯源查询 |\n| `episodes` | `(subject_id, occurred_at)` | 时间线查询 |\n| `episodes` | `(session_id)` | 会话聚合 |\n\n### JSONB 字段优化\n\n```python\n# JSONB 查询示例\nquery = select(MemoryRow).where(\n    MemoryRow.payload['event_type'].astext == 'message'\n)\n```\n\n## 迁移与版本管理\n\n### Alembic 集成\n\nStatewave 使用 Alembic 进行数据库迁移管理。\n\n```bash\n# Helm 安装时的预安装 Job\nalembic upgrade head\n```\n\n### 迁移执行时机\n\n| 操作 | 迁移时机 |\n|------|----------|\n| 首次安装 | Pre-install Job |\n| 版本升级 | Pre-upgrade Job |\n\n资料来源：[helm/statewave/README.md:1-30]()\n\n## 配置参考\n\n### 数据库连接配置\n\n```yaml\n# Docker Compose 配置示例\nenvironment:\n  STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n```\n\n### 测试环境配置\n\n```bash\n# 创建测试数据库\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\n```\n\n```python\n# 集成测试执行\npytest tests/integration/ -v\n```\n\n资料来源：[README.md:100-120]()\n\n## 最佳实践\n\n### 数据建模建议\n\n1. **事件不可变性**：事件一旦写入不应修改，通过新事件表达状态变更\n2. **记忆有效期**：使用 `valid_from`/`valid_to` 管理记忆时效\n3. **源事件追踪**：始终维护 `source_episode_ids` 引用链\n4. **租户隔离**：所有查询必须包含 `tenant_id` 过滤条件\n\n### 性能注意事项\n\n1. 避免全表扫描，使用索引覆盖查询\n2. 批量操作使用 `BATCH_SIZE = 50` 分批处理\n3. 大型导入使用快照机制而非实时编译\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：smaramwbc/statewave\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1219923941 | https://github.com/smaramwbc/statewave | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | release_recency=unknown\n\n<!-- canonical_name: smaramwbc/statewave; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "statewave",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "github_repo:1219923941",
          "kind": "repo",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/smaramwbc/statewave"
        },
        {
          "evidence_id": "art_4784ca0874154258a85b1099b900cdf5",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/smaramwbc/statewave#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "statewave 说明书",
      "toc": [
        "https://github.com/smaramwbc/statewave 项目说明书",
        "目录",
        "Statewave 简介",
        "核心概念",
        "系统架构",
        "API 参考",
        "编译模式",
        "连接器生态",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "b2bd8ef853bfa4894f9575890cf0957882f4526b",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "pyproject.toml",
      "Dockerfile",
      "README.md",
      "docker-compose.yml",
      "docs/state-assembly-receipts.md",
      "docs/memory-portability.md",
      "docs/licensing.md"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# statewave - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 statewave 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `pip install -e \".[dev,llm]\"` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `npm install @statewavedev/connectors-github` 证据：`README.md` Claim：`clm_0004` supported 0.86\n- `npm install @statewavedev/connectors-markdown` 证据：`README.md` Claim：`clm_0005` supported 0.86\n- `npm install @statewavedev/connectors-slack` 证据：`README.md` Claim：`clm_0006` supported 0.86\n- `npm install @statewavedev/connectors-n8n` 证据：`README.md` Claim：`clm_0007` supported 0.86\n- `npm install @statewavedev/connectors-zapier` 证据：`README.md` Claim：`clm_0008` supported 0.86\n- `npm install @statewavedev/mcp-server` 证据：`README.md` Claim：`clm_0009` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：需要管理员/安全审批\n- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。\n\n### 30 秒判断\n\n- **现在怎么做**：需要管理员/安全审批\n- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装\n- **先别相信**：工具权限边界不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key\n\n### 现在可以相信\n\n- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`DOCKER.md`, `README.md`, `helm/statewave/README.md`, `infra/postgres-pgvector/README.md` 等\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0010` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0011` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：230\n- 重要文件覆盖：40/230\n- 证据索引条目：50\n- 角色 / Skill 条目：17\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 statewave 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 statewave 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 statewave 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 17 个角色 / Skill / 项目文档条目。\n\n- **Statewave**（project_doc）：! CI https://github.com/smaramwbc/statewave/workflows/CI/badge.svg https://github.com/smaramwbc/statewave/actions/workflows/ci.yml ! License: AGPL-3.0 + Commercial https://img.shields.io/badge/license-AGPL--3.0%20%2B%20Commercial-blue.svg LICENSING.md ! Python 3.11+ https://img.shields.io/badge/python-3.11%2B-blue.svg https://www.python.org/ 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **Statewave Helm chart**（project_doc）：Deploys the Statewave API on Kubernetes. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`helm/statewave/README.md`\n- **Fly Postgres + pgvector — deployment runbook**（project_doc）：Fly Postgres + pgvector — deployment runbook 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`infra/postgres-pgvector/README.md`\n- **Server-side evals**（project_doc）：Internal regression tools for measuring server behaviour. These hit a live Statewave deployment admin endpoints included and are intended for the maintainers of this repo, not for external developers — see statewave-examples https://github.com/smaramwbc/statewave-examples for developer-facing demos. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`scripts/eval/README.md`\n- **Contributing to Statewave**（project_doc）：Thanks for your interest in contributing — Statewave is built in the open and external contributions are very welcome. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CONTRIBUTING.md`\n- **Statewave Commercial Licensing — Tiers**（project_doc）：Statewave Commercial Licensing — Tiers 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/licensing.md`\n- **Memory portability — admin API reference**（project_doc）：Memory portability — admin API reference 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/memory-portability.md`\n- **State-assembly receipts — design & reference**（project_doc）：State-assembly receipts — design & reference 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/state-assembly-receipts.md`\n- **Description**（project_doc）：- 🐛 Bug fix non-breaking change that fixes an issue - ✨ New feature non-breaking change that adds functionality - 💥 Breaking change fix or feature that would cause existing functionality to change - 📚 Documentation update - 🔧 Maintenance refactoring, dependencies, CI, etc. - 🧪 Test improvement 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.github/PULL_REQUEST_TEMPLATE.md`\n- **Code of Conduct**（project_doc）：Statewave adopts the Contributor Covenant, version 2.1 as its Code of Conduct. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CODE_OF_CONDUCT.md`\n- **Statewave Commercial License**（project_doc）：Statewave is dual-licensed. You may use it under the terms of the GNU Affero General Public License v3.0 LICENSE , or under a separate commercial license agreement with Statewave. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`COMMERCIAL-LICENSE.md`\n- **Statewave server**（project_doc）：Open-source memory runtime for AI agents — episodes in, distilled memories out. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`DOCKER.md`\n- **Licensing**（project_doc）：1. Open source — GNU Affero General Public License v3.0 LICENSE AGPLv3 2. Commercial — a separate Statewave Commercial License COMMERCIAL-LICENSE.md for proprietary, SaaS, embedded, hosted, or enterprise use. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`LICENSING.md`\n- **NOTICE**（project_doc）：Statewave Copyright c Statewave contributors. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`NOTICE.md`\n- **Security Policy**（project_doc）：Version Supported ------- ------------------ latest ✅ < latest ❌ upgrade recommended 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`SECURITY.md`\n- **Support**（project_doc）：Welcome to Statewave! Here's how to get help. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`SUPPORT.md`\n- **Statewave Trademark Policy**（project_doc）：The name \"Statewave\" , the Statewave logo, and related branding the \"Statewave Marks\" are project and company marks. The open-source license that covers the source code of Statewave AGPLv3 does not grant any rights to use the Statewave Marks. This policy describes the limited use we permit without a separate written agreement. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`TRADEMARKS.md`\n\n## 证据索引\n\n- 共索引 50 条证据。\n\n- **Statewave**（documentation）：! CI https://github.com/smaramwbc/statewave/workflows/CI/badge.svg https://github.com/smaramwbc/statewave/actions/workflows/ci.yml ! License: AGPL-3.0 + Commercial https://img.shields.io/badge/license-AGPL--3.0%20%2B%20Commercial-blue.svg LICENSING.md ! Python 3.11+ https://img.shields.io/badge/python-3.11%2B-blue.svg https://www.python.org/ 证据：`README.md`\n- **Statewave Helm chart**（documentation）：Deploys the Statewave API on Kubernetes. 证据：`helm/statewave/README.md`\n- **Fly Postgres + pgvector — deployment runbook**（documentation）：Fly Postgres + pgvector — deployment runbook 证据：`infra/postgres-pgvector/README.md`\n- **Server-side evals**（documentation）：Internal regression tools for measuring server behaviour. These hit a live Statewave deployment admin endpoints included and are intended for the maintainers of this repo, not for external developers — see statewave-examples https://github.com/smaramwbc/statewave-examples for developer-facing demos. 证据：`scripts/eval/README.md`\n- **Contributing to Statewave**（documentation）：Thanks for your interest in contributing — Statewave is built in the open and external contributions are very welcome. 证据：`CONTRIBUTING.md`\n- **License**（source_file）：GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 证据：`LICENSE`\n- **Statewave Commercial Licensing — Tiers**（documentation）：Statewave Commercial Licensing — Tiers 证据：`docs/licensing.md`\n- **Memory portability — admin API reference**（documentation）：Memory portability — admin API reference 证据：`docs/memory-portability.md`\n- **State-assembly receipts — design & reference**（documentation）：State-assembly receipts — design & reference 证据：`docs/state-assembly-receipts.md`\n- **Description**（documentation）：- 🐛 Bug fix non-breaking change that fixes an issue - ✨ New feature non-breaking change that adds functionality - 💥 Breaking change fix or feature that would cause existing functionality to change - 📚 Documentation update - 🔧 Maintenance refactoring, dependencies, CI, etc. - 🧪 Test improvement 证据：`.github/PULL_REQUEST_TEMPLATE.md`\n- **Code of Conduct**（documentation）：Statewave adopts the Contributor Covenant, version 2.1 as its Code of Conduct. 证据：`CODE_OF_CONDUCT.md`\n- **Statewave Commercial License**（documentation）：Statewave is dual-licensed. You may use it under the terms of the GNU Affero General Public License v3.0 LICENSE , or under a separate commercial license agreement with Statewave. 证据：`COMMERCIAL-LICENSE.md`\n- **Statewave server**（documentation）：Open-source memory runtime for AI agents — episodes in, distilled memories out. 证据：`DOCKER.md`\n- **Licensing**（documentation）：1. Open source — GNU Affero General Public License v3.0 LICENSE AGPLv3 2. Commercial — a separate Statewave Commercial License COMMERCIAL-LICENSE.md for proprietary, SaaS, embedded, hosted, or enterprise use. 证据：`LICENSING.md`\n- **NOTICE**（documentation）：Statewave Copyright c Statewave contributors. 证据：`NOTICE.md`\n- **Security Policy**（documentation）：Version Supported ------- ------------------ latest ✅ < latest ❌ upgrade recommended 证据：`SECURITY.md`\n- **Support**（documentation）：Welcome to Statewave! Here's how to get help. 证据：`SUPPORT.md`\n- **Statewave Trademark Policy**（documentation）：The name \"Statewave\" , the Statewave logo, and related branding the \"Statewave Marks\" are project and company marks. The open-source license that covers the source code of Statewave AGPLv3 does not grant any rights to use the Statewave Marks. This policy describes the limited use we permit without a separate written agreement. 证据：`TRADEMARKS.md`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"demo-coding-assistant\", \"display name\": \"Coding Assistant\", \"description\": \"Coding-assistant showcase pack: a developer Priya working on the Stratus codebase across roughly two months. Captures stack choices TS strict + Tailwind frontend, FastAPI + SQLModel + Pydantic v2 backend , style preferences composition over inheritance, top-level async, conventional-commits , an architecture decision log, an in-flight auth-middleware refactor with a documented blocker, a session-pool race fix that becomes a reusable diagnostic, and a no-mocks test policy traced to a real incident. Demonstrates preference layering, decision proven… 证据：`server/starter_packs/demo-coding-assistant/manifest.json`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"demo-devops-agent\", \"display name\": \"DevOps Agent\", \"description\": \"DevOps showcase pack: an SRE running the nimbus-api service across three months \\u2014 March pool-exhaustion outage with PgBouncer mitigation, secrets/backup/DB-failover runbooks, observability stack decision Datadog over Grafana Cloud , a noisy-alerts post-mortem that rewrote alert thresholds, a TLS rotation incident that split staging/prod issuers, deploy-window and phased-migration policies, and a canary deploy framework that cut rollback time from 6m to 30s. Demonstrates runbook recall, decision provenance, recurring-incident detection, and operation… 证据：`server/starter_packs/demo-devops-agent/manifest.json`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"demo-research-assistant\", \"display name\": \"Research Assistant\", \"description\": \"Research-assistant showcase pack: a researcher Arushi writing a NeurIPS 2026 submission on agent memory across four months \\u2014 citation conventions, an active draft with section-level progress and a settled architectural decision hard temporal-validity cutoffs over sigmoid decay , a co-author dynamic with Dr. Mei Wu at Berkeley, two empirical experiments compiler-density and multi-session-recall that supply paper results, an ICLR 2026 poster acceptance, a tooling stack with explicit anti-preferences, and personal work habits. Demonstrates… 证据：`server/starter_packs/demo-research-assistant/manifest.json`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"demo-sales-copilot\", \"display name\": \"Sales Copilot\", \"description\": \"Sales-copilot showcase pack: a rep Tom running a four-account pipeline across three months \\u2014 Acme Corp closed expansion + Q3 renewal vector , BetaTech SOC 2 cleared, in pricing negotiation , Cirrus Robotics churned then re-engaged with a new VP , and Delta Health HIPAA / BAA prospect . Captures decision-makers, contact preferences, AE routing, competitive positioning vs Mem0, HIPAA procurement order, and a closing-quarter pipeline summary. Demonstrates multi-subject identity, cross-account procedures, deal-stage history, win-back signals, and comp… 证据：`server/starter_packs/demo-sales-copilot/manifest.json`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"demo-support-agent\", \"display name\": \"Default Support Agent\", \"description\": \"Customer-support showcase pack: a multi-session story arc for one representative customer Northwind Logistics, Team plan, EU region covering onboarding, integration preferences, an SSO incident, repeat-issue detection, billing, an SLA-breached ticket with service credit, and a renewal signal. Demonstrates identity persistence, preference layering, procedure recall, prior-issue surfacing, and SLA awareness.\", \"version\": \"2.2026.05.06-focused\", \"created at\": \"2026-05-06T15:25:56.070391+00:00\", \"subject id suggestion\": \"demo-support-agent\", \"episo… 证据：`server/starter_packs/demo-support-agent/manifest.json`\n- **Index**（structured_config）：{ \"format\": \"statewave-starter-pack-index\", \"format version\": 1, \"packs\": { \"pack id\": \"statewave-support-agent\", \"kind\": \"support docs\", \"directory\": \"statewave-support-agent\" }, { \"pack id\": \"demo-support-agent\", \"kind\": \"demo agent\", \"directory\": \"demo-support-agent\" }, { \"pack id\": \"demo-coding-assistant\", \"kind\": \"demo agent\", \"directory\": \"demo-coding-assistant\" }, { \"pack id\": \"demo-sales-copilot\", \"kind\": \"demo agent\", \"directory\": \"demo-sales-copilot\" }, { \"pack id\": \"demo-devops-agent\", \"kind\": \"demo agent\", \"directory\": \"demo-devops-agent\" }, { \"pack id\": \"demo-research-assistant\", \"kind\": \"demo agent\", \"directory\": \"demo-research-assistant\" } } 证据：`server/starter_packs/index.json`\n- **Manifest**（structured_config）：{ \"format\": \"statewave-starter-pack\", \"format version\": 1, \"pack id\": \"statewave-support-agent\", \"display name\": \"Statewave Support\", \"description\": \"Full Statewave Support docs pack \\u2014 every curated section in statewave-docs chunked at heading boundaries, ingested as episodes, and compiled to memories. Importing this pack into the statewave-support-docs subject powers the docs-grounded support agent on day one with no extra bootstrap step.\", \"version\": \"1.2026.05.08\", \"created at\": \"2026-05-08T13:35:42.704407+00:00\", \"subject id suggestion\": \"statewave-support-docs\", \"episode count\": 276, \"memory count\": 364, \"source count\": 0, \"tags\": \"starter-pack\", \"platform-bundled\", \"docs-grounded… 证据：`server/starter_packs/statewave-support-agent/manifest.json`\n- **Build context exclusions for docker build / docker compose build .**（source_file）：Build context exclusions for docker build / docker compose build . Keeps developer-local config and dev artifacts OUT of the image, so the environment: block in docker-compose.yml is the single source of truth for runtime config — no surprise overrides from a baked-in .env . 证据：`.dockerignore`\n- **──────────────────────────────────────────────────**（source_file）：────────────────────────────────────────────────── Statewave — Environment Configuration Quickstart: 1. cp .env.example .env 2. Set STATEWAVE LITELLM API KEY below recommended . 3. docker compose up -d All variables are prefixed STATEWAVE . Values left commented use the defaults baked into server/core/config.py. ────────────────────────────────────────────────── 证据：`.env.example`\n- **Funding**（source_file）：github: smaramwbc 证据：`.github/FUNDING.yml`\n- **Dependabot**（source_file）：version: 2 updates: - package-ecosystem: \"pip\" directory: \"/\" schedule: interval: \"weekly\" open-pull-requests-limit: 10 labels: - \"dependencies\" commit-message: prefix: \"chore deps :\" 证据：`.github/dependabot.yml`\n- **.gitignore**（source_file）：pycache / .pyc .env .egg-info/ dist/ .venv/ .pytest cache/ 证据：`.gitignore`\n- **Dockerfile**（source_file）：COPY pyproject.toml README.md ./ RUN pip install --no-cache-dir \". llm \" 证据：`Dockerfile`\n- **Alembic**（source_file）：alembic script location = alembic sqlalchemy.url = postgresql+asyncpg://statewave:statewave@localhost:5432/statewave 证据：`alembic.ini`\n- **Override sqlalchemy.url from env. STATEWAVE DATABASE URL is the first-class**（source_file）：\"\"\"Alembic env — async Postgres migrations.\"\"\" 证据：`alembic/env.py`\n- **revision identifiers, used by Alembic.**（source_file）：Revision ID: ${up revision} Revises: ${down revision comma,n} Create Date: ${create date} \"\"\" from typing import Sequence, Union 证据：`alembic/script.py.mako`\n- **Default to the published multi-arch image — docker compose up -d works**（source_file）：services: db: image: pgvector/pgvector:pg16 environment: POSTGRES USER: statewave POSTGRES PASSWORD: statewave POSTGRES DB: statewave ports: - \"5432:5432\" volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: \"CMD-SHELL\", \"pg isready -U statewave\" interval: 2s timeout: 5s retries: 10 证据：`docker-compose.yml`\n- **Production seeds the docs pack via the dedicated GitHub Actions**（source_file）：app = 'statewave-api' primary region = 'ord' 证据：`fly.toml`\n- **Pyproject**（source_file）：project name = \"statewave\" version = \"0.8.0\" description = \"Open-source memory runtime for AI agents — durable, structured context with provenance.\" readme = \"README.md\" license = {text = \"AGPL-3.0-only OR LicenseRef-Statewave-Commercial\"} requires-python = \" =3.11\" dependencies = \"fastapi =0.111, =0.29, =2.7, =2.2, =2.0, =0.29, =1.13, =0.3, =0.7, =24.1, =6,<7\", 证据：`pyproject.toml`\n- **Allow running as python scripts/bootstrap docs pack.py from repo root**（source_file）：\"\"\"Bootstrap the default Statewave support docs memory pack. 证据：`scripts/bootstrap_docs_pack.py`\n- **Each persona has:**（source_file）：\"\"\"Bootstrap subject snapshots for demo instant seeding. 证据：`scripts/bootstrap_snapshots.py`\n- **─── Per-persona expansion content ──────────────────────────────────────────**（source_file）：\"\"\"Rebuild the 5 bundled demo starter packs with denser, narrative-consistent content that can sustain 8–10 visitor turns of recallable context. 证据：`scripts/build_demo_packs.py`\n- **Allow running as python scripts/build support pack.py from repo root**（source_file）：\"\"\"Build the bundled Statewave Support starter pack from the live docs corpus. 证据：`scripts/build_support_pack.py`\n- **!/usr/bin/env python**（source_file）：!/usr/bin/env python \"\"\"Bump or verify the project version across all user-facing surfaces. 证据：`scripts/bump_version.py`\n- **Triple shape: source, type, payload-dict . The payload's content field is**（source_file）：\"\"\"New-episode content for the 5 demo persona packs. 证据：`scripts/demo_pack_expansions.py`\n- **Curated allowlist — see statewave-docs/default-support-docs-pack.md**（source_file）：\"\"\"Statewave docs → episodes loader. 证据：`scripts/docs_loader.py`\n- **!/usr/bin/env python**（source_file）：!/usr/bin/env python \"\"\"Migration preflight check. 证据：`scripts/preflight.py`\n- **─── Narrative seed data ─────────────────────────────────────────────────────**（source_file）：\"\"\"Re-seed the website demo subjects with rich many-to-one provenance. 证据：`scripts/seed_demo_subjects.py`\n- **Compile job retention**（source_file）：import asyncio from contextlib import asynccontextmanager from importlib.metadata import PackageNotFoundError, version 证据：`server/app.py`\n- **Main**（source_file）：\"\"\"Entrypoint for running the server directly.\"\"\" 证据：`server/main.py`\n- **!/bin/sh**（source_file）：!/bin/sh Boot script for the Fly.io machine. We wait for Postgres to be reachable before running migrations. On Fly especially with auto stop machines=suspend the database can briefly refuse connections during a wake-up, which previously crashed alembic and put the machine in a restart loop. The retry loop turns that into a soft delay instead of a fatal boot. 证据：`start.sh`\n- **Dispose engine after test to ensure clean state for next test**（source_file）：import pytest from httpx import ASGITransport, AsyncClient 证据：`tests/conftest.py`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `helm/statewave/README.md`, `infra/postgres-pgvector/README.md`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `helm/statewave/README.md`, `infra/postgres-pgvector/README.md`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **Statewave 简介**：importance `high`\n  - source_paths: README.md, server/app.py, server/main.py\n- **快速开始**：importance `high`\n  - source_paths: docker-compose.yml, DOCKER.md, .env.example, pyproject.toml\n- **系统架构概览**：importance `high`\n  - source_paths: server/app.py, server/core/config.py, server/core/dependencies.py, server/api/__init__.py, server/db/engine.py\n- **数据流与生命周期**：importance `high`\n  - source_paths: server/api/episodes.py, server/api/memories.py, server/api/context.py, server/services/context.py, server/services/compiler.py\n- **Episode 管理**：importance `high`\n  - source_paths: server/api/episodes.py, server/schemas/requests.py, server/schemas/responses.py, server/domain/models.py\n- **编译器系统**：importance `high`\n  - source_paths: server/services/compiler.py, server/services/compilers/heuristic.py, server/services/compilers/llm.py, server/services/compile_jobs.py, server/services/compile_jobs_durable.py\n- **上下文检索与排名**：importance `high`\n  - source_paths: server/api/context.py, server/services/context.py, server/services/health.py, server/services/sla.py, server/services/embeddings/litellm.py\n- **API 路由参考**：importance `high`\n  - source_paths: server/api/episodes.py, server/api/memories.py, server/api/context.py, server/api/subjects.py, server/api/resolutions.py\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `b2bd8ef853bfa4894f9575890cf0957882f4526b`\n- inspected_files: `pyproject.toml`, `Dockerfile`, `README.md`, `docker-compose.yml`, `docs/state-assembly-receipts.md`, `docs/memory-portability.md`, `docs/licensing.md`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | github_repo:1219923941 | https://github.com/smaramwbc/statewave | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：smaramwbc/statewave\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：local_cli\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- 无阻塞项。\n\n## 项目专属踩坑\n\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n- 存在评分风险（medium）：风险会影响是否适合普通用户安装。 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- issue/PR 响应质量未知（low）：用户无法判断遇到问题后是否有人维护。 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/smaramwbc/statewave 项目说明书\n\n生成时间：2026-05-14 12:54:51 UTC\n\n## 目录\n\n- [Statewave 简介](#p-intro)\n- [快速开始](#p-quickstart)\n- [系统架构概览](#p-arch-overview)\n- [数据流与生命周期](#p-data-flow)\n- [Episode 管理](#p-episodes)\n- [编译器系统](#p-compiler)\n- [上下文检索与排名](#p-context-retrieval)\n- [API 路由参考](#p-api-routes)\n- [服务层实现](#p-services)\n- [数据库架构](#p-database)\n\n<a id='p-intro'></a>\n\n## Statewave 简介\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [快速开始](#p-quickstart)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n- [server/starter_packs/statewave-support-agent/manifest.json](https://github.com/smaramwbc/statewave/blob/main/server/starter_packs/statewave-support-agent/manifest.json)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [scripts/docs_loader.py](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n- [helm/statewave/README.md](https://github.com/smaramwbc/statewave/blob/main/helm/statewave/README.md)\n</details>\n\n# Statewave 简介\n\nStatewave 是一个专为 AI Agent 设计的**记忆管理系统**，帮助 Agent 从真实世界的各种数据源中构建、检索和利用持久化记忆。通过提供 Episode（事件片段）摄取、Memory（记忆片段）编译、上下文组装等功能，Statewave 使 Agent 能够在多轮对话和工作流程中保持一致性和连续性。\n\n资料来源：[README.md:1-20]()\n\n## 核心概念\n\nStatewave 的数据模型围绕以下核心实体构建：\n\n```mermaid\ngraph TD\n    A[Subject 主体] --> B[Episode 事件片段]\n    A --> C[Memory 记忆片段]\n    B --> D[Compilation 编译]\n    C --> E[Context 上下文]\n    F[Resolution 解决方案] --> A\n    G[Snapshot 快照] --> A\n```\n\n### Subject（主体）\n\nSubject 是最高层级的数据容器，代表一个特定的实体（如客户、项目、用户或任何需要记忆的抽象概念）。每个 Subject 拥有独立的 Episode 和 Memory 存储空间。\n\n资料来源：[server/starter_packs/statewave-support-agent/manifest.json:8]()\n\n### Episode（事件片段）\n\nEpisode 是 Statewave 中的基础数据单元，代表一次不可变的事件或交互记录。Episode 可以来源于：\n\n- 实时对话转录\n- GitHub Issues、Pull Requests\n- 文档变更\n- Slack 消息\n- MCP Server 事件\n- 任何自定义数据源\n\n每个 Episode 包含标题、正文内容、元数据以及来源信息，通过 `content_hash` 实现内容去重和增量更新。\n\n资料来源：[scripts/docs_loader.py:30-50]()\n\n### Memory（记忆片段）\n\nMemory 是经过编译（Compile）后的结构化记忆。编译过程从多个 Episode 中提取关键信息，生成包含以下属性的记忆单元：\n\n| 属性 | 说明 |\n|------|------|\n| `kind` | 记忆类型（如决策、偏好、问题等） |\n| `content` | 记忆内容 |\n| `summary` | 摘要信息 |\n| `confidence` | 置信度 |\n| `valid_from` | 有效起始时间 |\n| `valid_to` | 有效结束时间（可选） |\n| `source_episode_ids` | 来源 Episode ID 列表 |\n\n资料来源：[server/api/admin.py:50-80]()\n\n### Resolution（解决方案）\n\nResolution 用于跟踪会话级别的解决方案状态，支持 SLA 指标计算和响应时间追踪。\n\n资料来源：[server/api/timeline.py:60-90]()\n\n### Snapshot（快照）\n\nSnapshot 提供 Subject 的完整状态快照功能，包含 Episodes、Memories 和 Resolutions 的时间点副本，支持数据恢复和迁移场景。\n\n资料来源：[server/services/snapshots.py:20-80]()\n\n## 系统架构\n\nStatewave 采用现代化的微服务架构设计，主要组件包括：\n\n```mermaid\ngraph TD\n    subgraph 客户端层\n        A[Agent 应用]\n        B[Connectors]\n        C[SDK]\n    end\n    \n    subgraph API 网关层\n        D[FastAPI Server<br/>:8100]\n        E[OpenAPI / Swagger]\n    end\n    \n    subgraph 业务逻辑层\n        F[Episode Service]\n        G[Memory Service]\n        H[Context Service]\n        I[Timeline Service]\n    end\n    \n    subgraph 数据层\n        J[(PostgreSQL)]\n        K[(Embedding Store)]\n    end\n    \n    subgraph 外部服务\n        L[LiteLLM]\n        M[LLM Provider]\n    end\n    \n    A --> D\n    B --> D\n    C --> D\n    D --> F\n    D --> G\n    D --> H\n    D --> I\n    F --> J\n    G --> J\n    G --> K\n    H --> L\n    I --> J\n    L --> M\n```\n\n### 技术栈\n\n| 层级 | 技术选型 |\n|------|----------|\n| API 框架 | FastAPI |\n| 数据库 | PostgreSQL + asyncpg |\n| LLM 集成 | LiteLLM |\n| 向量嵌入 | 可配置（默认 LiteLLM） |\n| 部署方式 | Docker / Kubernetes Helm |\n\n资料来源：[README.md:50-70]()\n\n## API 参考\n\n### 健康检查端点\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活探针 |\n| `GET /readyz` 或 `GET /ready` | 就绪探针 |\n\n### Episode 管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄取单个 Episode（追加模式） |\n| `POST` | `/v1/episodes/batch` | 批量摄取最多 100 个 Episode |\n\n资料来源：[README.md:30-45]()\n\n### Memory 管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/memories/compile` | 编译 Memories（幂等操作） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n\n### Context 上下文组装\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/context` | 组装基于排序和 Token 限制的上下文包 |\n\n### Subject 主体管理\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `GET` | `/v1/subjects` | 列出已知主体及 Episode/Memory 计数 |\n| `DELETE` | `/v1/subjects/{id}` | 永久删除主体的所有数据 |\n| `GET` | `/v1/subjects/{id}/health` | 客户健康评分及可解释因素 |\n| `GET` | `/v1/subjects/{id}/sla` | SLA 指标（响应时间、解决时间、违反情况） |\n\n### 时间线与解决方案\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `GET` | `/v1/timeline` | 按时间顺序排列的主体时间线 |\n| `POST` | `/v1/resolutions` | 跟踪每个会话的解决方案状态 |\n| `GET` | `/v1/resolutions` | 列出主体的解决方案 |\n| `POST` | `/v1/handoff` | 生成紧凑的交接上下文包 |\n\n资料来源：[README.md:35-55]()\n\n## 编译模式\n\nStatewave 支持两种编译模式：\n\n### LLM 编译（默认）\n\n使用大型语言模型从 Episode 中提取结构化 Memory，提供更高的语义理解能力。需要配置 LLM API Key。\n\n### 启发式编译\n\n基于规则的编译模式，适用于演示环境或无 LLM 场景，性能更快但语义理解能力有限。\n\n配置方式：`STATEWAVE_COMPILER_TYPE=heuristic`\n\n资料来源：[helm/statewave/README.md:25-30]()\n\n## 连接器生态\n\nStatewave 提供了丰富的连接器（Connector）生态系统，用于从不同数据源摄取 Episode：\n\n| 数据源 | 功能 | 状态 |\n|--------|------|------|\n| MCP Server | Copilot/Claude/Cursor/Agent 记忆同步 | ✅ 已发布 |\n| GitHub | Issues、PRs、Reviews、Releases → Repo 记忆 | ✅ 已发布 |\n| Markdown | 本地文档、ADR、RFC → 决策记忆 | ✅ 已发布 |\n| Slack | 频道消息同步 | ✅ 已发布 |\n| n8n | 工作流事件集成 | ✅ 已发布 |\n| Zapier | Zapier 自动化集成 | ✅ 已发布 |\n\n安装方式（按需选择）：\n\n```bash\nnpm install @statewavedev/connectors-github\nnpm install @statewavedev/connectors-markdown\nnpm install @statewavedev/connectors-slack\nnpm install @statewavedev/connectors-n8n\nnpm install @statewavedev/connectors-zapier\nnpm install @statewavedev/mcp-server\n```\n\n资料来源：[README.md:80-110]()\n\n## 配置参考\n\n### 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接字符串（必填） |\n| `STATEWAVE_LITELLM_API_KEY` | — | LiteLLM API Key（LLM/嵌入必需） |\n| `STATEWAVE_LITELLM_BASE_URL` | — | LiteLLM 自定义基础 URL |\n| `STATEWAVE_EMBEDDING_PROVIDER` | `litellm` | 嵌入提供商 |\n| `STATEWAVE_COMPILER_TYPE` | `llm` | `llm` 或 `heuristic` |\n| `STATEWAVE_API_KEY` | — | API 认证密钥 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每分钟/IP 请求限制（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | `distributed`（Postgres）或 `memory` |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离 Header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 Header |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 上下文组装默认 Token 预算 |\n| `STATEWAVE_CORS_ORIGINS` | `[\"*\"]` | 允许的 CORS 来源列表 |\n\n资料来源：[README.md:100-120]()\n\n## 部署方式\n\n### Docker Compose 部署\n\n```yaml\nservices:\n  statewave:\n    image: statewavedev/statewave:latest\n    ports: [\"8100:8100\"]\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n\nvolumes:\n  pgdata:\n```\n\n```bash\ndocker compose up -d\ncurl http://localhost:8100/healthz\n```\n\n指定版本部署：\n\n```bash\nSTATEWAVE_VERSION=0.7.0 docker compose up -d\n```\n\n### Kubernetes Helm 部署\n\n```bash\nhelm install statewave ./helm/statewave \\\n  --set database.url='postgresql+asyncpg://...' \\\n  --set llm.apiKey='sk-...'\n```\n\nHelm 安装时会自动运行数据库迁移（Alembic）Job，确保在 API Pod 接收流量前完成 schema 初始化。\n\n资料来源：[DOCKER.md:1-50]()\n资料来源：[helm/statewave/README.md:1-30]()\n\n### Docker 镜像标签\n\n| 标签 | 含义 |\n|------|------|\n| `latest` | main 分支最新代码 |\n| `X.Y.Z` | 语义化版本发布 |\n| `X.Y` | 该 minor 版本的最新版本 |\n| `X` | 该 major 版本的最新版本 |\n| `sha-<7>` | 特定 Commit |\n\n资料来源：[DOCKER.md:30-40]()\n\n## 启动包\n\nStatewave 提供了开箱即用的 Starter Pack，其中包含预置的 Episodes 和 Memories：\n\n### statewave-support-agent\n\n预编译的支持代理启动包，包含 276 个 Episodes 和 364 个 Memories，涵盖：\n\n- 产品文档\n- 架构设计\n- 部署指南\n- 故障排除\n- 竞品对比\n\n版本：`1.2026.05.08`\n\n导入后可立即启用文档驱动的支持代理，无需额外引导步骤。\n\n资料来源：[server/starter_packs/statewave-support-agent/manifest.json:1-20]()\n\n## 当前限制\n\nStatewave 目前处于活跃开发阶段（v0.8.0），存在以下已知限制：\n\n### 速率限制\n\n- **速率限制按 IP 级别**：使用分布式（Postgres 后端）实现，但仅按 IP 键控，尚未支持按租户或 API Key 级别限制\n\n### 多租户\n\n- **多租户隔离在应用层**：通过查询作用域数据隔离（v0.5）+ 每租户配置/策略/收据包（v0.8）实现\n- **尚未支持 PostgreSQL RLS**（行级安全策略）\n\n资料来源：[README.md:130-140]()\n\n## 测试\n\n### 运行测试\n\n```bash\n# 单元测试（无需数据库）\npytest tests/test_*.py -v\n\n# 集成测试（需要 PostgreSQL）\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\npytest tests/integration/ -v\n\n# 全部测试\npytest tests/ -v\n```\n\n资料来源：[README.md:120-130]()\n\n## 相关资源\n\n- 官方文档：https://statewave.ai\n- 仓库地址：https://github.com/smaramwbc/statewave\n- 连接器生态：https://github.com/smaramwbc/statewave-connectors\n- API 契约文档：https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md\n\n---\n\n<a id='p-quickstart'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[Statewave 简介](#p-intro)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [docker-compose.yml](https://github.com/smaramwbc/statewave/blob/main/docker-compose.yml)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n- [.env.example](https://github.com/smaramwbc/statewave/blob/main/.env.example)\n- [pyproject.toml](https://github.com/smaramwbc/statewave/blob/main/pyproject.toml)\n</details>\n\n# 快速开始\n\n本页面提供 Statewave 的快速部署和基本使用指南，帮助你在本地环境快速启动服务并验证核心功能。\n\n## 系统要求\n\n| 组件 | 最低要求 | 推荐配置 |\n|------|----------|----------|\n| Docker | 20.10+ | 最新稳定版 |\n| Docker Compose | 2.0+ | v2.x |\n| PostgreSQL | 14+ | 15+ |\n| 内存 | 4GB | 8GB+ |\n| CPU | 2核 | 4核+ |\n\n资料来源：[docker-compose.yml:1-50]()\n\n## 快速启动（Docker Compose）\n\n### 1. 克隆仓库\n\n```bash\ngit clone https://github.com/smaramwbc/statewave.git\ncd statewave\n```\n\n### 2. 配置环境变量\n\nStatewave 通过环境变量进行配置。在项目根目录创建 `.env` 文件：\n\n```bash\ncp .env.example .env\n```\n\n基础配置项：\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接字符串，必填 |\n| `STATEWAVE_LITELLM_API_KEY` | — | LLM API 密钥（用于编译功能） |\n| `STATEWAVE_API_KEY` | — | API 访问密钥 |\n| `STATEWAVE_PORT` | `8100` | 服务监听端口 |\n| `STATEWAVE_RATE_LIMIT_PER_MIN` | `60` | 每IP每分钟请求限制 |\n\n资料来源：[.env.example](https://github.com/smaramwbc/statewave/blob/main/.env.example)\n\n### 3. 启动服务\n\n```yaml\n# docker-compose.yml 核心配置\nservices:\n  app:\n    image: statewavedev/statewave:latest\n    ports:\n      - \"8100:8100\"\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n\nvolumes:\n  pgdata:\n```\n\n```bash\ndocker compose up -d\n```\n\n资料来源：[DOCKER.md:1-20]()\n\n### 4. 验证服务\n\n服务启动后，通过健康检查端点验证：\n\n```bash\ncurl http://localhost:8100/healthz\n```\n\n预期响应：`{\"status\":\"ok\"}`\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活检查 |\n| `GET /readyz` 或 `GET /ready` | 就绪检查 |\n\n资料来源：[README.md:50-55]()\n\n## 服务架构\n\n```mermaid\ngraph TD\n    A[客户端] --> B[Statewave API<br/>:8100]\n    B --> C[PostgreSQL<br/>Database]\n    B --> D[LLM Provider<br/>LiteLLM]\n    B --> E[Embedding Provider]\n    \n    F[Connectors] --> B\n    G[SDK] --> B\n    \n    style B fill:#e1f5fe\n    style C fill:#f3e5f5\n```\n\n## API 基础使用\n\n### 文档界面\n\n| 地址 | 说明 |\n|------|------|\n| `http://localhost:8100/docs` | OpenAPI (Swagger) 文档 |\n| `http://localhost:8100/redoc` | ReDoc 文档 |\n\n### 核心 API 端点\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄入单个事件（仅追加） |\n| `POST` | `/v1/episodes/batch` | 批量摄入最多 100 个事件 |\n| `POST` | `/v1/memories/compile` | 从事件编译记忆（幂等） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n| `POST` | `/v1/context` | 组装带 token 限制的上下文包 |\n| `GET` | `/v1/timeline` | 按时间线查看主题历史 |\n| `GET` | `/v1/subjects` | 列出已知主题及其事件/记忆计数 |\n| `DELETE` | `/v1/subjects/{id}` | 永久删除主题的所有数据 |\n\n资料来源：[README.md:40-45]()\n\n### 基本请求示例\n\n**摄入事件：**\n\n```bash\ncurl -X POST http://localhost:8100/v1/episodes \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-Tenant-ID: default\" \\\n  -d '{\n    \"subject_id\": \"user-123\",\n    \"source\": \"api\",\n    \"type\": \"conversation\",\n    \"payload\": {\n      \"role\": \"user\",\n      \"content\": \"如何部署 Statewave？\"\n    },\n    \"session_id\": \"session-001\"\n  }'\n```\n\n**搜索记忆：**\n\n```bash\ncurl \"http://localhost:8100/v1/memories/search?query=部署\" \\\n  -H \"X-Tenant-ID: default\"\n```\n\n## 版本管理\n\nStatewave 支持指定版本部署：\n\n```bash\nSTATEWAVE_VERSION=0.7.0 docker compose up -d\n```\n\n| 标签格式 | 含义 |\n|----------|------|\n| `latest` | main 分支最新代码 |\n| `X.Y.Z` | 语义化版本发布 |\n| `X.Y` | 所属小版本的最新版本 |\n| `X` | 所属大版本的最新版本 |\n| `sha-<7>` | 特定提交 |\n\n资料来源：[DOCKER.md:25-35]()\n\n## 运行测试\n\n```bash\n# 单元测试（无需数据库）\npytest tests/test_*.py -v\n\n# 集成测试（需要 PostgreSQL）\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\npytest tests/integration/ -v\n\n# 运行全部测试\npytest tests/ -v\n```\n\n资料来源：[README.md:180-190]()\n\n## 完整配置选项\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接 URL，必填 |\n| `STATEWAVE_PORT` | `8100` | 服务端口 |\n| `STATEWAVE_API_KEY` | — | API 密钥认证 |\n| `STATEWAVE_LITELLM_API_KEY` | — | LiteLLM API 密钥 |\n| `STATEWAVE_LITELLM_BASE_URL` | — | LiteLLM 基础 URL |\n| `STATEWAVE_EMBEDDING_PROVIDER` | `litellm` | 嵌入提供者（litellm/stub） |\n| `STATEWAVE_COMPILER_TYPE` | `llm` | 编译器类型（llm/heuristic） |\n| `STATEWAVE_RATE_LIMIT_PER_MIN` | `60` | 每IP每分钟请求限制（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略（distributed/memory） |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_WEBHOOK_TIMEOUT` | `5.0` | Webhook 超时时间（秒） |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离 Header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 Header |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 上下文组装默认 token 预算 |\n| `STATEWAVE_CORS_ORIGINS` | `[\"*\"]` | 允许的 CORS 来源 |\n\n资料来源：[README.md:155-175]()\n\n## 下一步\n\n- 查看 [API v1 完整契约](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n- 阅读[部署指南](https://github.com/smaramwbc/statewave-docs/blob/main/deployment/guide.md)\n- 了解 [Connectors 生态系统](https://github.com/smaramwbc/statewave-connectors)\n- 查看[架构文档](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/overview.md)\n\n---\n\n<a id='p-arch-overview'></a>\n\n## 系统架构概览\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [API 路由参考](#p-api-routes), [服务层实现](#p-services)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/app.py](https://github.com/smaramwbc/statewave/blob/main/server/app.py)\n- [server/core/config.py](https://github.com/smaramwbc/statewave/blob/main/server/core/config.py)\n- [server/core/dependencies.py](https://github.com/smaramwbc/statewave/blob/main/server/core/dependencies.py)\n- [server/api/__init__.py](https://github.com/smaramwbc/statewave/blob/main/server/api/__init__.py)\n- [server/db/engine.py](https://github.com/smaramwbc/statewave/blob/main/server/db/engine.py)\n- [README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n</details>\n\n# 系统架构概览\n\n## 1. 概述\n\nStatewave 是一个自托管的长期记忆管理系统，专为 AI Agent 设计，旨在帮助 Agents 跨越会话边界保持上下文连贯性。该系统通过摄取事件片段（Episodes）、编译记忆（Memories）、并提供智能检索上下文构建能力，使 AI Agent 能够在多轮对话中持续学习和适应。\n\n当前版本：v0.8.0，采用 AGPL-3.0 开源协议。资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n## 2. 核心设计理念\n\nStatewave 的架构围绕三个核心概念展开：\n\n| 概念 | 说明 |\n|------|------|\n| **Episode（事件片段）** | 原子化的输入单元，代表一次交互、一条消息或一个外部事件 |\n| **Memory（记忆）** | 从 Episodes 编译提取的结构化知识，具有时间有效性和置信度 |\n| **Subject（主体）** | 记忆归属的实体（如客户、用户、项目），实现数据隔离 |\n\n系统支持两种编译模式：LLM 编译（语义理解）和 Heuristic 编译（规则提取）。资料来源：[server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n## 3. 系统架构图\n\n```mermaid\ngraph TB\n    subgraph 接入层\n        API[REST API v1]\n        DOCS[OpenAPI / Swagger]\n        REDOC[ReDoc]\n    end\n\n    subgraph 应用层\n        EP[Episode 管理]\n        MEM[Memory 管理]\n        CTX[Context 构建]\n        TIMELINE[Timeline 服务]\n        SNAP[Snapshot 服务]\n        ADMIN[Admin API]\n    end\n\n    subgraph 服务层\n        COMPILER[编译引擎]\n        RANKER[排名服务]\n        SEARCH[搜索服务]\n    end\n\n    subgraph 数据层\n        DB[(PostgreSQL)]\n        CACHE[缓存层]\n    end\n\n    API --> EP\n    API --> MEM\n    API --> CTX\n    API --> TIMELINE\n    API --> SNAP\n    API --> ADMIN\n\n    EP --> COMPILER\n    MEM --> RANKER\n    CTX --> RANKER\n    CTX --> SEARCH\n\n    COMPILER --> DB\n    RANKER --> DB\n    SEARCH --> DB\n    TIMELINE --> DB\n    SNAP --> DB\n```\n\n## 4. 技术栈\n\n| 层级 | 技术选型 |\n|------|----------|\n| Web 框架 | FastAPI |\n| 数据库 | PostgreSQL + asyncpg |\n| ORM | SQLAlchemy (async) |\n| 编译后端 | LiteLLM (支持多种 LLM 提供商) |\n| 部署方式 | Docker Compose / Helm |\n| 认证 | API Key / X-Tenant-ID 多租户隔离 |\n\n资料来源：[DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n\n## 5. API 架构\n\n### 5.1 主要端点\n\n| 方法 | 路径 | 描述 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 摄入单个事件片段 |\n| `POST` | `/v1/episodes/batch` | 批量摄入事件片段（最多100个） |\n| `POST` | `/v1/memories/compile` | 编译记忆（幂等操作） |\n| `GET` | `/v1/memories/search` | 按类型、文本或语义相似度搜索 |\n| `POST` | `/v1/context` | 组装带排名的 token 受限上下文包 |\n| `GET` | `/v1/timeline` | 主体时间线 |\n| `GET` | `/v1/subjects` | 列出已知主体及事件/记忆计数 |\n| `DELETE` | `/v1/subjects/{id}` | 删除主体所有数据 |\n| `POST` | `/v1/resolutions` | 跟踪会话解决状态 |\n| `GET` | `/v1/resolutions` | 列出主体解决方案 |\n| `POST` | `/v1/handoff` | 生成紧凑的交接上下文包 |\n| `GET` | `/v1/subjects/{id}/health` | 健康评分及可解释因素 |\n| `GET` | `/v1/subjects/{id}/sla` | SLA 指标 |\n\n资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n### 5.2 健康检查端点\n\n| 端点 | 用途 |\n|------|------|\n| `GET /healthz` 或 `GET /health` | 存活探针 |\n| `GET /readyz` 或 `GET /ready` | 就绪探针 |\n\n## 6. 数据模型\n\n### 6.1 核心实体关系\n\n```mermaid\nerDiagram\n    SUBJECT ||--o{ EPISODE : contains\n    SUBJECT ||--o{ MEMORY : owns\n    EPISODE ||--o{ MEMORY : contributes_to\n    SUBJECT ||--o{ RESOLUTION : tracks\n    SUBJECT ||--o| SNAPSHOT : preserves\n```\n\n### 6.2 Episode 数据结构\n\n事件片段是系统的原子输入单元，包含：\n\n```python\n{\n    \"id\": \"uuid\",\n    \"subject_id\": \"string\",\n    \"source\": \"string\",           # 来源标识 (e.g., \"api\", \"github\", \"slack\")\n    \"type\": \"string\",            # 类型 (e.g., \"chat\", \"issue\", \"doc_section\")\n    \"payload\": {\n        \"text\": \"string\",\n        \"messages\": [...],\n        \"event_time\": \"datetime\"  # 可选的显式时间戳\n    },\n    \"metadata\": {},\n    \"provenance\": {\n        \"content_hash\": \"string\",\n        \"pack_version\": \"int\"\n    },\n    \"occurred_at\": \"datetime\",\n    \"created_at\": \"datetime\",\n    \"session_id\": \"string | null\"\n}\n```\n\n资料来源：[server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n### 6.3 Memory 数据结构\n\n记忆从事件编译而来，具有时间有效性和置信度：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 唯一标识 |\n| `subject_id` | string | 归属主体 |\n| `kind` | string | 记忆类型（如 episode_summary, profile_fact） |\n| `content` | string | 记忆内容 |\n| `summary` | string | 内容摘要 |\n| `confidence` | float | 置信度 0.0-1.0 |\n| `valid_from` | datetime | 有效起始时间 |\n| `valid_to` | datetime | 有效结束时间（可选） |\n| `source_episode_ids` | list[UUID] | 来源事件片段 |\n| `status` | string | 状态（active, superseded） |\n| `sensitivity_labels` | list[string] | 敏感标签 |\n\n资料来源：[server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n## 7. 服务层架构\n\n### 7.1 编译引擎\n\n编译引擎负责将 Episodes 转换为 Memories，支持两种模式：\n\n```mermaid\ngraph LR\n    A[Episodes] --> B{编译模式}\n    B -->|Heuristic| C[规则提取]\n    B -->|LLM| D[语义理解]\n    C --> E[Memories]\n    D --> E\n```\n\n**Heuristic 编译**：基于规则提取摘要和配置事实\n\n- `episode_summary`：从文本提取摘要，置信度 0.8\n- `profile_fact`：提取配置类事实，置信度 0.6\n\n资料来源：[server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n### 7.2 上下文构建服务\n\n上下文构建服务（Context Service）负责根据查询组装最优上下文：\n\n```mermaid\ngraph TB\n    Q[用户查询] --> S[搜索相关Memories和Episodes]\n    S --> SC[评分计算]\n    SC --> R[相关性评分]\n    R --> RANK[排名服务]\n    RANK --> TB[Token预算约束]\n    TB --> CTX[组装上下文包]\n```\n\nContext Service 内部使用 `_ScoredItem` 类管理评分：\n\n```python\nclass _ScoredItem:\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n资料来源：[server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n\n### 7.3 快照服务\n\n快照服务支持主体的完整备份和恢复：\n\n| 操作 | 说明 |\n|------|------|\n| 创建快照 | 导出主体的所有 Episodes、Memories、Resolutions |\n| 恢复快照 | 支持时间偏移重放，可重建历史状态 |\n| 增量更新 | 保留 `restored_from_snapshot` 元数据 |\n\n资料来源：[server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n## 8. 时间线服务\n\n时间线服务（Timeline Service）提供会话视图的事件合并展示：\n\n```mermaid\ngraph TB\n    subgraph 事件类型\n        EE[Episode Event]\n        RE[Resolution Event]\n    end\n    \n    subgraph 时间线事件\n        TEE[TimelineEpisodeEvent]\n        TRE[TimelineResolutionEvent]\n    end\n    \n    EE --> TEE\n    RE --> TRE\n    TEE --> MERGE[合并排序]\n    TRE --> MERGE\n    MERGE --> RESP[SessionTimelineResponse]\n```\n\n关键指标计算：\n- `first_response_seconds`：首次响应时间\n- `resolution_seconds`：解决时间\n- `first_response_breached`：是否超出 SLA 首次响应阈值\n- `resolution_breached`：是否超出 SLA 解决时间阈值\n\n资料来源：[server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n## 9. 多租户架构\n\nStatewave 采用应用层多租户隔离：\n\n| 配置项 | 默认值 | 说明 |\n|--------|--------|------|\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 租户隔离 header |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户 header |\n| 隔离方式 | 查询作用域 | 基于 tenant_id 的数据过滤 |\n\n**当前限制**：\n- 限流基于 IP 地址，未实现 per-tenant 或 per-API-key 限流\n- 多租户采用应用层隔离，非 PostgreSQL Row-Level Security (RLS)\n\n资料来源：[README.md](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n## 10. 配置管理\n\n### 10.1 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | — | PostgreSQL 连接串（必需） |\n| `STATEWAVE_LITELLM_API_KEY` | — | LLM API 密钥 |\n| `STATEWAVE_API_KEY` | — | 服务认证密钥 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每 IP 每分钟请求数 |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略 |\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认上下文 token 预算 |\n\n### 10.2 编译模式配置\n\n| 模式 | 配置值 | 适用场景 |\n|------|--------|----------|\n| LLM 编译 | `compiler.type=llm` | 生产环境，语义理解 |\n| Heuristic 编译 | `compiler.type=heuristic` | Demo/无 LLM 模式 |\n\n资料来源：[helm/statewave/README.md](https://github.com/smaramwbc/statewave/blob/main/helm/statewave/README.md)\n\n## 11. 部署架构\n\n### 11.1 Docker 部署\n\n```yaml\nservices:\n  statewave:\n    image: statewavedev/statewave:latest\n    ports: [\"8100:8100\"]\n    environment:\n      STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n      STATEWAVE_LITELLM_API_KEY: sk-...\n    depends_on:\n      db:\n        condition: service_healthy\n```\n\n### 11.2 Kubernetes 部署\n\n使用 Helm Chart 部署，包含：\n- Pre-install Job：运行数据库迁移（`alembic upgrade head`）\n- Pre-upgrade Job：升级时重复迁移\n- 支持 `existingSecret` 引用敏感配置\n\n资料来源：[DOCKER.md](https://github.com/smaramwbc/statewave/blob/main/DOCKER.md)\n\n## 12. 启动流程\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant API as FastAPI App\n    participant DB as PostgreSQL\n    participant Migrator as Alembic\n    \n    Client->>API: 启动请求\n    API->>Migrator: alembic upgrade head\n    Migrator->>DB: 执行迁移\n    DB-->>Migrator: 迁移完成\n    Migrator-->>API: 就绪\n    API-->>Client: 服务可用\n```\n\n## 13. 外部集成\n\n### 13.1 连接器生态\n\nStatewave 提供官方连接器将外部数据源摄入为 Episodes：\n\n| 来源 | 记忆形态 | 状态 |\n|------|----------|------|\n| MCP Server | Agent 记忆 | ✅ 已发布 |\n| GitHub | Issues, PRs, Releases | ✅ 已发布 |\n| Markdown | 文档/决策记忆 | ✅ 已发布 |\n| Slack | 对话记忆 | ✅ 已发布 |\n\n### 13.2 SDK 支持\n\n提供 Python SDK 支持自定义摄入路径，连接器独立安装：\n\n```bash\nnpm install @statewavedev/connectors-github\nnpm install @statewavedev/connectors-markdown\nnpm install @statewavedev/mcp-server\n```\n\n## 14. 安全特性\n\n| 特性 | 说明 |\n|------|------|\n| API Key 认证 | 通过 `Authorization: Bearer <key>` |\n| 多租户隔离 | 基于 `X-Tenant-ID` header |\n| 敏感标签 | Memory 支持 `sensitivity_labels` |\n| 数据删除 | DELETE `/v1/subjects/{id}` 永久删除 |\n\n## 15. 测试架构\n\n| 测试类型 | 命令 | 依赖 |\n|----------|------|------|\n| 单元测试 | `pytest tests/test_*.py -v` | 无 DB |\n| 集成测试 | `pytest tests/integration/ -v` | PostgreSQL |\n| 全部测试 | `pytest tests/ -v` | PostgreSQL |\n\n集成测试数据库配置：\n```bash\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\n```\n\n## 16. 总结\n\nStatewave 采用分层架构设计，从底层的 PostgreSQL 数据持久化，到服务层的编译引擎、上下文构建、排名服务，再到 API 接入层，构成了一个完整的 AI Agent 记忆管理系统。其核心优势包括：\n\n1. **事件驱动的摄入**：支持多种来源（API、连接器、Webhook）\n2. **灵活的编译引擎**：兼容 LLM 和 Heuristic 两种模式\n3. **智能上下文组装**：基于 token 预算的排名检索\n4. **企业级功能**：多租户、快照、SLA 追踪\n5. **可观测性**：健康检查、Webhook 回调\n\n系统当前处于活跃开发状态（v0.8.0），建议生产环境使用语义版本号固定部署。\n\n---\n\n<a id='p-data-flow'></a>\n\n## 数据流与生命周期\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [Episode 管理](#p-episodes), [编译器系统](#p-compiler), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py)\n- [server/api/memories.py](https://github.com/smaramwbc/statewave/blob/main/server/api/memories.py)\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/compiler.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compiler.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/db/tables.py](https://github.com/smaramwbc/statewave/blob/main/server/db/tables.py)\n</details>\n\n# 数据流与生命周期\n\nStatewave 是一个长期记忆管理系统，其核心功能围绕 **Episode（事件）** → **Memory（记忆）** → **Context（上下文）** 的数据流展开。本页详细说明这三个核心实体的生命周期、数据转换过程，以及系统如何管理时间敏感信息的有效性。\n\n---\n\n## 系统架构概览\n\nStatewave 的数据流遵循经典的 ETL（Extract-Transform-Load）模式，但增加了时间维度的管理。系统接收外部事件作为 Episode，经过编译器（Compiler）处理后生成 Memory，最终通过 Context 服务组装为可供 AI Agent 使用的上下文包。\n\n```mermaid\ngraph TD\n    subgraph 数据源\n        E1[聊天/对话]\n        E2[GitHub Events]\n        E3[Slack 消息]\n        E4[MCP Server]\n        E5[Markdown 文档]\n    end\n    \n    subgraph 摄入层\n        EP[Episode 输入]\n    end\n    \n    subgraph 存储层\n        DB[(PostgreSQL)]\n    end\n    \n    subgraph 处理层\n        HC[Heuristic 编译器]\n        LC[LLM 编译器]\n    end\n    \n    subgraph 查询层\n        CTX[Context 上下文服务]\n        SCH[记忆搜索]\n        TLM[时间线查询]\n    end\n    \n    E1 --> EP\n    E2 --> EP\n    E3 --> EP\n    E4 --> EP\n    E5 --> EP\n    \n    EP --> DB\n    HC --> DB\n    LC --> DB\n    DB --> CTX\n    DB --> SCH\n    DB --> TLM\n```\n\n---\n\n## Episode 生命周期\n\n### 什么是 Episode\n\nEpisode 是 Statewave 中的**原始事件单元**，代表一次不可变的事实记录。它可以是客户对话、代码提交、文档更新、问题报告等任何有意义的事件。资料来源：[server/services/compilers/heuristic.py:1-50]()\n\n### Episode 的数据结构\n\n每个 Episode 包含以下核心字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 全局唯一标识符 |\n| `subject_id` | UUID | 所属主体 ID |\n| `session_id` | UUID | 关联的会话 ID（可选） |\n| `source` | string | 来源标识（mcp, github, slack 等） |\n| `type` | string | 事件类型（message, issue, pr 等） |\n| `payload` | JSON | 原始载荷数据 |\n| `provenance` | JSON | 来源元数据（内容哈希等） |\n| `occurred_at` | datetime | 事件发生时间 |\n| `created_at` | datetime | 记录创建时间 |\n\n资料来源：[server/db/tables.py]() 中的 `EpisodeRow` 定义\n\n### Episode 的时间锚定\n\n时间锚定（Temporal Anchoring）是 Episode 处理的关键环节。系统按以下优先级确定记忆的 `valid_from` 时间：\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"Return the best-effort temporal anchor for memories derived from\n    this episode.\n\n    Priority:\n      1. `payload.event_time` — explicit override set by the client\n         (e.g. a connector replaying historical data sets this to the\n         actual event date, not the POST date).\n      2. `payload.messages[0].timestamp` — the first-message timestamp\n         on chat-shaped payloads. This is what LoCoMo, Slack, Zendesk\n         etc emit naturally; preserving it as `valid_from`\"\"\"\n```\n\n资料来源：[server/services/compilers/heuristic.py:80-95]()\n\n这种设计确保了：\n- 连接器回放历史数据时使用真实事件时间\n- 实时聊天数据保留消息时间戳\n- 没有明确时间戳时回退到记录创建时间\n\n### Episode 的创建与批量摄入\n\n```mermaid\nsequenceDiagram\n    participant C as 客户端\n    participant API as /v1/episodes\n    participant DB as 数据库\n    \n    C->>API: POST /v1/episodes (单个)\n    API->>DB: Insert EpisodeRow\n    DB-->>API: 返回 ID\n    API-->>C: 201 Created\n    \n    Note over C,API: 批量摄入\n    C->>API: POST /v1/episodes/batch (最多100个)\n    API->>DB: Batch Insert\n    DB-->>API: 返回 ID 列表\n    API-->>C: 201 Created\n```\n\nAPI 支持单条和批量（最多 100 条）摄入。批量接口保证原子性——要么全部成功，要么全部回滚。资料来源：[README.md:API 文档]()\n\n---\n\n## Memory 生命周期\n\n### 编译过程概述\n\nMemory 是从 Episode 编译而来的**派生数据**，代表从原始事件中提取的结构化知识。编译过程可以是：\n\n1. **Heuristic 编译器**：基于规则的内容提取，速度快，适合结构化数据\n2. **LLM 编译器**：基于语言模型的语义理解，适合非结构化对话\n\n```mermaid\ngraph LR\n    subgraph 输入\n        EP1[Episode 1]\n        EP2[Episode 2]\n        EP3[Episode N]\n    end\n    \n    subgraph 编译\n        CMP[Compiler]\n        EP1 --> CMP\n        EP2 --> CMP\n        EP3 --> CMP\n    end\n    \n    subgraph 输出\n        MEM1[episode_summary]\n        MEM2[profile_fact]\n        MEM3[decision]\n        MEM4[preference]\n    end\n    \n    CMP --> MEM1\n    CMP --> MEM2\n    CMP --> MEM3\n    CMP --> MEM4\n```\n\n资料来源：[server/services/compiler.py]()\n\n### Heuristic 编译器的提取规则\n\nHeuristic 编译器从 Episode 内容中提取以下类型的 Memory：\n\n| Memory 类型 | 说明 | 置信度 |\n|-------------|------|--------|\n| `episode_summary` | 事件摘要 | 0.8 |\n| `profile_fact` | 用户画像事实 | 0.6 |\n| `decision` | 关键决策记录 | 0.7 |\n| `preference` | 用户偏好 | 0.6 |\n\n资料来源：[server/services/compilers/heuristic.py:40-70]()\n\n### Memory 的时间有效性\n\n每个 Memory 都有 `valid_from` 和 `valid_to` 字段定义其有效时间范围：\n\n```python\nvalid_to=compute_valid_to(\"episode_summary\", ep_valid_from, ttl)\n```\n\n资料来源：[server/services/compilers/heuristic.py:55]()\n\n时间有效性的设计支持：\n- **时间衰减**：过期的记忆自动降低相关性\n- **快照隔离**：历史时间点的记忆可以被完整保留\n- **状态追踪**：偏好和事实的变化可追溯\n\n### Memory 的来源追溯\n\nMemory 通过 `source_episode_ids` 字段维护与源 Episode 的关联关系：\n\n```python\nsource_episode_ids=[ep.id]\n```\n\n资料来源：[server/services/compilers/heuristic.py:45]()\n\n这种设计支持：\n- **反向查询**：从 Memory 找到原始 Episode\n- **归因分析**：了解记忆的来源\n- **一致性验证**：确保记忆与源事件一致\n\n```mermaid\ngraph LR\n    MEM[Memory] -->|source_episode_ids| EP1[Episode]\n    MEM -->|source_episode_ids| EP2[Episode]\n    \n    API[\"/subjects/{id}/episodes/{episode_id}/citing-memories\"]\n    EP1 -->|反向查找| API\n    API -->|返回| M1[引用该Episode的Memories]\n```\n\n资料来源：[server/api/admin.py:list_citing_memories]()\n\n### 编译的幂等性\n\nMemory 编译是**幂等操作**——重复编译不会产生重复记忆。系统通过内容哈希（`provenance.content_hash`）识别已存在的记忆。资料来源：[scripts/docs_loader.py:60-70]()\n\n---\n\n## Context 上下文组装\n\n### Context 的作用\n\nContext 是最终交付给 AI Agent 的**上下文包**，它从多个 Memory 和 Episode 中组装出满足以下约束的内容：\n\n- **Token 受限**：总长度不超过配置的 token 上限\n- **相关性排序**：最相关的内容优先包含\n- **时间范围**：覆盖指定的时间窗口\n- **多样性**：避免内容重复\n\n资料来源：[server/services/context.py]()\n\n### Context 组装流程\n\n```mermaid\ngraph TD\n    START[POST /v1/context] --> Q[解析查询参数]\n    Q --> TS[时间范围过滤]\n    TS --> TK[Token 预算分配]\n    TK --> SR[语义搜索 Memory]\n    SR --> SC[得分排序]\n    SC --> TR[时间线补充 Episode]\n    TR --> AS[组装最终上下文]\n    AS --> END[返回 Context Bundle]\n```\n\n### Context 响应结构\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n    \n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n资料来源：[server/services/context.py:80-90]()\n\n响应包含：\n- `episodes`：相关时间线事件\n- `memories`：相关记忆\n- `score_breakdown`：评分明细\n\n---\n\n## Subject 主体管理\n\n### Subject 的作用\n\nSubject 是 Episode 和 Memory 的**拥有者**，代表一个独立的实体（如用户、企业、仓库等）。所有数据流都发生在 Subject 的作用域内。\n\n### Subject 的数据删除\n\n删除 Subject 会级联删除其所有关联数据：\n\n| 删除内容 | 影响 |\n|----------|------|\n| Episodes | 永久删除 |\n| Memories | 永久删除 |\n| Resolutions | 永久删除 |\n| Snapshots | 永久删除 |\n\n资料来源：[README.md:DELETE /v1/subjects/{id}]()\n\n---\n\n## Snapshot 快照机制\n\n### Snapshot 的用途\n\nSnapshot 提供了 Subject 状态的**时间点快照**，用于：\n\n- 灾难恢复\n- 状态迁移\n- 版本回滚\n- 测试数据准备\n\n资料来源：[server/services/snapshots.py]()\n\n### Snapshot 的创建流程\n\n```mermaid\ngraph TD\n    CREATE[创建 Snapshot] --> Q[查询 Subject 数据]\n    Q --> SE[收集 Episodes]\n    Q --> SM[收集 Memories]\n    Q --> SR[收集 Resolutions]\n    SE --> CPY[复制数据到快照主体]\n    SM --> CPY\n    SR --> CPY\n    CPY --> META[记录快照元数据]\n    META --> DONE[返回 Snapshot ID]\n```\n\n### Snapshot 的时间偏移\n\n恢复快照时，系统支持时间偏移（time_shift）以适应不同的目标环境：\n\n```python\nvalid_from=(mem_valid_from + time_shift) if mem_valid_from else None,\nvalid_to=(mem_valid_to + time_shift) if mem_valid_to else None,\ncreated_at=mem_created + time_shift,\nupdated_at=mem_updated + time_shift,\n```\n\n资料来源：[server/services/snapshots.py:restore_snapshot]()\n\n---\n\n## 数据导入导出\n\n### 导入流程\n\n```mermaid\ngraph LR\n    JSON[\"JSONL 格式数据\"] --> VAL{验证}\n    VAL -->|通过| EPI[导入 Episodes]\n    VAL -->|通过| MEM[导入 Memories]\n    EPI --> REMAP[重映射 Episode ID]\n    MEM --> REMAP\n    REMAP --> COMMIT[提交事务]\n    COMMIT --> DONE[返回导入结果]\n```\n\n### ID 保留策略\n\n导入时可以选择是否保留原始 ID：\n\n| 策略 | 说明 |\n|------|------|\n| `preserve_ids=True` | 保留原始 UUID |\n| `preserve_ids=False` | 生成新 UUID |\n\n资料来源：[server/services/backup.py:subject_import]()\n\n---\n\n## 状态流转总览\n\n```mermaid\nstateDiagram-v2\n    [*] --> Episodes: 摄入\n    Episodes --> Compilation: 触发编译\n    Compilation --> Memories: 生成记忆\n    Memories --> Context: 组装上下文\n    Context --> [*]: 交付 Agent\n    \n    Episodes --> Snapshot: 创建快照\n    Snapshot --> [*]: 备份\n    \n    [*] --> Import: 导入数据\n    Import --> Episodes: 恢复 Episodes\n    Import --> Memories: 恢复 Memories\n```\n\n---\n\n## 核心配置参数\n\n| 参数 | 位置 | 说明 |\n|------|------|------|\n| `valid_from` | Memory | 有效起始时间 |\n| `valid_to` | Memory | 有效结束时间 |\n| `confidence` | Memory | 置信度 (0.0-1.0) |\n| `status` | Memory | 状态 (active/inactive) |\n| `time_shift` | Snapshot restore | 时间偏移量 |\n\n---\n\n## 总结\n\nStatewave 的数据流设计体现了以下核心原则：\n\n1. **不可变性优先**：Episode 作为原始事实永不修改\n2. **派生透明**：Memory 明确记录来源 Episode\n3. **时间感知**：所有实体都携带时间维度信息\n4. **幂等操作**：编译和导入操作可安全重复\n5. **原子性保证**：批量操作的事务完整性\n\n这种设计使得系统能够可靠地追踪信息来源、恢复历史状态，并在保持高性能的同时支持复杂的时间范围查询。\n\n---\n\n<a id='p-episodes'></a>\n\n## Episode 管理\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py) *(未在上下文中获取)*\n- [server/schemas/requests.py](https://github.com/smaramwbc/statewave/blob/main/server/schemas/requests.py) *(未在上下文中获取)*\n- [server/schemas/responses.py](https://github.com/smaramwbc/statewave/blob/main/server/schemas/responses.py) *(未在上下文中获取)*\n- [server/domain/models.py](https://github.com/smaramwbc/statewave/blob/main/server/domain/models.py) *(未在上下文中获取)*\n\n**补充参考文件（已在上下文中获取）：**\n\n- [scripts/docs_loader.py](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n- [scripts/bootstrap_docs_pack.py](https://github.com/smaramwbc/statewave/blob/main/scripts/bootstrap_docs_pack.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n</details>\n\n# Episode 管理\n\n## 概述\n\nEpisode（事件）是 Statewave 记忆系统的**原子数据单元**，代表与特定主题（Subject）相关的每一次交互或事件记录。Episode 采用**仅追加（append-only）**模式写入，不可直接修改，确保了事件溯源的完整性。\n\nStatewave 通过 Connectors 从多种数据源收集 Episodes，这些事件随后被编译（Compile）为结构化的 Memory（记忆），供 Agent 在推理时检索。\n\n**核心职责：**\n\n| 职责 | 说明 |\n|------|------|\n| 事件采集 | 接收并持久化来自各类 Connector 的事件数据 |\n| 溯源追踪 | 记录每个 Episode 的来源、类型和元数据 |\n| 时间锚定 | 支持显式事件时间和隐式时间戳 |\n| 关系映射 | 为后续 Memory 编译建立来源关联 |\n\n资料来源：[README.md:1-50](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## Episode 数据模型\n\n### 基本结构\n\n```python\n@dataclass(frozen=True)\nclass DocSection:\n    \"\"\"One ingestible unit. Maps 1:1 to an episode.\"\"\"\n    doc_path: str\n    title: str\n    heading_path: tuple[str, ...]\n    body: str\n    content_hash: str\n    url: str\n```\n\n### Episode 载荷格式\n\n```json\n{\n  \"title\": \"事件标题\",\n  \"heading_path\": [\"父标题\", \"子标题\"],\n  \"breadcrumb\": \"父标题 › 子标题 › 事件标题\",\n  \"doc_path\": \"architecture/overview.md\",\n  \"url\": \"https://statewave.ai/docs/...\",\n  \"text\": \"事件完整文本内容\",\n  \"messages\": [\n    {\n      \"role\": \"user|assistant|system\",\n      \"content\": \"消息内容\",\n      \"timestamp\": \"2024-01-15T10:30:00Z\"\n    }\n  ],\n  \"event_time\": \"2024-01-15T09:00:00Z\"\n}\n```\n\n### Provenance（溯源信息）\n\n每个 Episode 携带不可变的溯源元数据，用于去重和数据一致性校验：\n\n```python\n{\n    \"doc_path\": \"architecture/overview.md\",\n    \"content_hash\": \"sha256:abc123...\",  # 内容确定性哈希\n    \"pack_version\": 1\n}\n```\n\n资料来源：[scripts/docs_loader.py:30-60](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n\n---\n\n## API 端点\n\n### Episode 写入\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `POST` | `/v1/episodes` | 写入单个 Episode（仅追加） |\n| `POST` | `/v1/episodes/batch` | 批量写入最多 100 个 Episodes |\n\n### Episode 查询\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/v1/subjects/{id}/episodes` | 获取主题的所有 Episodes |\n| `GET` | `/v1/subjects/{id}/episodes/{episode_id}` | 获取单个 Episode 详情 |\n| `GET` | `/v1/subjects/{id}/episodes/{episode_id}/citing-memories` | 反向查询：引用此 Episode 的所有 Memories |\n\n### Episode 删除\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `DELETE` | `/v1/subjects/{id}` | 删除主题及其所有关联 Episodes |\n\n资料来源：[README.md:50-80](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## Episode 类型与来源\n\nStatewave 支持多种 Episode 来源（Connector），每种来源定义了不同的 Memory 形状：\n\n| 来源 | 类型 | 说明 | 状态 |\n|------|------|------|------|\n| MCP server | `agent_memory` | Copilot / Claude / Cursor / agent 记忆 | ✅ 已发布 |\n| GitHub | `repo_memory` | Issues, PRs, reviews, releases | ✅ 已发布 |\n| Markdown | `doc_section` | 本地文档、ADR、RFC | ✅ 已发布 |\n| Slack | `channel_event` | 频道消息事件 | ✅ 已发布 |\n\n资料来源：[README.md:80-95](https://github.com/smaramwbc/statewave/blob/main/README.md)\n\n---\n\n## 时间锚定机制\n\nEpisode 编译为 Memory 时需要确定有效时间范围（valid_from / valid_to）。系统按以下优先级确定时间锚点：\n\n```mermaid\ngraph TD\n    A[Episode 时间锚定] --> B{存在 payload.event_time?}\n    B -->|是| C[使用 event_time]\n    B -->|否| D{存在 messages[0].timestamp?}\n    D -->|是| E[使用首条消息时间戳]\n    D -->|否| F[使用 Episode 创建时间]\n    \n    C --> G[计算 valid_to]\n    E --> G\n    F --> G\n    \n    G --> H[基于 kind 确定 TTL]\n    H --> I[Memory 有效时间范围]\n```\n\n**TTL 计算规则：**\n\n| Memory Kind | 默认 TTL |\n|-------------|----------|\n| `episode_summary` | 较长（持久化知识） |\n| `profile_fact` | 中等（用户偏好） |\n| 其他 | 根据配置 |\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"Return the best-effort temporal anchor for memories derived from\n    this episode.\n\n    Priority:\n      1. `payload.event_time` — explicit override set by the client\n      2. `payload.messages[0].timestamp` — first-message timestamp\n      3. Episode creation timestamp (fallback)\n    \"\"\"\n```\n\n资料来源：[server/services/compilers/heuristic.py:80-100](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n---\n\n## Episode 编译流程\n\nEpisode 本身是不可变的原始数据。通过编译过程，系统从中提取结构化记忆：\n\n```mermaid\ngraph LR\n    A[Episode] --> B[Heuristic Compiler]\n    B --> C[Episode Summary]\n    B --> D[Profile Facts]\n    B --> E[Custom Extractions]\n    \n    C --> F[Memory Row]\n    D --> F\n    E --> F\n    \n    F --> G[source_episode_ids = [ep.id]]\n```\n\n**编译结果写入 MemoryRow：**\n\n```python\nMemoryRow(\n    id=uuid.uuid4(),\n    subject_id=ep.subject_id,\n    kind=\"episode_summary\",      # 记忆类型\n    content=text[:500],          # 完整内容（截断）\n    summary=text[:200],          # 摘要\n    confidence=0.8,              # 置信度\n    valid_from=ep_valid_from,\n    valid_to=compute_valid_to(...),\n    source_episode_ids=[ep.id], # 溯源关联\n    metadata_={},\n    status=\"active\",\n)\n```\n\n资料来源：[server/services/compilers/heuristic.py:50-75](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n\n---\n\n## Snapshot 与 Episode 迁移\n\nSnapshot 功能允许完整导出/恢复 Subject 的 Episodes 和 Memories：\n\n```mermaid\ngraph TD\n    A[Snapshot 创建] --> B[克隆 Episodes]\n    B --> C[克隆 Memories]\n    C --> D[克隆 Resolutions]\n    D --> E[保存 Snapshot 元数据]\n    \n    F[Snapshot 恢复] --> G[时间偏移调整]\n    G --> H[重建 Episode 关系]\n    H --> I[更新 source_episode_ids 映射]\n```\n\n**Snapshot 中的 Episode 克隆：**\n\n```python\n# Episode 克隆时保留原始 session_id 和时间戳\nEpisodeRow(\n    id=uuid.uuid4(),\n    subject_id=snapshot_subject,\n    session_id=ep.session_id,\n    source=ep.source,\n    type=ep.type,\n    payload=ep.payload,\n    metadata_=ep.metadata_,\n    provenance=ep.provenance,\n    occurred_at=ep.occurred_at + time_shift,  # 时间偏移\n    created_at=ep_created + time_shift,\n)\n```\n\n**Snapshot 恢复标记：**\n\n```python\nmetadata_={\n    \"restored_from_snapshot\": str(snapshot_id),\n    # ...\n}\n```\n\n资料来源：[server/services/snapshots.py:100-150](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n\n---\n\n## 管理 API\n\n### 引用关系查询\n\n```python\n@router.get(\n    \"/subjects/{subject_id}/episodes/{episode_id}/citing-memories\",\n    response_model=MemoryListResponse,\n)\nasync def list_citing_memories(\n    subject_id: str,\n    episode_id: str,\n    tenant_id: str | None = Query(None),\n    limit: int = Query(50, ge=1, le=200),\n    offset: int = Query(0, ge=0),\n):\n    \"\"\"List memories that cite (were derived from) a specific episode.\n    \n    This enables reverse provenance lookup: from an episode, find all\n    memories that list it in their source_episode_ids.\n    \"\"\"\n```\n\n**查询逻辑：**\n\n```python\n# 验证 episode_id 格式\nepisode_uuid = uuid_module.UUID(episode_id)\n\n# 查询 source_episode_ids 数组包含该 episode_id 的所有 memories\nbase = select(MemoryRow).where(\n    func.array_contains(MemoryRow.source_episode_ids, episode_id)\n)\n```\n\n资料来源：[server/api/admin.py:1-50](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n\n---\n\n## Bootstrap 与批量导入\n\nStatewave 提供脚本工具将外部文档批量转换为 Episodes：\n\n### docs_loader.py\n\n将 Markdown 文档按标题层级（H1/H2/H3）拆分为独立的 DocSection，每个 Section 对应一个 Episode：\n\n```python\nMANIFEST: tuple[str, ...] = (\n    \"README.md\",\n    \"getting-started.md\",\n    \"product.md\",\n    \"architecture/overview.md\",\n    \"architecture/repo-map.md\",\n    # ... 更多文档\n)\n```\n\n**特性：**\n\n- 使用 SHA256 内容哈希实现幂等性\n- 每个 Section 生成确定性 slug 用于 URL 生成\n- 支持 re-run 检测未变更内容\n\n### bootstrap_docs_pack.py\n\n```bash\n# 基本用法\npython -m scripts.bootstrap_docs_pack\n\n# 指定文档路径\npython -m scripts.bootstrap_docs_pack --docs-path /path/to/docs\n\n# 清空重建\npython -m scripts.bootstrap_docs_pack --purge\n\n# 仅解析不写入\npython -m scripts.bootstrap_docs_pack --dry-run\n```\n\n**环境变量：**\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_URL` | `http://localhost:8100` | API 地址 |\n| `STATEWAVE_API_KEY` | — | 可选认证密钥 |\n| `STATEWAVE_DOCS_PATH` | sibling `statewave-docs` | 文档目录 |\n\n资料来源：[scripts/bootstrap_docs_pack.py:1-80](https://github.com/smaramwbc/statewave/blob/main/scripts/bootstrap_docs_pack.py)\n\n---\n\n## Episode 响应模型\n\n```python\nclass EpisodeResponse(BaseModel):\n    id: str\n    subject_id: str\n    source: str           # 来源：slack, github, mcp, docs 等\n    type: str             # 类型：doc_section, message, event 等\n    payload: dict         # 原始载荷\n    metadata: dict        # 额外元数据\n    provenance: dict      # 溯源信息\n    occurred_at: datetime # 事件发生时间\n    created_at: datetime  # 记录创建时间\n    session_id: str | None # 会话标识（可选）\n```\n\n资料来源：[server/api/timeline.py:20-35](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n\n---\n\n## 最佳实践\n\n### 1. 事件时间 vs 创建时间\n\n对于回放历史数据（如 Connectors 重放旧事件），应显式设置 `payload.event_time` 为实际事件发生时间：\n\n```json\n{\n  \"event_time\": \"2023-12-01T08:00:00Z\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"历史消息内容\",\n      \"timestamp\": \"2023-12-01T08:00:00Z\"\n    }\n  ]\n}\n```\n\n### 2. 批量写入优化\n\n单次批量写入限制为 100 个 Episodes，较大导入应分批处理：\n\n```python\nBATCH_SIZE = 50  # 推荐批次大小\n\nfor i in range(0, len(episodes), BATCH_SIZE):\n    batch = episodes[i:i + BATCH_SIZE]\n    await client.post(\"/v1/episodes/batch\", json=batch)\n```\n\n### 3. 内容哈希用于去重\n\n创建 Episodes 时包含确定性内容哈希，支持增量刷新：\n\n```python\ncontent_hash = hashlib.sha256(text.encode(\"utf-8\")).hexdigest()\n\nprovenance = {\n    \"content_hash\": content_hash,\n    \"pack_version\": PACK_VERSION\n}\n```\n\n资料来源：[scripts/docs_loader.py:70-90](https://github.com/smaramwbc/statewave/blob/main/scripts/docs_loader.py)\n\n---\n\n## 相关文档\n\n- [Memory 管理](./memory-management.md)\n- [Context 组装](./context-assembly.md)\n- [Connector 架构](./connector-architecture.md)\n- [Snapshot 功能](./snapshot-feature.md)\n\n---\n\n<a id='p-compiler'></a>\n\n## 编译器系统\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [上下文检索与排名](#p-context-retrieval)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/services/compiler.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compiler.py)\n- [server/services/compilers/heuristic.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/heuristic.py)\n- [server/services/compilers/llm.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compilers/llm.py)\n- [server/services/compile_jobs.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compile_jobs.py)\n- [server/services/compile_jobs_durable.py](https://github.com/smaramwbc/statewave/blob/main/server/services/compile_jobs_durable.py)\n- [server/services/conflicts.py](https://github.com/smaramwbc/statewave/blob/main/server/services/conflicts.py)\n</details>\n\n# 编译器系统\n\n## 概述\n\n编译器系统（Compiler System）是 Statewave 的核心子系统，负责将原始的对话事件（Episodes）转化为结构化的记忆（Memories）。当新的对话片段被摄入系统后，编译器会分析这些事件，提取有价值的信息，生成可供后续检索和推理使用的记忆条目。\n\n编译过程是**幂等操作**（idempotent），这意味着对同一批事件重复编译不会产生副作用或重复数据。系统会追踪每个记忆的来源事件（`source_episode_ids`），确保记忆与原始事件之间的可追溯性。\n\n| 特性 | 说明 |\n|------|------|\n| 触发方式 | API 调用 `POST /v1/memories/compile` 或自动触发 |\n| 编译模式 | 启发式（heuristic）和 LLM 驱动两种模式 |\n| 输出产物 | MemoryRow 记录，包含多种记忆类型 |\n| 幂等性 | 重复编译安全，不会产生重复记忆 |\n\n资料来源：[README.md:1-30]()\n\n## 架构设计\n\n### 编译器类型\n\nStatewave 支持两种编译策略，可根据部署环境和技术要求选择合适的模式：\n\n| 编译模式 | 配置值 | 适用场景 | 依赖 |\n|----------|--------|----------|------|\n| 启发式编译 | `heuristic` | 演示环境、无 LLM 需求、本地开发 | 无外部依赖 |\n| LLM 编译 | `llm` | 生产环境、需要深度语义理解 | LLM API Key |\n\n```yaml\n# Helm 部署配置示例\ncompiler:\n  type: llm  # 或 heuristic\n```\n\n资料来源：[helm/statewave/README.md:1-20]()\n\n### 核心组件\n\n```\ngraph TD\n    A[Episode 摄入] --> B{编译模式选择}\n    B -->|heuristic| C[HeuristicCompiler]\n    B -->|llm| D[LLMCompiler]\n    C --> E[提取概要信息]\n    C --> F[提取 Profile Facts]\n    D --> G[语义分析与总结]\n    D --> H[关系抽取]\n    E --> I[MemoryRow 生成]\n    F --> I\n    G --> I\n    H --> I\n    I --> J[冲突检测]\n    J --> K[记忆合并/去重]\n    K --> L[持久化存储]\n```\n\n**主要组件职责：**\n\n| 组件 | 文件位置 | 职责 |\n|------|----------|------|\n| `Compiler` | `server/services/compiler.py` | 编译调度、模式路由 |\n| `HeuristicCompiler` | `server/services/compilers/heuristic.py` | 规则驱动的记忆提取 |\n| `LLMCompiler` | `server/services/compilers/llm.py` | 大语言模型驱动的语义理解 |\n| `CompileJob` | `server/services/compile_jobs.py` | 编译任务管理与队列 |\n| `CompileJobDurable` | `server/services/compile_jobs_durable.py` | 持久化编译任务支持 |\n| `ConflictResolver` | `server/services/conflicts.py` | 记忆冲突检测与消解 |\n\n## 编译流程\n\n### 完整工作流\n\n```\ngraph LR\n    A[收集未编译 Episodes] --> B{遍历 Episodes}\n    B --> C[确定时间锚点]\n    C --> D{编译模式}\n    D -->|heuristic| E[提取概要 + Facts]\n    D -->|llm| F[LLM 分析总结]\n    E --> G[生成 MemoryRows]\n    F --> G\n    G --> H[冲突检测]\n    H --> I{存在冲突?}\n    I -->|是| J[冲突消解]\n    I -->|否| K[直接写入]\n    J --> K\n    K --> L[更新编译状态]\n    L --> M{还有更多 Episodes?}\n    M -->|是| B\n    M -->|否| N[编译完成]\n```\n\n### 触发方式\n\n编译可以通过以下方式触发：\n\n1. **手动触发**：调用 `POST /v1/memories/compile` API\n2. **自动触发**：在摄入新 Episode 后自动启动编译\n3. **批量触发**：通过 `POST /v1/episodes/batch` 摄入多集后统一编译\n\n资料来源：[README.md:30-45]()\n\n## 启发式编译器\n\n### 概述\n\n启发式编译器（HeuristicCompiler）是一种基于规则的信息提取引擎，无需外部 LLM 依赖即可运行。它通过正则表达式和启发式算法从文本中提取结构化信息。\n\n### 记忆类型\n\n启发式编译器生成以下类型的记忆：\n\n| 记忆类型 | 置信度 | 描述 | TTL 配置 |\n|----------|--------|------|----------|\n| `episode_summary` | 0.8 | 对话片段的概要摘要 | 基于 `episode_summary` TTL |\n| `profile_fact` | 0.6 | 从对话中提取的用户 profile 事实 | 基于 `profile_fact` TTL |\n\n资料来源：[server/services/compilers/heuristic.py:1-80]()\n\n### 时间锚点计算\n\n编译器使用以下优先级确定记忆的时间锚点（`valid_from`）：\n\n```python\ndef episode_valid_from(ep: EpisodeRow) -> datetime:\n    \"\"\"返回派生记忆的最佳努力时间锚点\"\"\"\n    # 优先级 1: payload.event_time — 客户端显式设置\n    # 优先级 2: payload.messages[0].timestamp — 首条消息时间戳\n    # 优先级 3: ep.created_at — 系统记录时间\n```\n\n**时间锚点优先级：**\n\n| 优先级 | 来源字段 | 说明 |\n|--------|----------|------|\n| 1 | `payload.event_time` | 显式覆盖时间，适用于历史数据回放 |\n| 2 | `payload.messages[0].timestamp` | 聊天类载荷的首条消息时间戳 |\n| 3 | `ep.created_at` | 系统自动记录的时间 |\n\n资料来源：[server/services/compilers/heuristic.py:80-100]()\n\n### Profile Facts 提取\n\nProfile Facts 提取器从对话文本中识别用户相关的结构化信息，包括：\n\n- 用户姓名、职位、公司等基本信息\n- 用户偏好和习惯\n- 技术栈和技能水平\n- 过往交互历史摘要\n\n提取后的 facts 会被封装为独立的 MemoryRow，置信度为 0.6，source_episode_ids 指向原始 Episode。\n\n### TTL 计算\n\n每种记忆类型都有预设的存活时间（TTL），通过 `compute_valid_to()` 函数计算：\n\n```python\ndef compute_valid_to(kind: str, valid_from: datetime, ttl: dict) -> datetime | None:\n    \"\"\"根据记忆类型计算过期时间\"\"\"\n    # 返回 valid_from + 对应类型的 TTL\n```\n\n## LLM 编译器\n\n### 概述\n\nLLM 编译器使用大语言模型进行深度语义分析，能够：\n\n- 理解对话意图和情感\n- 提取隐含的关系和依赖\n- 生成更准确的摘要和总结\n- 识别实体和事件之间的关联\n\n### 配置要求\n\n```yaml\nllm:\n  apiKey: sk-...  # 必须配置\n  # 可选配置项\n  model: gpt-4    # 指定模型\n  temperature: 0.3\n```\n\n### 提示词策略\n\nLLM 编译器使用精心设计的提示词模板，引导模型生成符合 Statewave 数据模型的记忆结构。提示词设计考虑：\n\n- 记忆类型的严格分类\n- 置信度评分的指导\n- 时间范围的有效期设定\n- 避免幻觉和重复提取\n\n## 记忆数据结构\n\n### MemoryRow 字段说明\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 记忆唯一标识符 |\n| `subject_id` | UUID | 所属主体 ID |\n| `kind` | string | 记忆类型（如 episode_summary、profile_fact） |\n| `content` | text | 记忆内容正文 |\n| `summary` | string | 内容摘要（前 200 字符） |\n| `confidence` | float | 置信度 0.0-1.0 |\n| `valid_from` | datetime | 记忆起始时间 |\n| `valid_to` | datetime | 记忆过期时间（None 表示永不过期） |\n| `source_episode_ids` | list[UUID] | 源 Episodes ID 列表 |\n| `metadata_` | dict | 扩展元数据 |\n| `status` | string | 状态（active、superseded 等） |\n| `embedding` | vector | 向量嵌入（用于语义搜索） |\n| `sensitivity_labels` | list[string] | 敏感标签 |\n| `created_at` | datetime | 创建时间 |\n| `updated_at` | datetime | 更新时间 |\n\n### 记忆状态流转\n\n```mermaid\nstateDiagram-v2\n    [*] --> active: 新建记忆\n    active --> superseded: 被新记忆替代\n    active --> redacted: 策略过滤\n    active --> inactive: 过期\n    superseded --> [*]\n    redacted --> [*]\n    inactive --> [*]\n```\n\n## 冲突检测与消解\n\n### 冲突类型\n\n| 冲突类型 | 描述 | 检测方式 |\n|----------|------|----------|\n| 内容重复 | 新记忆与现有记忆内容高度相似 | 文本相似度 > 0.7 |\n| 时间冲突 | 新旧记忆的时间范围重叠 | valid_from/valid_to 区间重叠 |\n| 事实矛盾 | 同一事实的描述相互矛盾 | 实体提取比对 |\n| 覆盖冲突 | 新记忆应替代而非追加 | 置信度对比 |\n\n### 消解策略\n\n| 策略 | 触发条件 | 处理方式 |\n|------|----------|----------|\n| 合并 | 内容高度相似 | 合并 source_episode_ids |\n| 替代 | 新记忆置信度更高 | 将旧记忆标记为 superseded |\n| 保留 | 两者互补 | 同时保留 |\n| 丢弃 | 新记忆信息量不足 | 忽略新记忆 |\n\n资料来源：[server/services/conflicts.py:1-50]()\n\n## 编译任务管理\n\n### 同步编译\n\n适用于小批量 Episodes 的实时编译：\n\n```python\nresult = await compile_job.execute(episode_ids)\n```\n\n### 持久化任务\n\n对于大批量编译需求，系统提供持久化任务支持：\n\n```python\njob = await compile_job_durable.create(\n    episode_ids=episode_ids,\n    mode=\"llm\",\n    priority=\"normal\"\n)\n```\n\n| 任务状态 | 说明 |\n|----------|------|\n| `pending` | 等待执行 |\n| `running` | 执行中 |\n| `completed` | 成功完成 |\n| `failed` | 执行失败 |\n| `cancelled` | 已取消 |\n\n### 重试机制\n\n编译任务失败后自动重试，默认策略：\n\n- 最大重试次数：3\n- 重试间隔：指数退避（1s, 4s, 16s）\n- 永久失败：记录错误日志，标记任务状态\n\n## 配置参考\n\n### 环境变量配置\n\n| 变量名 | 默认值 | 说明 |\n|--------|--------|------|\n| `STATEWAVE_COMPILER_TYPE` | `llm` | 编译模式：llm 或 heuristic |\n| `STATEWAVE_COMPILER_LLM_MODEL` | - | LLM 模型名称 |\n| `STATEWAVE_COMPILER_MAX_RETRIES` | `3` | 最大重试次数 |\n\n### Helm Chart 配置\n\n```yaml\ncompiler:\n  type: llm  # 或 heuristic\n  timeout: 300  # 编译超时时间（秒）\n  batchSize: 50  # 每批处理 Episodes 数\n```\n\n## 最佳实践\n\n### 编译模式选择指南\n\n```mermaid\nflowchart TD\n    A[选择编译模式] --> B{有 LLM 需求?}\n    B -->|是| C[生产环境]\n    B -->|否| D{需要深度语义理解?}\n    D -->|是| C\n    D -->|否| E[开发/演示环境]\n    C --> F[LLM 编译器]\n    E --> G[Heuristic 编译器]\n```\n\n### 性能优化建议\n\n1. **批量摄入**：使用 `POST /v1/episodes/batch` 批量摄入，减少编译次数\n2. **合理选择模式**：非必要场景使用 Heuristic 模式降低延迟\n3. **配置 TTL**：根据业务需求调整各记忆类型的 TTL，减少存储压力\n4. **监控编译状态**：通过 API 监控编译任务的执行情况\n\n### 调试编译问题\n\n```bash\n# 检查编译状态\ncurl http://localhost:8100/v1/memories/search?subject_id=xxx\n\n# 查看编译任务详情\ncurl http://localhost:8100/admin/jobs?status=failed\n```\n\n## 相关文档\n\n- [架构概述](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/overview.md)\n- [编译器模式对比](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/compiler-modes.md)\n- [隐私与数据流](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/privacy-and-data-flow.md)\n- [API v1 契约](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n\n---\n\n<a id='p-context-retrieval'></a>\n\n## 上下文检索与排名\n\n### 相关页面\n\n相关主题：[数据流与生命周期](#p-data-flow), [编译器系统](#p-compiler), [Episode 管理](#p-episodes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/services/health.py](https://github.com/smaramwbc/statewave/blob/main/server/services/health.py)\n- [server/services/sla.py](https://github.com/smaramwbc/statewave/blob/main/server/services/sla.py)\n- [server/services/embeddings/litellm.py](https://github.com/smaramwbc/statewave/blob/main/server/services/embeddings/litellm.py)\n- [server/services/embeddings/query_cache.py](https://github.com/smaramwbc/statewave/blob/main/server/services/embeddings/query_cache.py)\n</details>\n\n# 上下文检索与排名\n\n## 概述\n\n上下文检索与排名（Context Retrieval and Ranking）是 Statewave 的核心子系统，负责从海量的记忆（Memory）和事件（Episode）数据中筛选出最相关的内容，并将其组装成符合令牌预算限制的上下文包，供下游 AI 代理使用。\n\n该系统的设计目标包括：\n\n- **相关性优先**：基于语义相似度、类型匹配、时间衰减等多维度评分机制\n- **令牌约束**：自动裁剪结果以满足 `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` 配置的令牌预算\n- **幂等性**：同一查询在相同数据状态下产生一致的上下文输出\n- **多租户隔离**：通过 `X-Tenant-ID` header 确保跨租户数据的严格隔离\n\n资料来源：[server/services/context.py:1-50]()\n\n## 核心概念\n\n### 上下文项（Context Item）\n\n在 Statewave 中，所有可被纳入上下文的实体都被抽象为 **Context Item**。系统支持两类主要实体：\n\n| 实体类型 | 数据模型 | 说明 |\n|---------|---------|------|\n| Memory | `MemoryRow` | 编译后的记忆条目，包含摘要、置信度、时间范围等信息 |\n| Episode | `EpisodeRow` | 原始事件记录，包含完整载荷和来源元数据 |\n\n每项实体都关联一个 **评分（Score）**，用于排名决策。\n\n### 评分项（ScoredItem）\n\n`ScoredItem` 是上下文组装过程中的内部数据结构，用于封装已评分的条目：\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `score` | `float` | 计算得出的相关性分数 |\n| `kind` | `str` | 条目类型（memory 或 episode） |\n| `memory_row` | `Any` | 关联的 MemoryRow（若 kind 为 memory） |\n| `episode_row` | `Any` | 关联的 EpisodeRow（若 kind 为 episode） |\n| `text` | `str` | 用于语义检索的文本内容 |\n| `section` | `str` | 条目所属的语义分区 |\n\n资料来源：[server/services/context.py:50-68]()\n\n## 系统架构\n\n```mermaid\ngraph TD\n    subgraph \"上下文检索与排名系统\"\n        A[POST /v1/context] --> B[Query Parser]\n        B --> C[语义检索模块]\n        C --> D[混合评分引擎]\n        D --> E[Token Budget Controller]\n        E --> F[上下文组装器]\n        F --> G[返回 Context Bundle]\n    end\n\n    subgraph \"数据存储层\"\n        H[(Memory Table)]\n        I[(Episode Table)]\n        J[(Embedding Cache)]\n    end\n\n    C --> H\n    C --> I\n    C --> J\n```\n\n## 检索流程\n\n### 1. 查询解析与参数验证\n\n客户端通过 `POST /v1/context` 端点提交上下文请求，请求参数包括：\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `subject_id` | `string` | 是 | - | 目标主题 ID |\n| `query` | `string` | 是 | - | 检索查询文本 |\n| `k` | `integer` | 否 | `10` | 返回的 top-k 结果数 |\n| `max_tokens` | `integer` | 否 | `4000` | 上下文令牌预算上限 |\n\n系统首先验证租户隔离（`STATEWAVE_TENANT_HEADER`），确保查询仅访问授权数据。\n\n### 2. 语义检索\n\n系统通过嵌入服务（Embedding Service）将查询文本转换为向量表示：\n\n```python\n# 嵌入服务配置\nembedding_provider = \"litellm\"  # 或 \"stub\" 用于演示模式\n```\n\n嵌入向量随后用于在向量数据库中执行相似度搜索。Statewave 支持两种嵌入模式：\n\n| 模式 | 配置值 | 说明 |\n|------|--------|------|\n| LiteLLM | `litellm` | 调用外部 LLM API 生成嵌入向量 |\n| Stub | `stub` | 返回占位符向量，用于无 API Key 的演示场景 |\n\n资料来源：[server/services/embeddings/litellm.py:1-30]()\n\n### 3. 查询缓存\n\n为降低嵌入 API 调用成本，系统实现了查询缓存机制：\n\n```python\n# 缓存键生成逻辑\ncache_key = hashlib.sha256(\n    f\"{query_text}:{k}:{include_episodes}\".encode()\n).hexdigest()\n```\n\n缓存有效期由 `STATEWAVE_EMBEDDING_CACHE_TTL` 配置控制。\n\n资料来源：[server/services/embeddings/query_cache.py:1-40]()\n\n## 评分与排名机制\n\n### 混合评分算法\n\n系统在多个维度上计算相关性分数：\n\n| 评分维度 | 权重 | 数据来源 |\n|---------|------|---------|\n| 语义相似度 | 0.4 | 嵌入向量余弦相似度 |\n| 类型匹配度 | 0.2 | 查询类型与条目类型的匹配程度 |\n| 时间衰减 | 0.2 | 基于 `valid_from` 的指数衰减 |\n| 置信度 | 0.2 | 条目自身的 `confidence` 字段 |\n\n最终分数计算公式：\n\n```\nfinal_score = 0.4 × semantic_score + 0.2 × type_match + 0.2 × time_decay + 0.2 × confidence\n```\n\n### 排名策略\n\n1. **Primary Sort**：按 `final_score` 降序排列\n2. **Secondary Sort**：相同分数时，按 `created_at` 降序排列（优先新条目）\n3. **Diversity Boost**：对类型多样的结果给予小幅加分，避免结果过度集中\n\n### Memory 类型权重\n\n不同类型的记忆在检索时享有不同的基础权重：\n\n| 记忆类型 | 基础权重 | 说明 |\n|---------|---------|------|\n| `episode_summary` | 0.9 | 事件摘要，高信息密度 |\n| `profile_fact` | 0.8 | 用户画像事实 |\n| `decision` | 0.85 | 决策记录 |\n| `default` | 0.7 | 默认类型 |\n\n资料来源：[server/services/context.py:70-120]()\n\n## Token 预算控制\n\n### 预算分配策略\n\n系统采用 **分层预算分配** 策略：\n\n```mermaid\ngraph LR\n    A[总预算<br/>max_tokens] --> B[Memory 层<br/>60%]\n    A --> C[Episode 层<br/>30%]\n    A --> D[元数据层<br/>10%]\n```\n\n### 裁剪算法\n\n当候选条目总 token 数超过预算时，系统按以下顺序裁剪：\n\n1. 移除分数最低的 Episode 条目\n2. 合并低置信度的 Memory 摘要\n3. 截断单个 Memory 的 content 字段至 `max_tokens_per_item` 限制\n4. 若仍超预算，返回部分结果并设置 `truncated: true` 标志\n\n### 配置参数\n\n| 环境变量 | 默认值 | 说明 |\n|---------|--------|------|\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认上下文令牌预算 |\n| `STATEWAVE_MAX_TOKENS_PER_ITEM` | `1000` | 单条目最大 token 数 |\n\n## API 端点\n\n### POST /v1/context\n\n**功能**：组装并返回上下文包\n\n**请求示例**：\n\n```bash\ncurl -X POST http://localhost:8100/v1/context \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-Tenant-ID: tenant-123\" \\\n  -d '{\n    \"subject_id\": \"user-001\",\n    \"query\": \"最近的产品需求讨论\",\n    \"k\": 10,\n    \"max_tokens\": 4000\n  }'\n```\n\n**响应结构**：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | `string` | 主题 ID |\n| `items` | `array` | 上下文字条目数组 |\n| `total_tokens` | `integer` | 实际使用的 token 数 |\n| `truncated` | `boolean` | 是否因预算限制被截断 |\n| `citations` | `array` | 引用的原始条目 ID |\n\n### GET /v1/timeline\n\n**功能**：获取主题的时间线视图\n\n**查询参数**：\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | `string` | 主题 ID |\n| `since` | `datetime` | 起始时间（ISO 8601） |\n| `until` | `datetime` | 结束时间（ISO 8601） |\n\n资料来源：[server/api/context.py:1-80]()\n\n## 与 SLA/健康检查的集成\n\n### 健康评分上下文\n\n上下文检索系统与健康服务（Health Service）共享数据访问层：\n\n```python\n# 健康评分的上下文因子\nhealth_factors = {\n    \"recent_memories\": memory_count_last_7d,\n    \"resolution_rate\": resolutions.resolved / resolutions.total,\n    \"avg_response_time\": sla_metrics.avg_response_time,\n    \"sla_breaches\": sla_metrics.breach_count\n}\n```\n\n系统通过 `/v1/subjects/{id}/health` 端点暴露综合健康评分，该评分依赖上下文检索获取近期记忆和 SLA 指标。\n\n资料来源：[server/services/health.py:1-60]()\n\n### SLA 指标上下文\n\nSLA 服务在计算响应时间和解决时间时，会向上下文检索模块请求相关 Episode 数据：\n\n```python\n# SLA 计算的数据依赖链\ntimeline_episodes → context_retrieval → \nsla_metrics → health_score\n```\n\n| SLA 指标 | 计算方式 | 上下文依赖 |\n|---------|---------|-----------|\n| `first_response_time` | 首条回复距首条消息的时间差 | `/v1/timeline` 数据 |\n| `resolution_time` | 问题解决距首条消息的时间差 | Resolution Episode |\n| `breach_count` | SLA 违规次数 | 时间窗口内的所有 Episode |\n\n资料来源：[server/services/sla.py:1-80]()\n\n## 性能优化\n\n### 向量检索优化\n\n1. **批处理嵌入**：将多个短查询合并为单次 API 调用\n2. **HNSW 索引**：使用 pgvector 的 HNSW 索引加速近似最近邻搜索\n3. **结果缓存**：语义相似的结果在短时间窗口内被缓存\n\n### 缓存策略\n\n| 缓存类型 | TTL | 键生成策略 |\n|---------|-----|-----------|\n| 嵌入结果 | `STATEWAVE_EMBEDDING_CACHE_TTL` | SHA256(query + k) |\n| 上下文包 | 60 秒 | query hash + subject_id |\n| 排名结果 | 300 秒 | 相同 |\n\n## 错误处理\n\n| 错误码 | 场景 | 处理策略 |\n|-------|------|---------|\n| `400` | 无效查询参数 | 返回参数校验错误详情 |\n| `401` | 缺少/无效 API Key | 要求认证 |\n| `403` | 租户 ID 不匹配 | 拒绝访问 |\n| `404` | 主题不存在 | 返回空上下文包 |\n| `429` | 速率限制 | 按 `X-RateLimit-Reset` 重试 |\n| `500` | 嵌入服务不可用 | 降级至关键词检索 |\n\n## 配置参考\n\n完整的上下文检索相关配置项：\n\n```bash\n# 令牌预算\nSTATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS=4000\n\n# 嵌入服务\nSTATEWAVE_EMBEDDING_PROVIDER=litellm\nSTATEWAVE_EMBEDDING_MODEL=text-embedding-3-small\nSTATEWAVE_EMBEDDING_CACHE_TTL=3600\n\n# 多租户\nSTATEWAVE_TENANT_HEADER=X-Tenant-ID\nSTATEWAVE_REQUIRE_TENANT=false\n```\n\n## 扩展阅读\n\n- [API v1 契约规范](https://github.com/smaramwbc/statewave-docs/blob/main/api/v1-contract.md)\n- [排名算法详解](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/ranking.md)\n- [隐私与数据流](https://github.com/smaramwbc/statewave-docs/blob/main/architecture/privacy-and-data-flow.md)\n\n---\n\n<a id='p-api-routes'></a>\n\n## API 路由参考\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [服务层实现](#p-services)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/api/episodes.py](https://github.com/smaramwbc/statewave/blob/main/server/api/episodes.py)\n- [server/api/memories.py](https://github.com/smaramwbc/statewave/blob/main/server/api/memories.py)\n- [server/api/context.py](https://github.com/smaramwbc/statewave/blob/main/server/api/context.py)\n- [server/api/subjects.py](https://github.com/smaramwbc/statewave/blob/main/server/api/subjects.py)\n- [server/api/resolutions.py](https://github.com/smaramwbc/statewave/blob/main/server/api/resolutions.py)\n- [server/api/handoff.py](https://github.com/smaramwbc/statewave/blob/main/server/api/handoff.py)\n- [server/api/health.py](https://github.com/smaramwbc/statewave/blob/main/server/api/health.py)\n- [server/api/sla.py](https://github.com/smaramwbc/statewave/blob/main/server/api/sla.py)\n- [server/api/admin.py](https://github.com/smaramwbc/statewave/blob/main/server/api/admin.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n</details>\n\n# API 路由参考\n\n本文档提供 Statewave API v1 的完整路由参考，涵盖所有可用端点、请求/响应格式及使用场景。\n\n## 概览\n\nStatewave API 基于 FastAPI 构建，提供 RESTful 接口用于管理 **Subject（主体）**、**Episode（事件）**、**Memory（记忆）**、**Resolution（解决方案）** 等核心实体。API 支持多租户隔离、速率限制和可配置的上下文组装策略。\n\n### 基础信息\n\n| 项目 | 值 |\n|------|-----|\n| 基础 URL | `http://localhost:8100` |\n| API 版本 | v1 |\n| 认证方式 | `X-API-Key` 请求头 |\n| 租户隔离 | `X-Tenant-ID` 请求头 |\n| 数据格式 | JSON |\n\n### 可用文档界面\n\n| 界面 | URL |\n|------|-----|\n| Swagger UI | `http://localhost:8100/docs` |\n| ReDoc | `http://localhost:8100/redoc` |\n\n---\n\n## 健康检查路由\n\n### 存活性检查\n\n```\nGET /healthz\nGET /health\n```\n\n返回服务存活性状态。\n\n**响应示例：**\n\n```json\n{\n  \"status\": \"ok\"\n}\n```\n\n### 就绪检查\n\n```\nGET /readyz\nGET /ready\n```\n\n返回服务就绪状态（依赖项检查通过后返回）。\n\n---\n\n## Episode 路由\n\nEpisode 是 Statewave 中的原子事件单元，支持追加写入。\n\n### 摄入单个 Episode\n\n```\nPOST /v1/episodes\n```\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"session_id\": \"string (optional)\",\n  \"source\": \"string\",\n  \"type\": \"string\",\n  \"payload\": {\n    \"messages\": [\n      {\n        \"role\": \"user|assistant|system\",\n        \"content\": \"string\",\n        \"timestamp\": \"ISO8601 (optional)\"\n      }\n    ],\n    \"event_time\": \"ISO8601 (optional)\"\n  },\n  \"metadata\": {},\n  \"provenance\": {}\n}\n```\n\n### 批量摄入 Episodes\n\n```\nPOST /v1/episodes/batch\n```\n\n**请求体：**\n\n```json\n{\n  \"episodes\": [\n    {\n      \"subject_id\": \"string\",\n      \"session_id\": \"string\",\n      \"source\": \"string\",\n      \"type\": \"string\",\n      \"payload\": {},\n      \"metadata\": {},\n      \"provenance\": {}\n    }\n  ]\n}\n```\n\n**限制：** 单次请求最多 100 条 Episodes\n\n### 查询 Episodes\n\n```\nGET /v1/episodes\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `subject_id` | string | - | 按主体 ID 过滤 |\n| `session_id` | string | - | 按会话 ID 过滤 |\n| `source` | string | - | 按来源过滤 |\n| `limit` | int | 50 | 返回条数 (1-200) |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Episode 详情\n\n```\nGET /v1/episodes/{episode_id}\n```\n\n### 获取 Episode 引用关系\n\n```\nGET /v1/subjects/{subject_id}/episodes/{episode_id}/citing-memories\n```\n\n列出引用特定 Episode 的所有 Memory，支持反向溯源查询。\n\n**响应包含字段：**\n\n- `id` - Memory ID\n- `kind` - Memory 类型\n- `content` - Memory 内容\n- `relationship` - 关系类型 (`sibling`)\n\n---\n\n## Memory 路由\n\nMemory 是从 Episode 编译提取的结构化知识单元。\n\n### 编译 Memories\n\n```\nPOST /v1/memories/compile\n```\n\n触发 Memory 编译流程，将指定主体的 Episodes 转换为 Memories。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"mode\": \"heuristic|llm (optional)\",\n  \"force\": false\n}\n```\n\n### 搜索 Memories\n\n```\nGET /v1/memories/search\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `kind` | string | Memory 类型 |\n| `query` | string | 语义搜索文本 |\n| `limit` | int | 返回条数 |\n| `offset` | int | 偏移量 |\n\n### 列出 Memories\n\n```\nGET /v1/memories\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `subject_id` | string | - | 按主体 ID 过滤 |\n| `kind` | string | - | 按类型过滤 |\n| `status` | string | - | 按状态过滤 |\n| `limit` | int | 50 | 返回条数 |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Memory 详情\n\n```\nGET /v1/memories/{memory_id}\n```\n\n### 获取 Memory 演化链\n\n```\nGET /v1/memories/{memory_id}/evolution\n```\n\n返回 Memory 的版本演化信息，包括：\n\n- `superseding_memory` - 替代当前 Memory 的新版本\n- `superseded_memories` - 被当前 Memory 替代的旧版本\n- `sibling_memories` - 同源 Memory（源自同一 Episode）\n\n### 删除 Memory\n\n```\nDELETE /v1/memories/{memory_id}\n```\n\n---\n\n## Context 路由\n\n### 组装上下文包\n\n```\nPOST /v1/context\n```\n\n根据查询条件组装满足 Token 限制的上下文束。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"query\": \"string (optional)\",\n  \"k\": 10,\n  \"max_tokens\": 4000,\n  \"include_episodes\": false,\n  \"include_memories\": true,\n  \"memory_kinds\": [\"profile_fact\", \"episode_summary\"]\n}\n```\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"query\": \"string\",\n  \"episodes\": [],\n  \"memories\": [],\n  \"total_tokens\": 1234,\n  \"truncated\": false\n}\n```\n\n---\n\n## Subject 路由\n\nSubject 是 Statewave 中的顶级实体，代表一个需要记忆的\"主体\"（用户、实体或概念）。\n\n### 列出 Subjects\n\n```\nGET /v1/subjects\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `limit` | int | 50 | 返回条数 |\n| `offset` | int | 0 | 偏移量 |\n\n### 创建 Subject\n\n```\nPOST /v1/subjects\n```\n\n**请求体：**\n\n```json\n{\n  \"id\": \"string (optional)\",\n  \"name\": \"string (optional)\",\n  \"metadata\": {}\n}\n```\n\n### 获取 Subject 详情\n\n```\nGET /v1/subjects/{id}\n```\n\n### 删除 Subject\n\n```\nDELETE /v1/subjects/{id}\n```\n\n永久删除指定主体的所有数据（包含 Episodes、Memories、Resolutions）。\n\n### 导出 Subject\n\n```\nGET /v1/subjects/{id}/export\n```\n\n导出主体的完整数据为归档包。\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `include_snapshots` | bool | false | 包含快照数据 |\n| `preserve_ids` | bool | false | 保留原始 ID |\n\n### 导入 Subject\n\n```\nPOST /v1/subjects/import\n```\n\n**请求体：**\n\n```json\n{\n  \"archive\": {},\n  \"conflict_strategy\": \"create_copy|merge|cancel\"\n}\n```\n\n**冲突处理策略：**\n\n| 策略 | 说明 |\n|------|------|\n| `create_copy` | 创建新主体并分配新 ID |\n| `merge` | 合并到已存在主体 |\n| `cancel` | 目标主体已存在则报错 |\n\n---\n\n## Timeline 路由\n\n### 获取 Subject 时间线\n\n```\nGET /v1/timeline\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `since` | ISO8601 | 起始时间 |\n| `until` | ISO8601 | 结束时间 |\n| `limit` | int | 返回条数 |\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"episodes\": [],\n  \"memories\": []\n}\n```\n\n### 获取 Session 时间线\n\n```\nGET /v1/timeline/sessions/{session_id}\n```\n\n返回会话内的所有事件（Episodes 和 Resolutions）按时间顺序合并。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `session_id` | string | 会话 ID |\n| `status` | string | 会话状态 |\n| `first_message_at` | string | 首条消息时间 |\n| `first_response_at` | string | 首次响应时间 |\n| `resolved_at` | string | 解决时间 |\n| `first_response_seconds` | float | 首次响应耗时 |\n| `resolution_seconds` | float | 解决耗时 |\n| `first_response_breached` | bool | 是否超过首次响应 SLA |\n| `resolution_breached` | bool | 是否超过解决 SLA |\n| `events` | array | 时间线事件列表 |\n\n---\n\n## Resolution 路由\n\nResolution 用于跟踪问题解决状态。\n\n### 记录 Resolution\n\n```\nPOST /v1/resolutions\n```\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"session_id\": \"string\",\n  \"status\": \"pending|resolved|escalated\",\n  \"resolution_summary\": \"string\",\n  \"resolved_at\": \"ISO8601 (optional)\",\n  \"metadata\": {}\n}\n```\n\n### 列出 Resolutions\n\n```\nGET /v1/resolutions\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `session_id` | string | 会话 ID |\n| `status` | string | 按状态过滤 |\n\n---\n\n## Handoff 路由\n\n### 生成 Handoff 上下文包\n\n```\nPOST /v1/handoff\n```\n\n生成紧凑的交接上下文，用于在代理/会话之间传递状态。\n\n**请求体：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"handoff_type\": \"agent_transfer|shift_change|escalation\",\n  \"max_tokens\": 2000,\n  \"include_recent_episodes\": true,\n  \"include_active_memories\": true\n}\n```\n\n**响应：**\n\n```json\n{\n  \"subject_id\": \"string\",\n  \"handoff_type\": \"string\",\n  \"context\": {\n    \"summary\": \"string\",\n    \"key_points\": [],\n    \"pending_items\": [],\n    \"recent_episodes\": [],\n    \"relevant_memories\": []\n  },\n  \"total_tokens\": 1234\n}\n```\n\n---\n\n## Health 路由\n\n### 获取 Customer Health Score\n\n```\nGET /v1/subjects/{id}/health\n```\n\n返回主体的健康评分及可解释因子。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `health_score` | float | 健康分 (0-100) |\n| `factors` | array | 影响因素 |\n| `breakdown` | object | 详细分解 |\n\n---\n\n## SLA 路由\n\n### 获取 SLA 指标\n\n```\nGET /v1/subjects/{id}/sla\n```\n\n返回 SLA 相关指标。\n\n**响应字段：**\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subject_id` | string | 主体 ID |\n| `response_time` | object | 响应时间统计 |\n| `resolution_time` | object | 解决时间统计 |\n| `breaches` | object | SLA 违约情况 |\n| `period` | string | 统计周期 |\n\n---\n\n## Admin 路由\n\nAdmin 路由提供系统管理功能。\n\n### 列出 Subject Episodes（分页）\n\n```\nGET /v1/admin/subjects/{subject_id}/episodes\n```\n\n**查询参数：**\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `limit` | int | 50 | 返回条数 (1-200) |\n| `offset` | int | 0 | 偏移量 |\n\n### 获取 Snapshot 详情\n\n```\nGET /v1/admin/snapshots/{snapshot_id}\n```\n\n### 恢复 Snapshot\n\n```\nPOST /v1/admin/snapshots/{snapshot_id}/restore\n```\n\n**请求体：**\n\n```json\n{\n  \"target_subject_id\": \"string (optional)\",\n  \"time_shift\": \"duration string (optional)\",\n  \"preserve_metadata\": true\n}\n```\n\n### 导入 Memory Pack\n\n```\nPOST /v1/memory-packs/import\n```\n\n**请求体：**\n\n```json\n{\n  \"pack_url\": \"string\",\n  \"pack_data\": {},\n  \"conflict_strategy\": \"create_copy|merge|cancel\"\n}\n```\n\n---\n\n## 架构流程图\n\n### Episode → Memory 编译流程\n\n```mermaid\ngraph TD\n    A[Episode 摄入] --> B{编译模式}\n    B -->|Heuristic| C[启发式编译器]\n    B -->|LLM| D[LLM 编译器]\n    C --> E[提取 Profile Facts]\n    C --> F[生成 Episode Summary]\n    D --> G[结构化知识提取]\n    E --> H[MemoryRow 存储]\n    F --> H\n    G --> H\n    H --> I[Memory 索引完成]\n```\n\n### Context 组装流程\n\n```mermaid\ngraph TD\n    A[Context 请求] --> B[查询 Episodes]\n    A --> C[查询 Memories]\n    B --> D[相关性评分]\n    C --> D\n    D --> E[Token 预算检查]\n    E -->|超出限制| F[按分数排序裁剪]\n    E -->|未超出| G[返回完整结果]\n    F --> G\n```\n\n### 主体数据流\n\n```mermaid\ngraph LR\n    A[Subject 创建] --> B[Episodes 摄入]\n    B --> C[Memories 编译]\n    C --> D[Context 组装]\n    B --> E[Resolutions 记录]\n    D --> F[Timeline 查询]\n    E --> F\n```\n\n---\n\n## 环境变量配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `STATEWAVE_DATABASE_URL` | - | PostgreSQL 连接串 |\n| `STATEWAVE_API_KEY` | - | API 认证密钥 |\n| `STATEWAVE_LITELLM_API_KEY` | - | LLM API 密钥 |\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 多租户隔离头 |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制租户头 |\n| `STATEWAVE_RATE_LIMIT` | `0` | 每 IP 请求限流 |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略 |\n| `STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS` | `4000` | 默认 Token 预算 |\n\n---\n\n## 速率限制\n\nStatewave 支持两种速率限制策略：\n\n| 策略 | 说明 |\n|------|------|\n| `distributed` | 基于 PostgreSQL 的分布式限流 |\n| `memory` | 进程内内存限流 |\n\n**当前限制：** 限流按 IP 维度，未实现按租户或 API Key 的细粒度限流。\n\n---\n\n## 错误响应格式\n\n```json\n{\n  \"detail\": \"错误描述信息\"\n}\n```\n\n常见 HTTP 状态码：\n\n| 状态码 | 说明 |\n|--------|------|\n| `400` | 请求参数错误 |\n| `401` | 认证失败 |\n| `403` | 权限不足 |\n| `404` | 资源不存在 |\n| `413` | 请求体过大 |\n| `429` | 速率限制 |\n| `500` | 服务器内部错误 |\n\n---\n\n<a id='p-services'></a>\n\n## 服务层实现\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview), [API 路由参考](#p-api-routes)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/services/backup.py](https://github.com/smaramwbc/statewave/blob/main/server/services/backup.py)\n- [server/services/handoff.py](https://github.com/smaramwbc/statewave/blob/main/server/services/handoff.py)\n- [server/services/memory_packs.py](https://github.com/smaramwbc/statewave/blob/main/server/services/memory_packs.py)\n- [server/services/receipts.py](https://github.com/smaramwbc/statewave/blob/main/server/services/receipts.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/webhooks.py](https://github.com/smaramwbc/statewave/blob/main/server/services/webhooks.py)\n- [server/services/ratelimit.py](https://github.com/smaramwbc/statewave/blob/main/server/services/ratelimit.py)\n</details>\n\n# 服务层实现\n\n## 概述\n\nStatewave 的服务层是业务逻辑的核心载体，负责处理记忆编译、上下文组装、快照管理、内存包操作、交接（handoff）处理、Webhook 通知、速率限制等关键功能。服务层位于 API 路由层与数据库持久层之间，封装了所有复杂的数据处理流程，确保 API 端点保持简洁。\n\n服务层采用异步架构设计，充分利用 Python 的 `asyncio` 特性处理 I/O 密集型操作。所有服务模块均支持多租户隔离，通过 `tenant_id` 参数实现数据层面的访问控制。\n\n---\n\n## 服务模块架构\n\n```mermaid\ngraph TD\n    subgraph \"服务层 (server/services)\"\n        A[context.py<br/>上下文组装服务]\n        B[snapshots.py<br/>快照管理服务]\n        C[memory_packs.py<br/>内存包服务]\n        D[handoff.py<br/>交接服务]\n        E[receipts.py<br/>回执服务]\n        F[webhooks.py<br/>Webhook服务]\n        G[ratelimit.py<br/>速率限制服务]\n        H[backup.py<br/>备份导出服务]\n    end\n    \n    subgraph \"API 层 (server/api)\"\n        I[episodes.py]\n        J[memories.py]\n        K[context.py]\n        L[handoff.py]\n        M[admin.py]\n    end\n    \n    subgraph \"数据层\"\n        N[(PostgreSQL)]\n    end\n    \n    I --> A\n    J --> A\n    K --> A\n    L --> D\n    M --> B\n    M --> C\n    A --> N\n    B --> N\n    C --> N\n    D --> E\n    D --> F\n    G --> N\n    H --> N\n```\n\n---\n\n## 上下文组装服务\n\n### 核心职责\n\n`context.py` 模块负责从主题的记忆库中检索相关记忆和事件，并组装成符合 token 预算限制的上下文束。该服务是 Statewave 记忆系统对外暴露的核心能力之一。\n\n### 内部类型设计\n\n**`_ScoredItem` 类** — 评分项封装\n\n```python\nclass _ScoredItem:\n    \"\"\"An item (memory or episode) with its computed relevance score.\"\"\"\n    __slots__ = (\"score\", \"kind\", \"memory_row\", \"episode_row\", \"text\", \"section\")\n```\n\n| 属性 | 类型 | 说明 |\n|------|------|------|\n| `score` | `float` | 计算后的相关性评分 |\n| `kind` | `str` | 项目类型：`\"memory\"` 或 `\"episode\"` |\n| `memory_row` | `Any` | 关联的 MemoryRow 对象（可选） |\n| `episode_row` | `Any` | 关联的 EpisodeRow 对象（可选） |\n| `text` | `str` | 用于检索的文本内容 |\n| `section` | `str` | 内容所属的逻辑分区 |\n\n### 上下文组装流程\n\n```mermaid\ngraph LR\n    A[请求上下文] --> B[查询记忆库]\n    B --> C[相关性评分]\n    C --> D[Token 预算计算]\n    D --> E[内容裁剪]\n    E --> F[返回上下文束]\n```\n\n### 响应格式化\n\n服务提供 `_episode_response` 工厂函数，将数据库行转换为标准 API 响应格式：\n\n```python\ndef _episode_response(row: Any) -> EpisodeResponse:\n    return EpisodeResponse(\n        id=row.id,\n        subject_id=row.subject_id,\n        source=row.source,\n        type=row.type,\n        payload=row.payload,\n        metadata=row.metadata_,\n        provenance=row.provenance,\n        occurred_at=row.occurred_at,\n        created_at=row.created_at,\n        session_id=getattr(row, \"session_id\", None),\n    )\n```\n\n资料来源：[server/services/context.py:1-30]()\n\n---\n\n## 快照管理服务\n\n### 核心职责\n\n`snapshots.py` 模块提供主题快照的创建、恢复和管理功能。快照是主题在某一时点的完整状态镜像，包含事件、记忆和解决方案数据。\n\n### 快照创建流程\n\n```mermaid\ngraph TD\n    A[创建快照请求] --> B[验证源主题存在]\n    B --> C{快照主题冲突检测}\n    C -->|冲突| D[生成候选主题ID]\n    C -->|无冲突| E[读取源主题数据]\n    E --> F[遍历事件并创建快照副本]\n    F --> G[遍历记忆并创建快照副本]\n    G --> H[遍历解决方案并创建快照副本]\n    H --> I[创建 SubjectSnapshotRow 元数据]\n    I --> J[提交事务]\n    J --> K[返回快照信息]\n```\n\n### 时间戳偏移处理\n\n恢复快照时，服务支持时间戳偏移（`time_shift`），允许在不影响原始数据的情况下重建历史状态：\n\n```python\nmem_created = mem.created_at\nif mem_created.tzinfo is None:\n    mem_created = mem_created.replace(tzinfo=timezone.utc)\nmem_updated = mem.updated_at\nif mem_updated.tzinfo is None:\n    mem_updated = mem_updated.replace(tzinfo=timezone.utc)\n```\n\n| 参数 | 说明 |\n|------|------|\n| `time_shift` | 时间偏移量，用于调整恢复后数据的时间戳 |\n| `target_subject_id` | 恢复的目标主题 ID |\n| `snapshot_id` | 快照唯一标识符 |\n\n### 快照元数据结构\n\n创建快照时记录以下元数据：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | `UUID` | 快照唯一标识 |\n| `name` | `str` | 快照名称 |\n| `version` | `str` | 快照版本 |\n| `source_subject_id` | `UUID` | 源主题 ID |\n| `episode_count` | `int` | 包含的事件数量 |\n| `memory_count` | `int` | 包含的记忆数量 |\n| `metadata_` | `dict` | 自定义元数据 |\n\n资料来源：[server/services/snapshots.py:1-80]()\n\n---\n\n## 内存包服务\n\n### 核心职责\n\n`memory_packs.py` 提供了内存包的克隆、导入、导出等高级操作，支持在主题之间迁移数据或基于现有主题创建新的种子包。\n\n### 克隆作用域\n\n服务定义了四种克隆范围：\n\n| 作用域 | 说明 | 包含内容 |\n|--------|------|----------|\n| `episodes` | 仅事件 | 源主题的全部事件 |\n| `memories` | 仅记忆 | 源主题的全部记忆 |\n| `episodes_and_memories` | 事件+记忆 | 事件和记忆，不含来源引用 |\n| `episodes_memories_sources` | 完整克隆 | 事件、记忆及完整的来源引用链 |\n\n### 冲突解决策略\n\n| 策略 | 说明 | 行为 |\n|------|------|------|\n| `create_copy` | 创建副本（默认） | 为新导入的主题生成新 ID |\n| `merge` | 合并 | 复用原始主题 ID |\n| `cancel` | 取消 | 目标已存在时中止操作 |\n\n### 导入流程\n\n```mermaid\ngraph TD\n    A[导入内存包请求] --> B[验证主题数量限制]\n    B --> C[遍历源主题列表]\n    C --> D[解析原始主题ID]\n    D --> E{冲突策略检测}\n    E -->|create_copy| F[生成新主题ID]\n    E -->|merge| G[复用原始ID]\n    E -->|cancel| H[检查目标存在]\n    H -->|存在| I[抛出错误]\n    H -->|不存在| G\n    F --> J[按类型分组数据]\n    J --> K[创建新主题及数据]\n    K --> L[提交事务]\n```\n\n### 标识符映射机制\n\n导入过程中，服务维护 `id_map` 字典，将原始主题 ID 映射到最终目标主题 ID：\n\n```python\nid_map: dict[str, str] = {}\nfor s in subjects:\n    original = s.get(\"original_subject_id\")\n    _validate_subject_id(original, field=\"subjects[].original_subject_id\", allow_reserved=True)\n    final = await _resolve_target_subject(\n        explicit=original if conflict_strategy != \"create_copy\" else None,\n        suggested=original,\n        conflict_strategy=conflict_strategy,\n    )\n    id_map[original] = final\n```\n\n### 来源验证\n\n服务对来源标识符有严格的验证规则：\n\n- `create_copy` 模式下允许保留前缀的 ID（如 `demo_web_*`）\n- `merge` 和 `cancel` 模式不接受保留前缀的 ID\n- 导入后自动将目标 ID 重写为 `imported-*` 前缀\n\n资料来源：[server/services/memory_packs.py:1-100]()\n\n---\n\n## 交接服务\n\n### 核心职责\n\n`handoff.py` 模块负责生成紧凑的交接上下文包，用于在不同代理或会话之间传递上下文信息。交接包含请求者的身份信息、任务标识和会话状态。\n\n### 交接请求参数\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `subject_id` | `str` | 是 | 主题 ID |\n| `session_id` | `str` | 否 | 会话 ID |\n| `reason` | `str` | 否 | 交接原因 |\n| `max_tokens` | `int` | 否 | 最大 token 数 |\n| `emit_receipt` | `bool` | 否 | 是否生成回执 |\n| `query_id` | `str` | 否 | 查询 ID |\n| `task_id` | `str` | 否 | 任务 ID |\n| `parent_receipt_id` | `str` | 否 | 父回执 ID |\n| `caller_id` | `str` | 条件必填 | 调用者 ID（部分配置下必填） |\n| `caller_type` | `str` | 条件必填 | 调用者类型（部分配置下必填） |\n\n### 租户配置验证\n\n某些配置下，系统要求每个交接请求必须包含 `caller_id` 和 `caller_type`：\n\n```python\nif tenant_config_requires_caller and (not body.caller_id or not body.caller_type):\n    raise HTTPException(\n        status_code=401,\n        detail=(\n            \"tenant config requires caller_id and caller_type on every \"\n            \"handoff call\"\n        ),\n    )\n```\n\n资料来源：[server/services/handoff.py:1-50]()\n\n---\n\n## 回执服务\n\n### 核心职责\n\n`receipts.py` 模块负责生成和管理操作回执（Receipt）。回执是操作的不可变审计记录，包含操作的输入、输出和元数据。\n\n### 回执数据结构\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | `UUID` | 回执唯一标识 |\n| `tenant_id` | `str` | 租户 ID |\n| `operation_type` | `str` | 操作类型 |\n| `query_id` | `str` | 关联的查询 ID |\n| `task_id` | `str` | 关联的任务 ID |\n| `parent_receipt_id` | `str` | 父回执 ID（用于追溯） |\n| `input_data` | `dict` | 操作输入数据 |\n| `output_data` | `dict` | 操作输出数据 |\n| `metadata` | `dict` | 额外元数据 |\n| `created_at` | `datetime` | 创建时间 |\n\n### 层级关系\n\n回执支持父子层级结构，允许追踪复杂操作链：\n\n```mermaid\ngraph TD\n    A[根回执] --> B[子回执 1]\n    A --> C[子回执 2]\n    B --> D[孙回执 1.1]\n    C --> E[孙回执 2.1]\n```\n\n---\n\n## Webhook 服务\n\n### 核心职责\n\n`webhooks.py` 模块提供异步事件通知能力，允许外部系统在特定事件发生时接收通知。\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_WEBHOOK_URL` | — | Webhook 回调 URL（空则禁用） |\n| `STATEWAVE_WEBHOOK_TIMEOUT` | `5.0` | HTTP 请求超时时间（秒） |\n\n### 事件类型\n\n| 事件类型 | 触发时机 |\n|----------|----------|\n| `episode.created` | 新事件创建时 |\n| `memory.compiled` | 记忆编译完成时 |\n| `memory.evolved` | 记忆演进时 |\n| `snapshot.created` | 快照创建时 |\n| `snapshot.restored` | 快照恢复时 |\n| `handoff.issued` | 交接发起时 |\n\n### 重试机制\n\nWebhook 投递采用指数退避策略，配置最大重试次数确保最终一致性。\n\n---\n\n## 速率限制服务\n\n### 核心职责\n\n`ratelimit.py` 模块实现请求速率控制，保护系统免受滥用和过载。\n\n### 速率限制策略\n\n| 策略 | 说明 | 存储后端 |\n|------|------|----------|\n| `distributed` | 分布式模式 | PostgreSQL |\n| `memory` | 内存模式 | 进程内内存 |\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_RATE_LIMIT` | `0` | 每分钟请求/IP（0=禁用） |\n| `STATEWAVE_RATE_LIMIT_STRATEGY` | `distributed` | 限流策略选择 |\n\n### 限流维度\n\n当前版本按 IP 地址进行速率限制，尚未支持按租户或 API Key 的细粒度控制。\n\n资料来源：[README.md:1-50]()\n\n---\n\n## 备份导出服务\n\n### 核心职责\n\n`backup.py` 模块提供主题数据的导出功能，生成标准化的备份格式供导入或迁移使用。\n\n### 导出数据结构\n\n导出的 JSON 文档包含以下顶级字段：\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `subjects` | `list` | 主题列表 |\n| `episodes` | `list` | 事件列表 |\n| `memories` | `list` | 记忆列表 |\n| `resolutions` | `list` | 解决方案列表 |\n| `exported_at` | `datetime` | 导出时间戳 |\n| `version` | `str` | 导出格式版本 |\n\n### 与导入的互操作性\n\n导出格式与内存包导入端点完全兼容，确保数据可以在不同 Statewave 实例间自由迁移：\n\n```python\nfrom server.services.backup import export_subject\nsource_doc = await export_subject(source_subject_id, tenant_id=None)\n```\n\n资料来源：[server/services/memory_packs.py:50-60]()\n\n---\n\n## 服务层公共模式\n\n### 多租户隔离\n\n所有服务方法都接受可选的 `tenant_id` 参数，用于数据层面的租户隔离：\n\n```python\nasync def some_service_method(..., tenant_id: str | None = None):\n    \"\"\"Service method with multi-tenant support.\"\"\"\n    pass\n```\n\n### 事务管理\n\n服务层通过 SQLAlchemy 的异步会话管理事务：\n\n```python\nasync with engine_module.get_session_factory()() as session:\n    # 业务逻辑\n    await session.commit()\n```\n\n### 日志记录\n\n服务层采用结构化日志记录关键操作：\n\n```python\nlogger.info(\n    \"snapshot_created\", name=name, version=version, \n    episodes=len(eps), memories=len(mems)\n)\n```\n\n---\n\n## 服务间依赖关系\n\n```mermaid\ngraph LR\n    A[API 层] --> B[Context 服务]\n    A --> C[Snapshot 服务]\n    A --> D[Memory Pack 服务]\n    A --> E[Handoff 服务]\n    \n    B --> F[Receipt 服务]\n    B --> G[Webhook 服务]\n    \n    E --> F\n    E --> G\n    \n    D --> H[Backup 服务]\n    \n    I[RateLimit 服务] --> A\n```\n\n---\n\n## 总结\n\nStatewave 的服务层通过模块化设计实现了业务逻辑的清晰分离。各服务专注于单一职责，同时通过标准化的接口相互协作。异步架构确保了高并发场景下的性能表现，而多租户支持则满足了企业级部署的需求。\n\n---\n\n<a id='p-database'></a>\n\n## 数据库架构\n\n### 相关页面\n\n相关主题：[系统架构概览](#p-arch-overview)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [server/db/tables.py](https://github.com/smaramwbc/statewave/blob/main/server/db/tables.py)\n- [server/db/repositories.py](https://github.com/smaramwbc/statewave/blob/main/server/db/repositories.py)\n- [server/services/snapshots.py](https://github.com/smaramwbc/statewave/blob/main/server/services/snapshots.py)\n- [server/services/context.py](https://github.com/smaramwbc/statewave/blob/main/server/services/context.py)\n- [server/api/timeline.py](https://github.com/smaramwbc/statewave/blob/main/server/api/timeline.py)\n</details>\n\n# 数据库架构\n\n## 概述\n\nStatewave 采用 **PostgreSQL** 作为主数据库，通过 `asyncpg` 异步驱动实现高性能数据访问。数据库架构围绕三个核心实体构建：**Episode（事件）**、**Memory（记忆）** 和 **Subject（主体）**，支持多租户隔离、快照恢复和时间线查询等高级功能。\n\n资料来源：[DOCKER.md:8]()\n\n## 核心数据模型\n\n### Entity-Relationship 概览\n\n```mermaid\nerDiagram\n    Subject ||--o{ Episode : contains\n    Subject ||--o{ Memory : contains\n    Episode ||--o{ Memory : generates\n    Subject ||--o{ Resolution : tracks\n    Subject ||--o{ SubjectSnapshot : snapshots\n    Memory }o--o{ Memory : supersedes\n```\n\n### 主要数据表\n\n| 表名 | 用途 | 核心字段 |\n|------|------|----------|\n| `episodes` | 不可变事件记录 | id, subject_id, session_id, source, type, payload, occurred_at |\n| `memories` | 从事件编译的记忆 | id, subject_id, kind, content, summary, source_episode_ids |\n| `resolutions` | 问题解决状态跟踪 | id, subject_id, session_id, status, resolved_at |\n| `subject_snapshots` | 主题时间点快照 | id, source_subject_id, episode_count, memory_count |\n\n资料来源：[server/services/snapshots.py:1-100]()\n\n## 表结构详解\n\n### EpisodeRow（事件表）\n\n事件是 Statewave 的基础数据单元，代表主体（Subject）的任意活动记录。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 事件唯一标识符 |\n| `subject_id` | String | 关联的主体 ID |\n| `session_id` | String | 所属会话标识 |\n| `tenant_id` | String | 多租户隔离标识 |\n| `source` | String | 事件来源（api, github, slack 等） |\n| `type` | String | 事件类型（message, issue, pr 等） |\n| `payload` | JSONB | 事件完整负载 |\n| `metadata_` | JSONB | 附加元数据 |\n| `provenance` | JSONB | 数据溯源信息 |\n| `occurred_at` | DateTime | 事件实际发生时间 |\n| `created_at` | DateTime | 记录创建时间 |\n\n```python\n# 事件创建示例（server/services/snapshots.py:51-65）\nEpisodeRow(\n    id=uuid.uuid4(),\n    subject_id=snapshot_subject,\n    session_id=ep.session_id,\n    tenant_id=ep.tenant_id,\n    source=ep.source,\n    type=ep.type,\n    payload=ep.payload,\n    metadata_=ep.metadata_,\n    provenance=ep.provenance,\n    occurred_at=ep.occurred_at,\n    created_at=ep.created_at,\n)\n```\n\n资料来源：[server/services/snapshots.py:51-65]()\n\n### MemoryRow（记忆表）\n\n记忆是从事件编译的提炼数据，支持多种类型和有效期管理。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 记忆唯一标识符 |\n| `subject_id` | String | 关联的主体 ID |\n| `kind` | String | 记忆类型（episode_summary, profile_fact 等） |\n| `content` | Text | 完整记忆内容 |\n| `summary` | String | 摘要（200字符） |\n| `confidence` | Float | 置信度（0-1） |\n| `valid_from` | DateTime | 有效期起始 |\n| `valid_to` | DateTime | 有效期结束（可选） |\n| `source_episode_ids` | Array[UUID] | 源事件 ID 列表 |\n| `status` | String | 状态（active, superseded 等） |\n| `sensitivity_labels` | Array[String] | 敏感度标签 |\n\n```python\n# 记忆创建示例（server/services/compilers/heuristic.py:1-50）\nMemoryRow(\n    id=uuid.uuid4(),\n    subject_id=ep.subject_id,\n    kind=\"episode_summary\",\n    content=text[:500],\n    summary=text[:200],\n    confidence=0.8,\n    valid_from=ep_valid_from,\n    valid_to=compute_valid_to(\"episode_summary\", ep_valid_from, ttl),\n    source_episode_ids=[ep.id],\n    metadata_={},\n    status=\"active\",\n)\n```\n\n资料来源：[server/services/compilers/heuristic.py:1-50]()\n\n### SubjectSnapshotRow（快照表）\n\n快照用于备份和恢复主体在特定时间点的完整状态。\n\n| 字段 | 类型 | 说明 |\n|------|------|------|\n| `id` | UUID | 快照唯一标识符 |\n| `name` | String | 快照名称 |\n| `version` | String | 版本标识 |\n| `source_subject_id` | UUID | 源主体 ID |\n| `episode_count` | Integer | 事件数量 |\n| `memory_count` | Integer | 记忆数量 |\n| `metadata_` | JSONB | 快照元数据 |\n\n```python\n# 快照创建示例（server/services/snapshots.py:85-95）\nSubjectSnapshotRow(\n    name=name,\n    version=version,\n    source_subject_id=snapshot_subject,\n    episode_count=len(eps),\n    memory_count=len(mems),\n    metadata_=metadata or {},\n)\n```\n\n资料来源：[server/services/snapshots.py:85-95]()\n\n## 异步数据库访问模式\n\n### 引擎与会话管理\n\nStatewave 使用 SQLAlchemy 2.0 异步引擎，结合 `asyncpg` 驱动实现非阻塞 IO。\n\n```python\n# 异步会话获取模式（server/api/timeline.py:100-120）\nfrom server.db import engine as engine_module\n\nasync with engine_module.get_session_factory()() as session:\n    base = select(MemoryRow)\n    # ... 查询操作\n```\n\n### 查询构建示例\n\n```python\n# 复杂查询：查找引用特定事件的记忆（server/api/timeline.py:130-150）\nbase = select(MemoryRow).where(\n    MemoryRow.tenant_id == tenant_id,\n    MemoryRow.subject_id == subject_id,\n    func.any_(MemoryRow.source_episode_ids) == episode_uuid\n)\n```\n\n资料来源：[server/api/timeline.py:100-150]()\n\n## 仓储层设计\n\n### Repository 模式\n\n数据访问通过 Repository 模式封装，提供统一的 CRUD 操作接口。\n\n```mermaid\ngraph TD\n    A[API Layer] --> B[Service Layer]\n    B --> C[Repository Layer]\n    C --> D[(PostgreSQL)]\n    \n    E[Memory Repository] --> C\n    F[Episode Repository] --> C\n    G[Resolution Repository] --> C\n```\n\n### 核心仓储操作\n\n| 操作类型 | 方法 | 说明 |\n|----------|------|------|\n| 创建 | `write_receipt()` | 写入收据记录 |\n| 读取 | `get_session_factory()` | 获取异步会话 |\n| 更新 | `compile_memories()` | 编译新记忆 |\n| 删除 | 批量删除 | 按主体 ID 删除 |\n\n资料来源：[server/db/repositories.py](https://github.com/smaramwbc/statewave/blob/main/server/db/repositories.py)\n\n## 多租户数据隔离\n\n### 隔离策略\n\nStatewave 采用应用层多租户隔离，通过 `tenant_id` 字段实现数据分区。\n\n```mermaid\ngraph LR\n    A[Request] --> B{X-Tenant-ID Header}\n    B -->|有租户ID| C[按 tenant_id 过滤]\n    B -->|无租户ID| D[拒绝请求]\n    \n    C --> E[WHERE tenant_id = ?]\n```\n\n### 环境配置\n\n| 环境变量 | 默认值 | 说明 |\n|----------|--------|------|\n| `STATEWAVE_TENANT_HEADER` | `X-Tenant-ID` | 租户标识头 |\n| `STATEWAVE_REQUIRE_TENANT` | `false` | 是否强制要求租户头 |\n\n```python\n# 租户过滤查询示例\nbase = select(MemoryRow).where(\n    MemoryRow.tenant_id == tenant_id,\n    MemoryRow.subject_id == subject_id\n)\n```\n\n资料来源：[README.md:1-50]()\n\n## 时间线与快照管理\n\n### 时间线查询\n\n支持按时间顺序检索主体的事件和记忆，支持事件合并展示。\n\n```python\n# 时间线响应模型（server/api/admin.py:50-80）\nclass SessionTimelineResponse(BaseModel):\n    session_id: str\n    status: str\n    first_message_at: str | None\n    resolved_at: str | None\n    episode_count: int\n    events: list[TimelineEvent]\n```\n\n### 快照恢复\n\n快照恢复支持时间偏移（Time Shift），确保恢复后时间戳的连续性。\n\n```python\n# 时间偏移处理（server/services/snapshots.py:130-160）\ntime_shift = target_created_at - snapshot_created_at\n\n# 记忆时间戳偏移\ncreated_at=mem_created + time_shift,\nupdated_at=mem_updated + time_shift,\nvalid_from=mem_valid_from + time_shift if mem_valid_from else None,\n```\n\n资料来源：[server/services/snapshots.py:130-160]()\n\n## 索引与性能优化\n\n### 推荐索引策略\n\n| 表名 | 推荐索引 | 用途 |\n|------|----------|------|\n| `memories` | `(subject_id, kind)` | 记忆类型查询 |\n| `memories` | `(source_episode_ids)` | 事件溯源查询 |\n| `episodes` | `(subject_id, occurred_at)` | 时间线查询 |\n| `episodes` | `(session_id)` | 会话聚合 |\n\n### JSONB 字段优化\n\n```python\n# JSONB 查询示例\nquery = select(MemoryRow).where(\n    MemoryRow.payload['event_type'].astext == 'message'\n)\n```\n\n## 迁移与版本管理\n\n### Alembic 集成\n\nStatewave 使用 Alembic 进行数据库迁移管理。\n\n```bash\n# Helm 安装时的预安装 Job\nalembic upgrade head\n```\n\n### 迁移执行时机\n\n| 操作 | 迁移时机 |\n|------|----------|\n| 首次安装 | Pre-install Job |\n| 版本升级 | Pre-upgrade Job |\n\n资料来源：[helm/statewave/README.md:1-30]()\n\n## 配置参考\n\n### 数据库连接配置\n\n```yaml\n# Docker Compose 配置示例\nenvironment:\n  STATEWAVE_DATABASE_URL: postgresql+asyncpg://statewave:statewave@db:5432/statewave\n```\n\n### 测试环境配置\n\n```bash\n# 创建测试数据库\nPGPASSWORD=statewave createdb -h localhost -U statewave statewave_test\n```\n\n```python\n# 集成测试执行\npytest tests/integration/ -v\n```\n\n资料来源：[README.md:100-120]()\n\n## 最佳实践\n\n### 数据建模建议\n\n1. **事件不可变性**：事件一旦写入不应修改，通过新事件表达状态变更\n2. **记忆有效期**：使用 `valid_from`/`valid_to` 管理记忆时效\n3. **源事件追踪**：始终维护 `source_episode_ids` 引用链\n4. **租户隔离**：所有查询必须包含 `tenant_id` 过滤条件\n\n### 性能注意事项\n\n1. 避免全表扫描，使用索引覆盖查询\n2. 批量操作使用 `BATCH_SIZE = 50` 分批处理\n3. 大型导入使用快照机制而非实时编译\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：smaramwbc/statewave\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1219923941 | https://github.com/smaramwbc/statewave | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | release_recency=unknown\n\n<!-- canonical_name: smaramwbc/statewave; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：smaramwbc/statewave\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | github_repo:1219923941 | https://github.com/smaramwbc/statewave | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | github_repo:1219923941 | https://github.com/smaramwbc/statewave | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | github_repo:1219923941 | https://github.com/smaramwbc/statewave | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# statewave - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 statewave 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: Open-source memory runtime for AI agents. Durable, structured context with provenance — so your AI stops forgetting across sessions. Self-hosted on Postgres. 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. p-intro：Statewave 简介。围绕“Statewave 简介”模拟一次用户任务，不展示安装或运行结果。\n2. p-quickstart：快速开始。围绕“快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. p-arch-overview：系统架构概览。围绕“系统架构概览”模拟一次用户任务，不展示安装或运行结果。\n4. p-data-flow：数据流与生命周期。围绕“数据流与生命周期”模拟一次用户任务，不展示安装或运行结果。\n5. p-episodes：Episode 管理。围绕“Episode 管理”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. p-intro\n输入：用户提供的“Statewave 简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. p-quickstart\n输入：用户提供的“快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. p-arch-overview\n输入：用户提供的“系统架构概览”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. p-data-flow\n输入：用户提供的“数据流与生命周期”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. p-episodes\n输入：用户提供的“Episode 管理”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / p-intro：Step 1 必须围绕“Statewave 简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / p-quickstart：Step 2 必须围绕“快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / p-arch-overview：Step 3 必须围绕“系统架构概览”形成一个小中间产物，并等待用户确认。\n- Step 4 / p-data-flow：Step 4 必须围绕“数据流与生命周期”形成一个小中间产物，并等待用户确认。\n- Step 5 / p-episodes：Step 5 必须围绕“Episode 管理”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://github.com/smaramwbc/statewave\n- https://github.com/smaramwbc/statewave#readme\n- README.md\n- server/app.py\n- server/main.py\n- docker-compose.yml\n- DOCKER.md\n- .env.example\n- pyproject.toml\n- server/core/config.py\n- server/core/dependencies.py\n- server/api/__init__.py\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 statewave 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：smaramwbc/statewave\n\n## 官方安装入口\n\n### Python / pip · 官方安装入口\n\n```bash\npip install statewave\n```\n\n来源：https://github.com/smaramwbc/statewave#readme\n\n## 来源\n\n- repo: https://github.com/smaramwbc/statewave\n- docs: https://github.com/smaramwbc/statewave#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_710ffdadb42e4d4ca81c22901be11584"
}
