Sfoglia il codice sorgente

docs: define knowledge base implementation plan

马小龙 1 giorno fa
parent
commit
172ec8e280

+ 249 - 0
docs/architecture/ADR-005-llamaindex-lightrag-knowledge-base.md

@@ -0,0 +1,249 @@
+# ADR-005:LlamaIndex 主检索链路与 LightRAG 图增强侧车
+
+- 状态:Accepted
+- 日期:2026-07-20
+- 细化:[数据治理知识库原实施计划](../superpowers/plans/2026-07-16-governance-knowledge-base.md)
+- 依赖:[ADR-003:跨存储最终一致性](ADR-003-cross-store-consistency.md)
+
+## 背景
+
+DataOps Platform 已经具备以下知识库基础:
+
+- Neo4j 保存 `BusinessDomain`、`DataFlow`、`DataMeta`、数据标准、标签和血缘,
+  是治理对象结构和关系的源真相。
+- PostgreSQL 16 已启用 pgvector,并已经存在 `governance_documents`、
+  `governance_chunks` 和 `governance_sync_jobs`。
+- 平台已有稳定治理 UID、RBAC、Outbox、Qwen Embedding 适配器、DeepSeek
+  生成模型和保留的知识库前端入口。
+
+当前缺口不是再建设一套独立知识库控制面,而是完成:
+
+1. 可替换的混合检索与重排链路;
+2. 对现有治理图的确定性关系检索;
+3. 面向多跳问题的图增强检索;
+4. 业务域级授权、版本和引用闭环;
+5. 增量同步、失败补偿、效果评测和可回滚发布。
+
+LlamaIndex 与 Haystack 位于相同的通用 RAG 框架层。平台选择 LlamaIndex 作为
+唯一主框架;LightRAG 不作为第二套通用框架,而作为隔离的图增强检索引擎。
+
+## 决策
+
+1. **DataOps 继续拥有控制面。** 身份、业务域授权、治理对象版本、同步状态、
+   查询审计、引用和最终答案均由 DataOps 管理。
+2. **LlamaIndex 嵌入 Flask 后端。** 它负责 Node 映射、Retriever 编排、候选
+   融合、重排和回答合成,但不创建自己的用户、权限或业务源数据。
+3. **不采用 LlamaIndex 默认持久化表作为源真相。** 建设
+   `DataOpsVectorStore`、`DataOpsNodeMapper` 和治理图 Retriever,适配已有
+   PostgreSQL/pgvector 与 Neo4j 数据模型。
+4. **LightRAG 以内部侧车服务运行。** DataOps 通过受限客户端调用 LightRAG;
+   浏览器、外部调用方和模型 Agent 不直接访问 LightRAG API 或 WebUI。
+5. **LightRAG 只返回检索上下文。** 查询使用 `only_need_context` 语义,最终
+   DeepSeek 提示词、回答、引用和无答案判断由 DataOps 生成。
+6. **两类图严格区分。**
+   - 现有 Neo4j 治理图是人工/业务流程维护的源真相,由 DataOps
+     `GovernanceGraphRetriever` 只读查询。
+   - LightRAG 抽取图是可重建的检索投影,不能写入现有治理节点、关系或约束。
+7. **LightRAG 存储隔离。** PostgreSQL 使用独立数据库和最小权限账号;
+   本地 Neo4j Community 使用独立 `lightrag-neo4j` 服务和卷。生产环境可以使用
+   独立 Neo4j 数据库/集群,但不能只依赖与治理图共库的标签约定作为安全边界。
+8. **先授权后检索,再重新授权。** DataOps 根据用户角色和业务域授权限定查询
+   空间;候选返回后按治理对象 UID、版本和业务域再次过滤。无法映射到合法来源
+   的 LightRAG 上下文不得进入最终提示词。
+9. **标准链路始终可独立运行。** LightRAG、Neo4j 或 reranker 故障时,系统按
+   受控降级策略保留精确检索和 pgvector 检索;LightRAG 不是可用性单点。
+10. **索引发布采用版本化投影。** 新文档版本只有在分块和 embedding 完成后才
+    原子切换为 active;LightRAG 投影异步完成,失败不回滚已可用的标准索引。
+11. **模型职责保持分离。** Qwen 负责 embedding;独立 reranker 负责精排;
+    DeepSeek 负责最终问答。LightRAG 抽取模型使用独立配置,不得隐式改变
+    DataOps 的默认模型职责。
+12. **效果门禁优先于产品宣传。** LlamaIndex-only 是基线,只有在 DataOps
+    黄金问题集上证明多跳召回有实质提升且权限测试为零泄漏时,LightRAG 路径才
+    能从影子模式提升为正式查询路径。
+
+## 目标架构
+
+```mermaid
+flowchart LR
+    USER["管理员 / 编辑者 / 查看者"] --> API["DataOps Knowledge API"]
+    API --> ACCESS["KnowledgeAccessContext\n角色 + 业务域 + 对象范围"]
+    ACCESS --> ROUTER["确定性 Query Router"]
+
+    subgraph Standard["LlamaIndex 主链路(Flask 内)"]
+        EXACT["精确 / 别名 / 词法 Retriever"]
+        VECTOR["DataOps pgvector Retriever"]
+        GRAPH["治理 Neo4j Retriever"]
+        FUSION["RRF 融合"]
+    end
+
+    ROUTER --> EXACT
+    ROUTER --> VECTOR
+    ROUTER --> GRAPH
+    EXACT --> FUSION
+    VECTOR --> FUSION
+    GRAPH --> FUSION
+
+    ROUTER -->|关系 / 全局 / 多跳| LRCLIENT["LightRAG Client"]
+    LRCLIENT --> LRSVC["LightRAG 内部侧车"]
+    LRSVC --> LRPG["独立 LightRAG PostgreSQL"]
+    LRSVC --> LRNEO["独立 LightRAG Neo4j 投影"]
+
+    FUSION --> MERGE["候选合并 + 来源重新授权"]
+    LRCLIENT --> MERGE
+    MERGE --> RERANK["Cross-Encoder Reranker"]
+    RERANK --> QA["DataOps Answer Synthesizer"]
+    QA --> DEEPSEEK["DeepSeek"]
+    QA --> RESULT["答案 + 对象 UID + 版本 + 引用"]
+```
+
+## 组件所有权
+
+| 能力 | 责任组件 | 源真相 |
+|---|---|---|
+| 用户、角色、业务域授权 | DataOps RBAC | PostgreSQL |
+| 治理对象与血缘 | DataOps 治理 API | Neo4j |
+| 规范化文档与分块 | DataOps Knowledge Indexer | PostgreSQL |
+| 向量及 embedding 版本 | DataOps Knowledge Indexer | PostgreSQL/pgvector |
+| 主检索编排 | LlamaIndex 适配层 | 无独立源数据 |
+| 图增强抽取与检索 | LightRAG | 可重建投影 |
+| LightRAG 图 | LightRAG | 独立 Neo4j |
+| 候选融合、重排和无答案判断 | DataOps Retrieval Pipeline | 运行时 |
+| 最终生成与引用 | DataOps Answer Synthesizer | PostgreSQL 来源映射 |
+| 同步和补偿 | DataOps Outbox + Projection Worker | PostgreSQL |
+| 评测、指标与查询审计 | DataOps | PostgreSQL/监控系统 |
+
+## LlamaIndex 集成边界
+
+LlamaIndex 只使用以下抽象能力:
+
+- 将 `governance_chunks` 映射为带稳定 `node_id` 和 metadata 的 Node;
+- 将已有 SQL 检索封装为 VectorStore/Retriever;
+- 并行运行词法、向量和治理图 Retriever;
+- 使用确定性融合器和可插拔 Node Postprocessor/reranker;
+- 将已授权 Node 交给 DataOps 的回答合成器。
+
+以下能力不由 LlamaIndex 持久化或决定:
+
+- 用户、角色、业务域授权;
+- active/superseded/deleted 版本状态;
+- 治理对象 UID 和跨存储一致性;
+- embedding 模型切换和索引发布;
+- 对外 API、错误码、审计和数据保留周期。
+
+## LightRAG 集成边界
+
+LightRAG 使用官方服务接口或由 DataOps 封装的兼容网关,接口至少包含:
+
+- 插入规范化文档;
+- 查询投影状态;
+- 使用 `mix`/`hybrid` 模式查询上下文;
+- 按外部文档 ID 删除或重建;
+- 健康检查。
+
+所有调用必须携带:
+
+- `correlation_id`;
+- DataOps `object_uid`、`object_version` 和 `content_hash`;
+- 不包含用户名、连接串、密钥或未授权附件正文的规范化内容;
+- 可验证的 workspace/index generation。
+
+LightRAG 返回内容只有满足以下条件才可使用:
+
+1. 能映射回 active 的 DataOps 文档和 chunk;
+2. 来源业务域在当前 `KnowledgeAccessContext` 内;
+3. 文档版本和当前 active 版本一致;
+4. 未超过上下文预算且通过 reranker/阈值;
+5. 不包含系统提示词、工具指令或其他不可作为证据的内容。
+
+## 安全与权限
+
+### 业务域授权
+
+新增持久化的用户—业务域授权关系。管理员可以拥有 `*` 范围;其他用户只读取被
+授予的业务域。角色权限决定“能否使用知识库”,业务域授权决定“能看到什么”。
+
+### 双重过滤
+
+1. SQL/Neo4j 查询在召回前应用业务域和对象类型过滤。
+2. 融合后按 canonical source 再过滤一次。
+3. LightRAG 查询只路由到允许的安全分区;返回上下文仍需重新授权。
+4. 最终 Prompt 只包含重新授权后的 canonical chunks。
+
+### Prompt Injection
+
+治理正文、附件、LightRAG 实体描述和关系说明全部视为不可信数据。最终系统
+Prompt 明确禁止执行证据文本中的指令;候选内容只放在结构化 evidence 区域。
+
+## 一致性与失败策略
+
+```mermaid
+stateDiagram-v2
+    [*] --> pending
+    pending --> canonical_ready: 文档、分块、embedding 成功
+    pending --> failed: 构建或 embedding 失败
+    canonical_ready --> projecting: 创建 LightRAG 投影任务
+    projecting --> ready: LightRAG 投影完成并核验
+    projecting --> degraded: LightRAG 超时或失败
+    degraded --> projecting: 有上限重试 / 人工重放
+    ready --> stale: 源版本或模型 profile 变化
+    stale --> pending: 重建新 generation
+```
+
+- canonical index 发布失败:旧 active 版本继续提供服务。
+- LightRAG 失败:标准 LlamaIndex 链路继续工作,响应标记
+  `graph_retrieval=degraded`。
+- Neo4j 治理图失败:保留精确和向量检索。
+- reranker 失败:使用 RRF 排序结果并降低置信度。
+- DeepSeek 失败:`search` 仍返回来源;`ask` 返回模型不可用状态和已检索来源,
+  不伪造答案。
+- 删除对象:先发布 DataOps tombstone,使查询立即不可见,再异步删除 LightRAG
+  投影;每日巡检清理孤儿投影。
+
+## 不采用的方案
+
+### 同时使用 LlamaIndex 和 Haystack
+
+拒绝。两者会引入重复 Document、Retriever、Pipeline、回调和配置抽象,增加维护
+和排障成本。
+
+### 让 LightRAG 直接使用治理 Neo4j
+
+首期拒绝。LightRAG 的实体/关系抽取模型与现有治理模型不同,直接写入会破坏源
+真相、约束和审计边界。
+
+### 让 LightRAG 直接回答用户
+
+拒绝。LightRAG 无法替代 DataOps 的业务域授权、版本核验、统一引用和无答案
+策略。
+
+### 同步调用 LightRAG 完成索引后再提交治理变更
+
+拒绝。外部模型和图抽取延迟不应扩大治理写事务;使用 Outbox 和可重建投影实现
+最终一致。
+
+## 结果
+
+正面结果:
+
+- 复用已有 pgvector、Neo4j、Qwen、DeepSeek、RBAC 和 Outbox。
+- 主检索链路保持可测试、可降级、可替换。
+- LightRAG 的多跳能力不会污染治理源图。
+- 框架升级或 LightRAG 退役不改变 DataOps 领域模型。
+
+成本与限制:
+
+- 需要建设 LlamaIndex 适配器,而不是直接使用其默认表。
+- LightRAG 会维护一份可重建的抽取图,产生额外存储和模型成本。
+- 业务域安全分区、来源映射和删除补偿必须由 DataOps 实现。
+- embedding 维度或 LightRAG 存储实现变化需要新 generation 全量重建,不能原地
+  混用。
+
+详细实施工作包、Schema、API、验收门槛和回滚点见
+[LlamaIndex + LightRAG 数据治理知识库实施计划](../superpowers/plans/2026-07-20-llamaindex-lightrag-knowledge-base.md)。
+
+## 上游依据
+
+- [LlamaIndex OSS README](https://github.com/run-llama/llama_index/blob/main/README.md)
+- [LightRAG Core 编程与存储隔离](https://github.com/HKUDS/LightRAG/blob/main/docs/ProgramingWithCore.md)
+- [LightRAG API Server](https://github.com/HKUDS/LightRAG/blob/main/docs/LightRAG-API-Server.md)
+- [pgvector 混合检索与索引说明](https://github.com/pgvector/pgvector)

+ 1565 - 0
docs/superpowers/plans/2026-07-20-llamaindex-lightrag-knowledge-base.md

@@ -0,0 +1,1565 @@
+# LlamaIndex + LightRAG 数据治理知识库实施计划
+
+> 状态:技术方案已确认,尚未进入代码实施。
+>
+> 目标:在不替换 DataOps 控制面、治理 Neo4j 和现有 PostgreSQL 的前提下,
+> 交付权限安全、可追溯、可评测、可降级,并能随治理事实变化进行知识点级
+> 增量更新的治理知识库。
+>
+> 2026-07-22 修订:将知识点版本、语义 Diff、依赖影响传播、增量索引、缓存失效
+> 和原子发布纳入正式实施范围;不再把“对象级文档重建”视为动态更新的完整实现。
+
+## 1. 交付结论
+
+本计划采用:
+
+- LlamaIndex:Flask 内部唯一 RAG 主框架;
+- LightRAG:内部图增强检索侧车;
+- PostgreSQL/pgvector:规范化文档、分块、向量和控制状态;
+- 现有 Neo4j:治理对象与血缘源真相,只读检索;
+- 独立 LightRAG Neo4j:可重建的抽取图;
+- Qwen:embedding;
+- 独立 reranker:候选精排;
+- DeepSeek:最终问答。
+
+知识动态更新采用:
+
+- 稳定 `point_key`:标识跨版本不变的知识语义位置;
+- `knowledge_points`:保存知识点版本和有效期;
+- `knowledge_point_dependencies`:保存治理事实和确定性规则形成的依赖;
+- `knowledge_change_sets`:记录一次变更的 Diff、影响范围、发布和回滚状态;
+- 语义快照 + Diff:区分 `added`、`modified`、`deleted`、`unchanged`;
+- 有边界的影响传播:只重建受影响的 chunk、embedding、LightRAG 投影和缓存;
+- prepare/validate/activate:新版本校验通过后原子切换,失败时保留旧 active 版本。
+
+不采用:
+
+- Haystack 与 LlamaIndex 双框架;
+- LightRAG WebUI 作为 DataOps 用户入口;
+- LightRAG 直接生成最终用户答案;
+- LightRAG 直接写入现有治理 Neo4j;
+- 新增 Milvus、Elasticsearch、Qdrant 或 Redis 作为首期必需依赖。
+
+## 2. 当前基线与必须补齐的缺口
+
+### 已存在
+
+- `deploy/docker/docker-compose.yml` 已使用 PostgreSQL 16 + pgvector 和 Neo4j 5。
+- `20260716_40_governance_knowledge.py` 已创建文档、分块和同步任务表。
+- `app/core/knowledge/document_builder.py` 已提供确定性 JSON 文档和基础脱敏。
+- `app/services/embedding/qwen.py` 已提供 Qwen Embedding 客户端。
+- `app/core/events/outbox.py` 已提供 Outbox、幂等消费和失败状态。
+- `app/core/system/permissions.py` 已提供管理员、编辑者、查看者的服务端 RBAC。
+- 前端 `/knowledge-base-product` 已保留“数据治理知识库”入口。
+
+### 缺口
+
+1. 当前文档是紧凑 JSON,固定按 1200 字符切分,可能切断字段和关系语义。
+2. `governance_chunks` 没有词法索引、结构化 metadata、section path 和 token 数。
+3. 没有向量索引 generation,模型切换无法安全影子重建。
+4. 没有检索、重排、引用和回答实现。
+5. 没有治理对象变更事件的完整生产者。
+6. 当前 Outbox 是全局 claim 状态,不能假设同一个事件会被多个独立消费者依次
+   处理。
+7. Web 身份只有角色,没有持久化的用户—业务域授权。
+8. 没有 LightRAG 投影状态、来源映射、删除补偿和隔离存储。
+9. 没有黄金问题集、离线评测和发布门禁。
+10. 没有稳定知识点模型,无法判断治理对象内部具体哪些事实发生变化。
+11. 没有知识点依赖和影响传播,字段、标准、指标、血缘之间的联动只能全量重建或
+    留下陈旧内容。
+12. 没有 change set、缓存依赖和知识新鲜度契约,不能证明一次动态变更已经完整发布。
+
+## 3. 实施原则
+
+1. **源真相不变。** 治理对象在 Neo4j,身份/授权/索引控制状态在 PostgreSQL,
+   LightRAG 只保存投影。
+2. **先过滤,再召回,再复核。** 权限不依赖前端和 Prompt。
+3. **最终回答只有一个出口。** DataOps Answer Synthesizer 负责 DeepSeek 和引用。
+4. **旧索引持续可用。** 新版本或新模型失败不覆盖 active generation。
+5. **外部组件可关闭。** 关闭 LightRAG 后仍有完整的标准检索和问答闭环。
+6. **所有外部写入幂等。** 使用稳定对象 UID、版本、内容哈希和 generation。
+7. **先评测后放量。** LightRAG 先影子运行,不因接入完成就默认进入正式答案。
+8. **知识点是最小变更单元。** 对象和文档仍是来源及授权边界,但更新、影响分析、
+   缓存失效和新鲜度判断下沉到稳定 `point_key`。
+9. **变化先 Diff 再构建。** 相同知识点内容不重复 embedding;删除和权限收紧先使
+   canonical 内容不可见,再异步清理外部投影。
+10. **影响传播必须有界。** 依赖传播限定关系类型、最大 hop 和最大对象/知识点数;
+    超过阈值时升级为新 generation 的影子重建。
+11. **发布状态可证明。** 每次变化都形成 change set,只有 canonical 产物、权限和
+    引用通过校验后才标记 active;LightRAG 等异步投影单独报告 ready/degraded,部分
+    成功不能被报告为投影完成。
+
+## 4. 运行时架构
+
+```mermaid
+flowchart TB
+    subgraph Write["索引写链路"]
+        SOURCE["Neo4j / PostgreSQL 治理对象"] --> EVENT["governance.* Outbox 事件"]
+        EVENT --> SNAP["规范化语义快照"]
+        SNAP --> DIFF["知识点级 Diff"]
+        DIFF --> IMPACT["有界依赖影响传播"]
+        IMPACT --> INDEXER["Knowledge Indexer"]
+        INDEXER --> DOC["知识点 + 结构化分块"]
+        DOC --> EMB["仅对变化内容生成 Qwen Embedding"]
+        EMB --> CANON["Canonical Index\nPostgreSQL + pgvector"]
+        CANON --> ACTIVATE["校验 + 原子切换"]
+        ACTIVATE --> INVALIDATE["精准缓存失效"]
+        CANON --> PROJ["knowledge_index_projections"]
+        PROJ --> LRWORKER["LightRAG Projection Worker"]
+        LRWORKER --> LRSVC["LightRAG Service"]
+        LRSVC --> LRPG["LightRAG PostgreSQL"]
+        LRSVC --> LRNEO["LightRAG Neo4j"]
+    end
+
+    subgraph Read["查询读链路"]
+        API["/api/knowledge"] --> ACCESS["KnowledgeAccessContext"]
+        ACCESS --> PIPE["LlamaIndex Retrieval Pipeline"]
+        PIPE --> LEX["Lexical / Alias"]
+        PIPE --> VEC["pgvector"]
+        PIPE --> GRA["治理 Neo4j"]
+        PIPE --> LRC["LightRAG Client"]
+        LEX --> RRF["RRF"]
+        VEC --> RRF
+        GRA --> RRF
+        LRC --> AUTHZ["Canonical Source Re-authorization"]
+        RRF --> AUTHZ
+        AUTHZ --> RERANK["Reranker"]
+        RERANK --> QA["DeepSeek Answer Synthesizer"]
+    end
+```
+
+写链路中的 canonical active 版本是查询可见性的唯一开关。LightRAG 投影可以在
+canonical 发布后异步完成;但任何 LightRAG 上下文在进入答案前仍必须映射到当前
+active 的 `point_key`、来源对象和版本。
+
+## 5. 数据模型
+
+### 5.1 新迁移
+
+建议新增:
+
+`migrations/versions/20260720_100_llamaindex_lightrag_knowledge.py`
+
+- `revision = "20260720_100"`
+- `down_revision = "20260719_90"`
+- V100 是 Alembic revision,不是产品版本。
+
+### 5.2 用户—业务域授权
+
+新增 `user_business_domain_grants`:
+
+| 字段 | 说明 |
+|---|---|
+| `user_id UUID` | FK `users.id` |
+| `business_domain_uid UUID` | 稳定治理 UID |
+| `grant_type VARCHAR(20)` | `read` / `manage` |
+| `granted_by UUID` | 管理员 |
+| `created_at TIMESTAMPTZ` | 授权时间 |
+
+约束:
+
+- 主键 `(user_id, business_domain_uid, grant_type)`;
+- `admin` 可解析为 `*`,但不写伪造的全局业务域 UID;
+- 删除用户时级联删除授权;
+- 非管理员没有授权记录时返回空范围,而不是默认全量。
+
+### 5.3 知识点、版本与有效期
+
+新增 `knowledge_points`。一行表示一个知识点的一个版本,不把覆盖更新当作版本管理:
+
+| 字段 | 说明 |
+|---|---|
+| `id UUID` | 知识点版本 ID |
+| `point_key VARCHAR(500)` | 跨源版本稳定的语义位置标识 |
+| `point_revision BIGINT` | 同一 `point_key` 内单调递增的知识点版本 |
+| `source_type VARCHAR(50)` | `BusinessDomain` / `DataFlow` / `DataMeta` / `DataStandard` / `Label` |
+| `source_uid UUID` | 来源治理对象稳定 UID |
+| `source_revision BIGINT` | 来源对象单调版本 |
+| `semantic_path VARCHAR(500)` | 对象内部字段或关系路径 |
+| `content TEXT` | 脱敏、规范化后的知识内容 |
+| `content_hash CHAR(64)` | 规范化内容 SHA-256 |
+| `metadata JSONB` | 名称、关系端点、权限范围和 source locator |
+| `status VARCHAR(20)` | `building` / `active` / `superseded` / `deleted` / `failed` |
+| `valid_from/valid_to TIMESTAMPTZ` | 业务有效期;`valid_to` 可空 |
+| `created_at/activated_at TIMESTAMPTZ` | 构建与发布时刻 |
+
+约束和索引:
+
+- `UNIQUE(point_key, point_revision)`;
+- 对 `status='active'` 建部分唯一索引,保证同一 `point_key` 最多一个 active 版本;
+- `(source_type, source_uid, source_revision)` 普通索引;
+- `(content_hash)` 普通索引,用于复用未变化内容;
+- 删除使用 `deleted` tombstone,审计保留期内不物理删除版本历史。
+
+`source_revision` 表示来源对象版本,`point_revision` 表示知识点自身版本。一个对象
+revision 可以同时改变多个 point;依赖传播只要求重建某个 point 的派生产物时,可以
+保留其 point revision,并通过新的 chunk hash/generation 体现派生索引变化。
+
+`point_key` 只由稳定 UID、固定语义路径和稳定关系类型构成,不包含显示名称、数组
+下标、文本内容或内容哈希。例如:
+
+```text
+BusinessDomain/{domain_uid}/definition
+DataFlow/{flow_uid}/owner
+DataFlow/{flow_uid}/reads_from/{metadata_uid}
+DataMeta/{table_uid}/fields/{field_uid}/definition
+DataStandard/{standard_uid}/rules/{rule_uid}
+```
+
+如果源系统没有字段/规则的稳定 UID,必须先建立确定性 surrogate key 和迁移映射;
+不得用列表位置生成 `point_key`,否则重排会被误判为批量删除与新增。
+
+### 5.4 知识点依赖、Change Set 与缓存依赖
+
+新增 `knowledge_point_dependencies`:
+
+| 字段 | 说明 |
+|---|---|
+| `from_point_key` | 依赖发起方 |
+| `to_point_key` | 被依赖知识点 |
+| `relation_type` | `uses` / `defines` / `derived_from` / `governs` / `lineage` |
+| `source` | `governance` / `deterministic_rule` |
+| `generation` | 关系所属 generation |
+| `status` | `active` / `superseded` / `deleted` |
+
+约束:
+
+- 主键 `(from_point_key, to_point_key, relation_type, source, generation)`;
+- `governance` 和 `deterministic_rule` 可驱动正式影响传播;
+- 传播规则必须配置关系白名单,禁止沿任意抽取边无限扩散。
+
+LightRAG 模型抽取关系继续只保存在隔离的 LightRAG 图和投影诊断中,不写入
+`knowledge_point_dependencies`。这样依赖传播的输入始终来自治理事实或确定性代码,
+不会把模型推断边升级成 canonical 依赖。
+
+新增 `knowledge_change_sets`:
+
+| 字段 | 说明 |
+|---|---|
+| `id UUID` / `correlation_id UUID` | 变更和全链路追踪标识 |
+| `source_type/source_uid/source_revision` | 来源对象与目标版本 |
+| `change_type` | `create` / `update` / `delete` / `permission` / `rebuild` |
+| `source_snapshot_hash` | 本次规范化快照哈希 |
+| `added/modified/deleted_count` | 直接 Diff 统计 |
+| `impacted_point_count` | 依赖传播后的影响数量 |
+| `impact_truncated BOOLEAN` | 是否因边界升级为 generation 重建 |
+| `status` | `pending` / `diffed` / `building` / `validating` / `canonical_active` / `projecting` / `complete` / `degraded` / `failed` / `rolled_back` |
+| `target_generation` | 目标索引 generation |
+| `last_error` | 脱敏错误与阶段 |
+| `created_at/activated_at` | 生命周期 |
+
+新增 `knowledge_change_items`,按 `change_set_id + point_key` 保存:
+
+- `change_kind`:`added` / `modified` / `deleted` / `impacted`;
+- old/new point version 和 content hash;
+- 影响来源 `caused_by_point_key` 与传播 hop;
+- canonical、embedding、cache、LightRAG 各阶段状态;
+- 重试次数和脱敏错误。
+
+新增 `knowledge_cache_dependencies`:
+
+| 字段 | 说明 |
+|---|---|
+| `cache_key_hash` | 不记录原始查询文本的缓存键哈希 |
+| `point_key` | 回答或检索结果依赖的知识点 |
+| `point_revision` | 生成缓存时使用的知识点版本 |
+| `generation` | 索引 generation |
+| `expires_at` | 最大生存时间 |
+
+任何 `modified`、`deleted`、权限收紧或 active generation 切换都按 `point_key`
+删除相关缓存;依赖记录缺失时必须失效整个业务域缓存,不能继续返回无法证明新鲜度的
+结果。
+
+### 5.5 规范化分块
+
+扩展 `governance_chunks`:
+
+| 字段 | 说明 |
+|---|---|
+| `chunk_kind` | `summary`、`definition`、`field`、`relation`、`attachment` |
+| `section_path` | 标题/字段路径 |
+| `metadata JSONB` | 对象类型、别名、责任人、业务域、关系端点等 |
+| `token_count` | 使用固定 tokenizer 计算 |
+| `lexical_text` | 名称、编码、别名和正文的规范化检索文本 |
+| `search_vector TSVECTOR` | PostgreSQL 词法索引 |
+| `source_locator JSONB` | Neo4j UID、MinIO object key、页码/表格定位 |
+
+索引:
+
+- `GIN(search_vector)`;
+- `GIN(metadata jsonb_path_ops)`;
+- `(document_id, chunk_no)` 保留唯一;
+- `document_id` 普通索引;
+- 常用范围 `(chunk_kind)` 与文档上的
+  `(business_domain_uid, object_type, status)` 联合索引。
+
+首期中文精确检索不只依赖 PostgreSQL 自带分词:
+
+- 对对象名、英文名、表名、字段名、编码和显式别名建立 normalized alias;
+- 精确匹配、前缀匹配和 `pg_trgm` 召回独立计分;
+- 语义召回由 pgvector 负责;
+- 是否引入 `zhparser` 必须经过独立镜像、许可证和部署验证,不作为首期前置条件。
+
+每个 chunk 新增:
+
+- `primary_point_key`:该 chunk 的主要知识点;
+- `point_keys JSONB`:chunk 覆盖的全部知识点;
+- `point_set_hash`:知识点集合和版本哈希;
+- `change_set_id`:生成本 chunk 的 change set。
+
+同一知识点可以映射到多个 chunk,一个 chunk 也可以包含多个紧密相关知识点;但每个
+chunk 必须能反查其知识点依赖,支持精准重建、缓存失效和引用新鲜度校验。
+
+### 5.6 Embedding profile 与 generation
+
+新增 `knowledge_embedding_profiles`:
+
+| 字段 | 说明 |
+|---|---|
+| `id UUID` | profile ID |
+| `provider` | `qwen` |
+| `model` | 模型名 |
+| `dimension` | 首期固定 1024 |
+| `distance` | `cosine` |
+| `status` | `building`、`active`、`retired`、`failed` |
+| `config_hash` | 不包含密钥的配置哈希 |
+| `created_at/activated_at` | 生命周期 |
+
+新增 `knowledge_chunk_embeddings`:
+
+| 字段 | 说明 |
+|---|---|
+| `id UUID` | embedding ID |
+| `chunk_id UUID` | FK `governance_chunks.id` |
+| `profile_id UUID` | FK profile |
+| `embedding vector(1024)` | 向量 |
+| `embedding_hash` | 输入、模型和维度哈希 |
+| `created_at` | 创建时间 |
+
+约束和索引:
+
+- `UNIQUE(chunk_id, profile_id)`;
+- active profile 使用 HNSW cosine 索引;
+- 小语料验收阶段保留 exact scan 基线;
+- ANN 与业务域过滤组合必须测 Recall;必要时启用 pgvector iterative scan 或
+  oversampling,不能只看延迟。
+
+现有 `governance_chunks.embedding*` 字段首期保留兼容,不在同一迁移中删除。
+完成双读、回填和切换后再单独下线。
+
+维度变化不允许写入同一个 `vector(1024)` 表。必须建立新维度的 shadow 表和新
+profile,完整重建并切换。
+
+`knowledge_chunk_embeddings.embedding_hash` 必须包含规范化 chunk hash、模型、维度
+和 tokenizer profile。知识点集合与内容均未变化时复用现有 embedding;只改变责任人
+等独立知识点时,不重算无关 definition/relation chunk。
+
+### 5.7 外部引擎投影
+
+新增 `knowledge_index_projections`:
+
+| 字段 | 说明 |
+|---|---|
+| `id UUID` | 投影记录 |
+| `document_id UUID` | canonical document |
+| `change_set_id UUID` | 触发投影的 change set |
+| `engine` | `canonical_vector` / `lightrag` |
+| `generation` | 索引 generation |
+| `workspace` | 安全分区 |
+| `external_document_id` | LightRAG 幂等文档 ID |
+| `content_hash` | 投影输入哈希 |
+| `status` | `pending`、`processing`、`ready`、`failed`、`deleting`、`deleted` |
+| `attempts/available_at` | 有上限重试 |
+| `last_error` | 脱敏错误 |
+| `updated_at` | 健康与巡检 |
+
+唯一键:
+
+`(document_id, engine, generation, workspace)`
+
+LightRAG `external_document_id` 固定使用:
+
+`dataops:{object_type}:{object_uid}:v{object_version}:{content_hash前12位}`
+
+对支持知识点级外部 ID 的适配层,首选:
+
+`dataops:point:{point_key的SHA256前24位}:p{point_revision}:{content_hash前12位}`
+
+如果 LightRAG 只能以文档为最小删除单位,则按“来源对象 + 业务域 + generation”维护
+投影包:任一知识点变化时删除旧包并重插该对象的当前 active 知识点。该限制必须通过
+K0 契约测试确认,不能假设底层支持不存在的局部更新语义。
+
+### 5.8 查询审计与评测
+
+新增:
+
+- `knowledge_query_audits`
+- `knowledge_evaluation_sets`
+- `knowledge_evaluation_cases`
+- `knowledge_evaluation_runs`
+- `knowledge_evaluation_results`
+
+查询审计默认只保存:
+
+- query hash,不保存完整问题正文;
+- 用户、角色、授权业务域摘要;
+- 路由模式和各 Retriever 命中数量;
+- 最终引用的 object UID/version;
+- 最终引用的 `point_key`、point revision、source update time 和 index generation;
+- 延迟、模型、token、降级状态和 correlation ID。
+
+如需保存问题/答案样本,必须由管理员显式标记并进入有保留期限的评测集。
+
+## 6. 规范化文档协议
+
+替换紧凑 JSON + 固定字符切割,按对象类型使用确定性模板。
+
+每个 canonical document 至少包含:
+
+```yaml
+object_type: DataFlow
+object_uid: 019...
+object_version: 7
+object_name: 客户主数据同步
+aliases:
+  - customer_master_sync
+business_domain_uid: 019...
+owner: 数据治理组
+source_updated_at: 2026-07-20T...
+definitions:
+  purpose: ...
+  inputs: ...
+  outputs: ...
+relations:
+  - type: READS_FROM
+    target_uid: 019...
+    target_name: 客户表
+knowledge_points:
+  - point_key: DataFlow/019.../purpose
+    semantic_path: definitions/purpose
+    content_hash: sha256:...
+  - point_key: DataFlow/019.../reads_from/019...
+    semantic_path: relations/READS_FROM/019...
+    content_hash: sha256:...
+permission_scope:
+  business_domains:
+    - 019...
+```
+
+构建规则:
+
+1. 字段、关系和别名排序稳定;
+2. 时间统一 UTC ISO-8601;
+3. secret key 使用递归、大小写不敏感和模式匹配脱敏;
+4. 每类对象使用黄金 fixture;
+5. summary、definition、field 和 relation 分块不跨类型切断;
+6. 超长字段在 token 边界切分并保留父标题和对象摘要;
+7. 每个 chunk 都携带 object UID、version、domain、kind 和 source locator;
+8. 每个知识点携带稳定 `point_key`、semantic path、content hash 和依赖端点;
+9. 同一来源快照产生相同 document、point set 和 chunk hash;
+10. 只改变字段顺序、JSON 键顺序或无语义格式时,Diff 必须为 `unchanged`;
+11. 显示名称变化不改变已有 `point_key`,但名称知识点内容和依赖它的检索别名会更新;
+12. point/chunk 的 permission scope 从 canonical 来源计算,不接受模型抽取值。
+
+每类对象必须实现 `KnowledgePointBuilder`,输出排序稳定的:
+
+```python
+KnowledgeSnapshot(
+    source_type=...,
+    source_uid=...,
+    source_revision=...,
+    source_snapshot_hash=...,
+    permission_scope=...,
+    points=tuple[KnowledgePointDraft, ...],
+    dependencies=tuple[KnowledgeDependencyDraft, ...],
+)
+```
+
+Builder 是确定性领域代码,不使用 LLM 判断 point identity。LLM 只能在 LightRAG
+投影中抽取辅助关系,不能生成 canonical `point_key`、权限或版本。
+
+## 7. 同步与一致性
+
+### 7.1 事件类型
+
+治理写路径在同一业务事务中产生:
+
+- `governance.business_domain.changed`
+- `governance.dataflow.changed`
+- `governance.metadata.changed`
+- `governance.standard.changed`
+- `governance.label.changed`
+- `governance.object.deleted`
+
+payload 只包含:
+
+- object type/UID/version;
+- source update time;
+- correlation ID;
+- 变更类型;
+- 可选的 changed field/relationship hints,仅用于优化,不能作为完整 Diff 的事实源;
+- 不包含完整附件或密钥。
+
+事件处理规则:
+
+- 以 `(source_type, source_uid, source_revision)` 幂等;
+- revision 小于当前 active revision 的乱序事件记录为 stale 并跳过,不允许回退;
+- revision 相同但 snapshot hash 不同视为源版本协议错误,进入人工检查;
+- 事件 hint 与实际语义快照不一致时以重新读取的源快照为准。
+
+### 7.2 单消费者协调
+
+当前 Outbox 的 event status 是全局状态,不能让 canonical indexer 与 LightRAG
+各自 claim 同一个事件。
+
+首期采用:
+
+1. `governance.*` 只注册一个 `KnowledgeIndexHandler`;
+2. Handler 创建或恢复一个 `knowledge_change_sets`,执行快照、Diff、影响分析和
+   canonical 发布;
+3. 同一 PostgreSQL 事务写 change items、缓存失效任务和
+   `knowledge_index_projections(status='pending')`;
+4. 独立 LightRAG Projection Worker 只 claim projection 表;
+5. 缓存失效 worker 只 claim cache invalidation 任务,删除操作和权限收紧使用高优先级;
+6. 不把当前 Outbox 伪装成多订阅消息总线。
+
+同一 `(source_type, source_uid)` 的 Diff 与 activate 必须串行。实现使用数据库行锁或
+transaction-scoped advisory lock;锁内再次读取当前 active source revision,防止两个
+worker 分别基于同一旧快照发布出相互覆盖的版本。不同来源对象可以并行处理。
+
+未来若其他业务也需要 fan-out,再独立增加 `outbox_deliveries`,不在本阶段扩大。
+
+### 7.3 语义快照与知识点 Diff
+
+`KnowledgeIndexHandler` 对每个事件执行:
+
+1. 在一致性读取边界内重新读取治理对象、稳定子对象 UID、关系和权限范围;
+2. 使用对应 `KnowledgePointBuilder` 构建新 `KnowledgeSnapshot`;
+3. 读取该对象当前 active point set;
+4. 按 `point_key` 对比 old/new snapshot;
+5. 写入 change set 和 change items;
+6. 对 `unchanged` point 复用 active point/chunk/embedding;
+7. 对 `added`、`modified`、`deleted` 进入影响分析。
+
+Diff 判定:
+
+| 情况 | change kind | 后续动作 |
+|---|---|---|
+| 新快照有、旧快照无 | `added` | 新建 point、chunk、embedding 和投影 |
+| 两边都有、content/metadata/permission hash 变化 | `modified` | 建新版本,重建相关产物 |
+| 旧快照有、新快照无 | `deleted` | 准备 tombstone,删除相关产物 |
+| key 和所有语义 hash 相同 | `unchanged` | 复用,不调用 embedding |
+
+权限 hash 单独比较。权限扩大按普通修改发布;权限收紧进入高优先级安全路径,不等待
+LightRAG 或 embedding 完成后才禁止旧内容查询。
+
+### 7.4 有界依赖影响传播
+
+直接 Diff 完成后,从 `added`、`modified`、`deleted` point 沿
+`knowledge_point_dependencies` 计算受影响集合:
+
+1. 只沿配置白名单中的确定性关系传播;
+2. 默认最大 hop 为 3,具体值由黄金用例调优;
+3. 限制单 change set 最大知识点数和最大来源对象数;
+4. 每个 `impacted` item 记录根因 point、关系路径和 hop;
+5. 到达边界或发现循环时停止,不重复处理已访问 point;
+6. 超过阈值将 `impact_truncated=true`,为相关业务域创建新 generation 影子重建,
+   不发布不完整的局部结果。
+
+`impacted` 只表示“需要重新验证或重建”,不表示依赖方的治理事实已经变化。对依赖方:
+
+- 如果其 canonical 内容由该依赖确定性派生,重新读取依赖方来源并运行 point builder,
+  再次计算实际 Diff;
+- 如果只影响组合 chunk、检索别名、图路径或缓存,则保留 point revision,只重建对应
+  派生产物;
+- 禁止因为传播结果直接改写治理 Neo4j 或凭模型推断创建 canonical 事实。
+
+首期传播规则至少覆盖:
+
+- 字段定义/类型变化 → 引用字段的数据标准、DataFlow 输入输出说明;
+- 数据标准规则变化 → 绑定该标准的元数据定义和检索别名;
+- 血缘关系变化 → 对应 relation point、上下游 chunk 和图投影;
+- 业务域归属变化 → 该对象全部 point 的 permission scope、缓存和 workspace 投影;
+- 责任人变化 → owner point 和相关检索 chunk,不重建无关 definition/relation embedding。
+
+### 7.5 增量构建、校验与原子发布
+
+每个 change set 使用 `prepare -> validate -> activate`:
+
+#### Prepare
+
+1. 为 added/modified point 写 `building` 版本;
+2. 为 deleted point 准备 tombstone;
+3. 对 impacted point 重新验证 canonical 来源,只在实际 Diff 后创建新 point revision;
+4. 只重建 point set、依赖集合或检索表现发生变化的 chunks;
+5. 按 embedding hash 复用未变化向量,只批量生成缺失向量;
+6. 准备新 canonical document、chunk、embedding 和依赖边;
+7. 写 LightRAG 投影任务,但不把 projection ready 作为 canonical 可见性的前置条件。
+
+#### Validate
+
+至少检查:
+
+- point key 唯一、source revision 单调、point set hash 可复现;
+- 每个新 chunk 都能反查 active/building point 和 canonical source;
+- embedding profile、维度和覆盖率正确;
+- permission scope 来自服务端 canonical 来源;
+- 删除/修改后不存在仍指向旧 point revision 的待发布引用;
+- 影响传播未被静默截断;
+- change item 各阶段状态完整。
+
+#### Activate
+
+在单个 PostgreSQL 事务中:
+
+1. 将旧 active point/document/chunk 标记 `superseded` 或 `deleted`;
+2. 将新 point/document/chunk 标记 `active`;
+3. 更新 source active revision 和 point set hash;
+4. 创建/确认缓存失效任务和 LightRAG projection;
+5. 将 change set 标记 `canonical_active` 并提交;投影 worker 开始后转为 `projecting`,
+   异步投影完成后转为 `complete`,超过重试或 SLA 时转为 `degraded`,但不回滚已正确
+   发布的 canonical 版本。
+
+Qwen、校验或事务失败时,旧 active 版本保持不变,building 产物可重试或清理。禁止
+逐 point 提交后再补偿,因为这会暴露半新半旧的对象快照。
+
+### 7.6 删除、权限收紧与紧急撤销
+
+删除对象:
+
+1. 在 canonical 事务中将对象及其 active points 发布为 tombstone,查询立即不可见;
+2. 删除相关缓存依赖;
+3. projection 进入 `deleting`;
+4. LightRAG 按 point ID 或投影包 ID 删除;
+5. 删除成功标记 `deleted`,失败有上限重试并告警;
+6. 每日 audit 对孤儿 projection 重试或隔离。
+
+权限收紧、敏感级别提升和业务域移出使用相同的高优先级撤销通道:先在 canonical
+授权层拒绝访问并失效缓存,再异步修正 embedding metadata 和 LightRAG workspace。
+紧急撤销 SLA 需要在 K1D 确认;在 SLA 未验证前不得声称外部投影已实现实时删除。
+
+### 7.7 缓存失效与回答新鲜度
+
+检索结果缓存和答案缓存都必须记录 `point_key + point revision + generation` 依赖。
+
+- point modified/deleted:失效直接依赖缓存;
+- 影响传播:失效所有 impacted point 缓存;
+- permission change:按用户/角色/业务域安全范围失效;
+- generation 切换:失效旧 generation 缓存;
+- 依赖写入失败:回退为整个业务域缓存失效;
+- 高风险治理内容可以配置最大允许陈旧时间,超时后不返回旧缓存。
+
+首期若尚未实现跨 worker 的依赖失效广播,则关闭可跨请求复用的答案缓存;允许的短期
+进程内缓存必须把 generation/point set hash 纳入键并使用保守 TTL。不能先上线不可
+精准失效的长生命周期缓存,再依赖人工清理保证新鲜度。
+
+回答和引用响应增加:
+
+- `point_key`、`point_revision`;
+- `source_updated_at`;
+- `index_generation`;
+- `freshness_status`:`fresh` / `updating` / `degraded`;
+- 可选 `active_change_set_id`,仅管理员可见。
+
+`fresh` 表示引用 point set 已对应最新成功处理的 source revision;`updating` 表示存在
+更高 source revision 的未完成 change set,当前回答仍基于旧 active 快照;`degraded`
+表示巡检发现 source/canonical/projection 不一致,或无法证明缓存依赖完整。
+
+### 7.8 LightRAG 增量投影与 Generation 重建
+
+LightRAG 的实际更新粒度由 K0 契约测试决定:
+
+- 支持可靠 point/document delete:删除旧外部 ID,再插入新 active 内容;
+- 只支持文档级删除:重建该对象投影包;
+- 无法证明删除一致性:新建 workspace generation,影子构建、评测后整体切换;
+- embedding、抽取模型、抽取 Prompt、实体关系 Schema 变化:强制新 generation;
+- 影响传播超过阈值或跨业务域大规模重分区:强制新 generation。
+
+新 workspace 激活前必须验证 active point 覆盖率、孤儿来源数、删除残留、权限分区和
+黄金集结果。旧 workspace 保留到回滚窗口结束后再异步回收。
+
+### 7.9 每日全量巡检
+
+巡检比较:
+
+- Neo4j/PostgreSQL 源对象 UID、版本和 source snapshot hash;
+- canonical active document hash 和 point set hash;
+- 每个 active point 的 source revision、content hash 和有效期;
+- chunk 到 point 的映射完整性;
+- active embedding profile 覆盖率和陈旧 embedding;
+- LightRAG projection generation、hash、状态和孤儿外部 ID;
+- deleted/superseded point 的残留 chunk、缓存和投影;
+- 业务域授权与 point/document permission scope 的合法性;
+- 长时间停留在 pending/building/validating 的 change set。
+
+默认 report-only;只有显式 `--repair` 才修复派生数据差异,不删除源治理数据。
+repair 必须创建独立 change set,保留修复前后审计记录。
+
+## 8. LlamaIndex 主检索链路
+
+### 8.1 代码边界
+
+新增:
+
+```text
+app/core/knowledge/
+├── access.py
+├── contracts.py
+├── document_builder.py
+├── point_builder.py
+├── chunking.py
+├── diff.py
+├── impact.py
+├── publish.py
+├── cache_invalidation.py
+├── sync.py
+├── audit.py
+├── qa.py
+├── evaluation.py
+├── llamaindex/
+│   ├── node_mapper.py
+│   ├── vector_store.py
+│   └── synthesizer.py
+├── retrieval/
+│   ├── lexical.py
+│   ├── vector.py
+│   ├── governance_graph.py
+│   ├── fusion.py
+│   ├── rerank.py
+│   ├── router.py
+│   └── pipeline.py
+└── lightrag/
+    ├── client.py
+    ├── projection.py
+    └── health.py
+```
+
+### 8.2 KnowledgeAccessContext
+
+每次查询在 API 层构建不可变上下文:
+
+```python
+KnowledgeAccessContext(
+    subject_id=...,
+    roles=frozenset(...),
+    permissions=frozenset(...),
+    business_domain_uids=frozenset(...),
+    correlation_id=...,
+)
+```
+
+禁止 Retriever 自己从请求 JSON 接受任意业务域。客户端 filters 只能缩小服务端
+已计算范围,不能扩大范围。
+
+### 8.3 Retriever
+
+#### ExactLexicalRetriever
+
+用于:
+
+- 表名、字段名、对象编码;
+- 中文名、英文名和别名;
+- 前缀和轻微拼写差异。
+
+#### DataOpsVectorRetriever
+
+- 查询 active profile;
+- 在 SQL 中应用 active document、业务域和对象类型过滤;
+- exact scan 和 HNSW 路径均可配置;
+- 返回 canonical chunk ID、`point_keys`、point revisions 和 generation,不返回框架
+  生成的临时 ID。
+
+#### GovernanceGraphRetriever
+
+只读查询现有 Neo4j:
+
+- 上下游血缘;
+- 业务域—DataFlow—元数据关系;
+- 数据标准/标签关联;
+- 限定最大 hop、最大节点和最大关系数量;
+- 使用参数化 Cypher;
+- 仅返回稳定 UID,不依赖 Neo4j internal ID。
+
+#### LightRAGRetriever
+
+- 只对允许 workspace 调用;
+- 首期使用 `mix` 和 `only_need_context`;
+- 强制超时、最大上下文和 circuit breaker;
+- 把返回来源映射为当前 active canonical document/chunk/point;
+- 映射失败的上下文丢弃并计数。
+
+### 8.4 Query Router
+
+首期使用可测试的确定性规则,不用 LLM 决定权限或任意路由。
+
+| 模式 | 触发条件 | Retriever |
+|---|---|---|
+| `exact` | 编码、表名、字段名、显式引号 | lexical + vector |
+| `semantic` | 定义、含义、用途、负责人 | lexical + vector |
+| `relationship` | 上游、下游、依赖、关联、经过 | vector + governance graph |
+| `global` | 整体、主要主题、跨域总结 | vector + LightRAG |
+| `auto` | 服务端确定性分类 | 上述之一 |
+
+用户可请求更窄模式,但不能强制访问未授权 LightRAG workspace。
+
+### 8.5 融合和重排默认值
+
+初始可调参数:
+
+- lexical top 20;
+- vector top 40;
+- governance graph top 20;
+- LightRAG context top 20;
+- RRF `k=60`;
+- RRF 后保留 30;
+- reranker 后保留 8;
+- 每对象最多 3 个 chunk;
+- 最终 evidence token 预算 8,000。
+
+这些只是起始配置,必须由黄金问题集调优,不能写死为“最佳参数”。
+
+### 8.6 无答案与引用
+
+回答必须满足:
+
+- 至少一个通过授权和版本核验的来源;
+- reranker/融合分数超过已校准阈值;
+- 每个事实引用 `object_uid + object_version + point_key + point_revision + chunk_id`;
+- 引用的 point、chunk 和 generation 在回答提交时仍为 active;
+- 来源内容不足时明确返回“不足以回答”;
+- 不允许模型生成不存在的引用。
+
+## 9. LightRAG 侧车
+
+### 9.1 部署
+
+新增 Compose 服务:
+
+- `lightrag`
+- `lightrag-projector`
+- `lightrag-neo4j`
+
+存储:
+
+- PostgreSQL:同一 PostgreSQL 集群内独立数据库 `dataops_lightrag` 和独立账号;
+- Neo4j:本地使用独立 Community 容器与卷;
+- 不使用 DataOps `public` schema;
+- 不使用治理 Neo4j 凭据;
+- 服务不暴露宿主机公网端口,只有后端/worker 内部网络可访问。
+
+镜像和 Python 包必须固定版本或 digest。不得使用 floating `latest`。
+
+### 9.2 Workspace 与权限
+
+workspace 使用稳定安全分区:
+
+`dataops-{tenant_or_global}-{business_domain_uid}-g{generation}`
+
+首期如果没有 tenant,固定使用 `global`,但仍按业务域分区。
+
+由于官方 LightRAG Server 的 workspace 是实例级配置,实施顺序为:
+
+1. PoC 只选择一个非敏感业务域;
+2. 验证共享服务是否能安全管理多个 workspace;
+3. 若不能按请求硬隔离,使用 DataOps LightRAG Gateway 管理 workspace 实例,
+   或按安全分区部署服务实例;
+4. 在多业务域隔离验收前,禁止将混合权限语料放入一个正式 workspace。
+
+### 9.3 模型配置
+
+- embedding 与 DataOps active Qwen profile 保持同模型、同维度;
+- extraction/query/final 模型分别配置;
+- LightRAG final generation 对 DataOps 请求禁用,只返回 context;
+- reranker 配置独立,失败可以由 DataOps 统一 reranker 补偿;
+- 任何模型切换创建新 generation/workspace,全量重建后再切换。
+
+### 9.4 接口适配
+
+`LightRAGClient` 对上层暴露稳定接口:
+
+```python
+insert(document_contract, idempotency_key) -> ProjectionReceipt
+delete(external_document_id, idempotency_key) -> DeleteReceipt
+query_context(query, workspace, mode, limits) -> list[ExternalEvidence]
+status(external_document_id) -> ProjectionStatus
+health() -> DependencyHealth
+```
+
+`insert` 输入必须包含 active point keys/revisions,`delete` 必须返回可核验的删除回执。
+如果官方接口无法证明旧内容已删除,client 将 projection 标记为 `unverified`,并触发
+新 generation 重建或人工隔离,不能把 HTTP 2xx 直接等同于语义删除完成。
+
+官方 REST 路径变化只影响 client,不进入领域代码和前端。
+
+## 10. Knowledge API
+
+新增蓝图:
+
+`app/api/knowledge_base/`
+
+注册前缀:
+
+`/api/knowledge`
+
+### 10.1 用户接口
+
+| 方法 | 路径 | 权限 | 用途 |
+|---|---|---|---|
+| POST | `/search` | `governance:read` | 只检索,不生成 |
+| POST | `/ask` | `governance:read` | 检索并生成有引用答案 |
+| GET | `/sources/<uid>` | `governance:read` + domain | 查看 active 来源 |
+| GET | `/sources/<uid>/versions/<version>` | 同上 | 查看指定引用版本 |
+| GET | `/capabilities` | `governance:read` | 模型与降级状态 |
+
+注意:当前全局权限策略会把普通 POST 视为编辑操作。必须为 `/search` 和 `/ask`
+增加显式 read-only 分类,不能要求 viewer 拥有 `governance:edit`。
+
+### 10.2 管理接口
+
+新增权限:
+
+`knowledge:manage`
+
+仅 admin 默认拥有。
+
+| 方法 | 路径 | 用途 |
+|---|---|---|
+| GET | `/admin/sync` | 同步、投影、失败和 lag |
+| POST | `/admin/reindex` | 创建新 generation |
+| POST | `/admin/retry-projection` | 重试指定失败投影 |
+| POST | `/admin/audit` | 启动 report/repair |
+| GET | `/admin/change-sets` | 查询知识点 Diff、影响范围和发布状态 |
+| GET | `/admin/change-sets/<id>` | 查看 change items 和失败阶段 |
+| POST | `/admin/change-sets/<id>/retry` | 从安全检查点重试失败变更 |
+| POST | `/admin/change-sets/<id>/rollback` | 回退未完成或新激活的 change set |
+| GET | `/admin/evaluations` | 评测运行与门禁结果 |
+
+### 10.3 响应契约
+
+统一包含:
+
+```json
+{
+  "query_id": "uuid",
+  "mode": "relationship",
+  "answer": "...",
+  "answer_status": "grounded",
+  "degraded_components": [],
+  "citations": [
+    {
+      "object_uid": "uuid",
+      "object_type": "DataFlow",
+      "object_name": "客户同步",
+      "object_version": 7,
+      "point_key": "DataFlow/019.../purpose",
+      "point_revision": 7,
+      "chunk_id": "uuid",
+      "section_path": "relations/READS_FROM",
+      "source_updated_at": "2026-07-22T02:10:00Z",
+      "index_generation": 3,
+      "retrievers": ["vector", "governance_graph"],
+      "score": 0.91
+    }
+  ],
+  "freshness_status": "fresh"
+}
+```
+
+## 11. 前端
+
+修改:
+
+- `frontend/src/views/knowledgeBaseProduct/index.vue`
+- 新建 `frontend/src/api/governanceKnowledge.js`
+- 新建 `frontend/src/views/knowledgeBaseProduct/components/`
+
+首期页面:
+
+1. 搜索/提问输入;
+2. `auto / 精确 / 语义 / 关系 / 全局` 模式;
+3. 对象类型和已授权业务域过滤;
+4. 答案与逐条引用;
+5. 点击引用回到治理对象;
+6. 降级、无答案和索引更新时间;
+7. 答案来源版本、更新时间和 freshness 状态;
+8. 管理员 change set、知识点 Diff、同步状态、失败重试和评测结果。
+
+前端不得:
+
+- 直接访问 LightRAG;
+- 自行决定用户业务域;
+- 隐藏后仍调用无权限来源接口;
+- 渲染模型返回的任意 HTML;
+- 显示内部 Prompt、模型密钥或原始堆栈。
+
+## 12. 配置与依赖
+
+### 12.1 Python 依赖
+
+将知识库依赖与核心依赖分组并锁定:
+
+- `llama-index-core`
+- PostgreSQL/Neo4j 所需的最小 LlamaIndex integration
+- tokenizer
+- reranker client
+
+不安装 `llama-index` 全量 starter,避免引入未使用 provider。
+
+实施前做 Python 3.11、SQLAlchemy 2.0、NumPy 和现有 OpenAI SDK 的兼容性
+spike。通过后将精确版本写入锁定文件;不得仅使用宽松 `>=`。
+
+LightRAG 保持独立镜像,不安装进 Flask backend,避免依赖冲突和扩大镜像。
+
+### 12.2 配置项
+
+新增但不提供生产默认密钥:
+
+```text
+KNOWLEDGE_ENABLED
+KNOWLEDGE_ACTIVE_EMBEDDING_PROFILE
+KNOWLEDGE_VECTOR_TOP_K
+KNOWLEDGE_RRF_K
+KNOWLEDGE_RERANK_TOP_K
+KNOWLEDGE_EVIDENCE_TOKEN_BUDGET
+KNOWLEDGE_IMPACT_MAX_HOPS
+KNOWLEDGE_IMPACT_MAX_POINTS
+KNOWLEDGE_IMPACT_MAX_OBJECTS
+KNOWLEDGE_FULL_REBUILD_THRESHOLD
+KNOWLEDGE_HIGH_RISK_MAX_STALENESS_SECONDS
+KNOWLEDGE_CHANGESET_RETRY_LIMIT
+KNOWLEDGE_LIGHTRAG_ENABLED
+KNOWLEDGE_LIGHTRAG_SHADOW_ONLY
+KNOWLEDGE_LIGHTRAG_BASE_URL
+KNOWLEDGE_LIGHTRAG_API_KEY
+KNOWLEDGE_LIGHTRAG_TIMEOUT_SECONDS
+KNOWLEDGE_LIGHTRAG_CANARY_PERCENT
+QWEN_EMBEDDING_BASE_URL
+QWEN_EMBEDDING_API_KEY
+QWEN_EMBEDDING_MODEL
+QWEN_EMBEDDING_DIMENSION
+RERANK_BASE_URL
+RERANK_API_KEY
+RERANK_MODEL
+```
+
+日志只能记录配置是否存在、模型名和配置哈希,不能记录密钥。
+
+## 13. 可观测性与降级
+
+### 指标
+
+- canonical index backlog、失败数、最老事件年龄;
+- change set pending/building/validating/failed 数、处理时延和最老年龄;
+- 每次变更 added/modified/deleted/impacted point 数;
+- impact propagation hop、截断次数和 generation 重建升级次数;
+- embedding 复用率与因知识点变化实际重算的 chunk 数;
+- 缓存精准失效数、业务域回退失效数和 stale cache 拒绝数;
+- LightRAG projection pending/failed/lag;
+- active 文档和 embedding 覆盖率;
+- 各 Retriever latency、candidate count、empty rate;
+- reranker latency 和降级次数;
+- search/ask P50/P95/P99;
+- no-answer rate;
+- citation count 和 stale citation 拒绝数;
+- point/chunk/source 版本映射失败数和 freshness 状态分布;
+- LightRAG source mapping failure;
+- 模型 token、费用和超时;
+- ACL 拒绝与跨域候选丢弃数。
+
+### 降级矩阵
+
+| 故障 | 行为 |
+|---|---|
+| LightRAG 不可用 | 标准链路继续,标记 graph enhanced degraded |
+| 治理 Neo4j 不可用 | lexical + vector |
+| pgvector 不可用 | lexical;ask 默认不生成或明确证据不足 |
+| reranker 不可用 | RRF 结果,降低置信度 |
+| Qwen 不可用 | 停止新索引;旧 active index 可查 |
+| DeepSeek 不可用 | search 可用;ask 返回来源和模型不可用状态 |
+| 新 generation 构建失败 | 保留旧 active generation |
+
+## 14. 评测与发布门禁
+
+### 14.1 黄金问题集
+
+首期 150–300 条,包含:
+
+- 30% 对象名、表名、字段、编码和别名;
+- 25% 定义、用途、责任人和数据标准;
+- 25% 上下游、依赖和两至三跳关系;
+- 10% 跨对象/全局主题;
+- 10% 无答案、旧版本、删除对象、Prompt Injection 和跨域越权。
+
+每条至少标注:
+
+- 允许的业务域;
+- 相关 object UID/version;
+- 相关 chunk 或关系;
+- 预期答案要点;
+- 是否必须拒答。
+
+### 14.2 对照组
+
+固定比较:
+
+1. lexical only;
+2. pgvector only;
+3. LlamaIndex standard;
+4. LlamaIndex + governance graph;
+5. LlamaIndex + governance graph + LightRAG。
+
+### 14.3 门禁指标
+
+初始验收目标:
+
+- 精确对象 Recall@5 ≥ 0.98;
+- 语义问题 Recall@10 ≥ 0.90;
+- 多跳 source Recall@10 ≥ 0.80;
+- Citation Precision ≥ 0.95;
+- 权限负向用例泄漏 = 0;
+- deleted/superseded 来源进入答案 = 0;
+- 无答案问题拒答准确率 ≥ 0.90;
+- search P95 ≤ 1.5 秒(不含外部模型生成);
+- LightRAG 故障时标准检索可用率 = 100%。
+
+LightRAG 正式放量还必须满足:
+
+- 多跳 Recall@10 相对
+  `LlamaIndex + governance graph` 提升至少 10 个百分点;
+- 精确问题 Recall@5 下降不超过 2 个百分点;
+- P95、token 和索引成本在批准预算内;
+- workspace 隔离和 canonical source re-authorization 全部通过。
+
+### 14.4 动态更新专项评测
+
+黄金集必须增加“变更前问题 + 变更操作 + 变更后预期”的时序用例,至少覆盖:
+
+1. 修改字段定义,只更新对应 definition point 和确定性依赖;
+2. 修改责任人,不重算无关 relation/definition embedding;
+3. 新增/删除血缘边,二至三跳问题引用新关系且不再返回旧关系;
+4. 数据标准变化,绑定对象和缓存按依赖传播更新;
+5. 删除治理对象,canonical 立即不可见且 LightRAG 残留可检测;
+6. 权限收紧,旧缓存和外部投影不能造成跨域泄漏;
+7. 重复、乱序和并发事件最终收敛到最高合法 source revision;
+8. Qwen、LightRAG、缓存 worker 或数据库事务失败时旧 active 版本持续可用;
+9. 影响范围超过阈值时升级为 generation 重建,不发布截断的局部结果;
+10. 新 generation 失败或效果退化时能够回滚。
+
+新增门禁指标:
+
+- 知识点 Diff 准确率 = 1.00(黄金 fixture);
+- 删除/权限收紧后 canonical 不可见延迟满足批准的安全 SLA;
+- unchanged point 的 embedding 重算率 = 0;
+- change set 部分发布导致的混合版本命中 = 0;
+- stale point/chunk/citation 进入答案 = 0;
+- change set 最终收敛率 ≥ 0.999,失败项全部可观测、可重试或可回滚;
+- 依赖传播漏更新 = 0(已声明规则的黄金用例);
+- LightRAG 删除残留必须被巡检发现,不能静默通过发布门禁。
+
+## 15. 分阶段交付
+
+```mermaid
+flowchart LR
+    K0["K0\n兼容性与评测基线"] --> K1A["K1A\n事件与授权"]
+    K1A --> K1B["K1B\n知识点与版本"]
+    K1B --> K1C["K1C\nDiff 与影响传播"]
+    K1C --> K1D["K1D\n原子发布与新鲜度"]
+    K1D --> K2["K2\nLlamaIndex 标准检索"]
+    K2 --> K3["K3\nLightRAG 影子侧车"]
+    K3 --> K4["K4\n融合问答与引用"]
+    K4 --> K5["K5\n前端与运维"]
+    K5 --> K6["K6\n评测、Canary 与发布"]
+```
+
+### K0:兼容性与评测基线
+
+实施:
+
+- 建立 30–50 条小型黄金集;
+- 验证 LlamaIndex 最小依赖与 Python 3.11;
+- 验证自定义 VectorStore/Retriever 可读取现有表;
+- 验证 LightRAG REST、PostgreSQL 16.6+、Neo4j 和 1024 维 embedding;
+- 验证 insert/query/delete、context source mapping 和 workspace 隔离;
+- 验证 LightRAG 的真实最小删除粒度、删除回执、重复插入语义和孤儿内容发现方式;
+- 用两个版本的 DataFlow fixture 验证 point/document external ID 更新策略。
+
+退出门槛:
+
+- 不需要第二套业务源表;
+- LightRAG context 能映射回 DataOps stable source;
+- 已明确 LightRAG 使用 point 级更新、对象投影包重建或 generation 重建中的哪一种;
+- 依赖锁可重复安装;
+- 无密钥进入镜像、日志或测试 fixture。
+
+回滚:
+
+- 删除 PoC 容器和测试数据库;
+- 不改变当前生产路径。
+
+### K1A:对象级事件、授权与快照边界
+
+主要文件:
+
+- V100 migration;
+- `app/core/knowledge/access.py`
+- `document_builder.py`
+- `sync.py`
+- governance 写路径 Outbox 事件。
+
+测试:
+
+- schema/migration;
+- 每类对象 golden document;
+- secret redaction;
+- user-domain grants;
+- source revision 单调性;
+- duplicate/out-of-order/restart;
+- 权限扩大与权限收紧事件。
+
+退出门槛:
+
+- 业务域为空时 fail closed;
+- 每类首期治理对象均有同步事件和稳定 source revision;
+- 事件能重新读取完整、一致的 canonical source snapshot;
+- changed-field hint 不会代替实际快照比较;
+- 权限收紧事件进入高优先级处理队列。
+
+### K1B:知识点模型、稳定键与版本
+
+主要文件:
+
+- V100 中 `knowledge_points`、`knowledge_point_dependencies`、
+  `knowledge_change_sets`、`knowledge_change_items`、`knowledge_cache_dependencies`;
+- `app/core/knowledge/point_builder.py`
+- `app/core/knowledge/contracts.py`
+- `app/core/knowledge/chunking.py`
+
+实施:
+
+- 先支持 `BusinessDomain` 和 `DataFlow` 的 point builders;
+- 为 DataMeta 字段、标准规则、标签和关系确认稳定子对象 UID;
+- 定义 point → chunk 和 point → dependency 的确定性映射;
+- 生成 point set hash、chunk point set hash 和 permission hash;
+- 旧文档回填为初始 point generation,但不凭文本相似度猜测稳定 ID。
+
+测试:
+
+- stable `point_key` golden fixtures;
+- 字段/关系重排不改变 point identity;
+- 名称变化只修改预期 point;
+- point/document/chunk hash 可重复;
+- 同一 point 最多一个 active 版本;
+- 模型抽取关系不能写入 canonical dependency source。
+
+退出门槛:
+
+- 五类首期治理对象均能产生稳定、可复现 point set;
+- 每个 chunk 能反查来源 point 和版本;
+- 权限和版本不由 LLM 决定;
+- 初始回填有审计报告和可回滚 generation。
+
+### K1C:语义 Diff 与有界影响传播
+
+主要文件:
+
+- `app/core/knowledge/diff.py`
+- `app/core/knowledge/impact.py`
+- `app/core/knowledge/sync.py`
+
+实施:
+
+- 按 `point_key` 计算 added/modified/deleted/unchanged;
+- 记录 change set 和逐 point change items;
+- 实现关系白名单、最大 hop、最大 point/object 数和循环检测;
+- 超阈值自动升级为业务域 generation 重建;
+- 只为 changed/impacted point 生成待构建 chunk 集合。
+
+测试:
+
+- 新增、修改、删除和无语义格式变化;
+- 字段、标准、血缘、责任人和业务域变更;
+- 多级依赖、环、孤儿依赖和超阈值传播;
+- duplicate/out-of-order/concurrent events;
+- 传播路径和根因审计可复现。
+
+退出门槛:
+
+- 黄金 fixture 的知识点 Diff 准确率为 1.00;
+- 已声明传播规则不存在漏更新;
+- unchanged point 不进入 embedding 队列;
+- 影响被截断时不允许局部 change set 进入 `canonical_active`。
+
+### K1D:增量构建、原子发布、缓存失效与审计
+
+主要文件:
+
+- `app/core/knowledge/publish.py`
+- `app/core/knowledge/cache_invalidation.py`
+- `app/core/knowledge/audit.py`
+- Qwen embedding batch/reuse;
+- projection 与 cache invalidation worker。
+
+实施:
+
+- prepare/validate/activate 状态机;
+- unchanged embedding 复用和 changed chunk 批量生成;
+- point/document/chunk 的事务级 active 切换;
+- point dependency 精准缓存失效及业务域回退失效;
+- 删除/权限收紧的紧急撤销路径;
+- LightRAG 增量投影能力探测与 generation 重建策略;
+- report-only audit、显式 repair 和 rollback。
+
+测试:
+
+- Qwen/事务/cache/LightRAG 任一步失败;
+- 部分构建不可见和旧 active 持续可用;
+- delete/permission 紧急撤销 SLA;
+- stale cache、stale citation 和孤儿 projection;
+- retry/restart/rollback;
+- generation 切换和回退。
+
+退出门槛:
+
+- 不存在半新半旧的可查询对象快照;
+- Qwen 失败不覆盖旧 active;
+- 删除和权限收紧满足批准的 canonical 不可见 SLA;
+- unchanged point embedding 重算率为 0;
+- change set 可从任何失败阶段安全重试或回滚;
+- 每日 audit 能发现 source/canonical/cache/LightRAG 差异。
+
+### K2:LlamaIndex 标准检索
+
+主要文件:
+
+- `llamaindex/node_mapper.py`
+- `llamaindex/vector_store.py`
+- lexical/vector/governance graph/fusion/router/pipeline;
+- `/api/knowledge/search`。
+
+测试:
+
+- metadata filter;
+- active version;
+- active point revision 和 generation 过滤;
+- exact/vector/graph/RRF;
+- Neo4j 和 pgvector 故障降级;
+- viewer 的 POST search 仍按 read 权限;
+- 负向跨域检索。
+
+退出门槛:
+
+- 不使用 LlamaIndex 默认持久化表;
+- 返回稳定 UID/version/chunk;
+- 返回稳定 point key/revision 和 freshness metadata;
+- 标准链路达到 Recall 和延迟基线;
+- search 不依赖 DeepSeek。
+
+### K3:LightRAG 影子侧车
+
+主要文件:
+
+- Compose LightRAG 服务与独立存储;
+- `lightrag/client.py`
+- `lightrag/projection.py`
+- projector command/service;
+- projection admin 状态。
+
+测试:
+
+- insert/update/delete 幂等;
+- point/object 投影包更新与删除残留检测;
+- workspace 隔离;
+- mapping failure 丢弃;
+- LightRAG timeout/circuit breaker;
+- generation 重建;
+- change set 到 projection 的状态关联;
+- 每日 audit 修复孤儿。
+
+退出门槛:
+
+- 默认 `shadow_only=true`;
+- 不影响正式答案;
+- 现有治理 Neo4j 没有 LightRAG 标签、索引或关系;
+- 多跳评测数据完整;
+- canonical change set 发布不依赖 LightRAG ready,且旧投影上下文无法通过来源复核。
+
+### K4:融合问答与引用
+
+主要文件:
+
+- LightRAGRetriever;
+- rerank;
+- qa/synthesizer;
+- `/api/knowledge/ask`;
+- source/version API。
+
+测试:
+
+- context-only;
+- canonical re-authorization;
+- Prompt Injection;
+- stale/deleted citations;
+- point modified/impacted 后 stale citation 拒绝;
+- no-answer;
+- model timeout;
+- citation fabrication rejection。
+
+退出门槛:
+
+- 最终答案只由 DataOps 生成;
+- 每个引用能打开合法源对象;
+- 每个引用能定位 active point revision 和 generation;
+- 模型不可用时不伪造答案;
+- 权限负向用例零泄漏。
+
+### K5:前端与运维
+
+实施:
+
+- 搜索、问答、模式和过滤;
+- 引用与回跳;
+- 降级提示;
+- 管理员同步/重试/评测;
+- 管理员 change set、Diff、影响范围和 freshness 状态;
+- system health 增加 knowledge 组件。
+
+退出门槛:
+
+- viewer/editor/admin 页面与 API 权限一致;
+- 前端不直连 LightRAG;
+- 无内部错误、密钥和 Prompt 暴露;
+- 浏览器验收通过。
+
+### K6:评测、Canary 与发布
+
+实施:
+
+- 扩展到 150–300 条黄金集;
+- 保存各对照组结果;
+- LightRAG 先按业务域和百分比 Canary;
+- 观察 no-answer、投诉、延迟、成本和引用反馈;
+- 达标后逐步关闭 shadow-only。
+
+退出门槛:
+
+- 全部质量和安全门禁通过;
+- LightRAG 有明确收益;
+- 关闭 LightRAG 的回滚演练通过;
+- 新旧 generation 切换和回退通过;
+- 动态更新专项门禁、紧急撤销 SLA 和缓存失效门禁通过;
+- 形成 `docs/validation/knowledge-k6.md`。
+
+## 16. 测试布局
+
+新增建议:
+
+```text
+tests/knowledge/
+├── test_access_context.py
+├── test_document_builder.py
+├── test_point_builder.py
+├── test_chunking.py
+├── test_knowledge_diff.py
+├── test_impact_propagation.py
+├── test_atomic_publish.py
+├── test_cache_invalidation.py
+├── test_sync.py
+├── test_audit.py
+├── test_lexical_retriever.py
+├── test_vector_retriever.py
+├── test_governance_graph_retriever.py
+├── test_fusion.py
+├── test_router.py
+├── test_reranker.py
+├── test_lightrag_client.py
+├── test_lightrag_projection.py
+├── test_qa.py
+└── test_evaluation.py
+
+tests/integration/
+├── test_knowledge_pgvector.py
+├── test_knowledge_neo4j.py
+├── test_lightrag_contract.py
+├── test_knowledge_outbox_projection.py
+├── test_knowledge_dynamic_update.py
+├── test_knowledge_generation_switch.py
+├── test_knowledge_emergency_revoke.py
+└── test_knowledge_degraded_modes.py
+
+tests/e2e/
+└── governance-knowledge.spec.js
+```
+
+验证分层:
+
+- L1:纯单元和 golden fixtures;
+- L2:迁移、权限、API 和适配器契约;
+- L3:PostgreSQL + Neo4j + backend;
+- L4:增加 LightRAG 与模型 mock;
+- L5:有显式密钥时运行真实模型评测,不作为普通 CI 前置。
+
+## 17. 风险与控制
+
+| 风险 | 控制 |
+|---|---|
+| LlamaIndex 依赖膨胀/冲突 | 只装 core + 最小 integrations,精确锁版本 |
+| LightRAG 升级破坏 API | client 适配层 + 契约测试 + 固定 digest |
+| LightRAG 图污染治理图 | 独立 Neo4j 凭据、服务、卷/数据库 |
+| 多业务域泄漏 | workspace 分区 + 查询前授权 + 来源重新授权 |
+| ANN 过滤降低召回 | exact baseline、iterative scan/oversampling 和分域评测 |
+| embedding 模型切换 | profile + shadow generation + 原子切换 |
+| `point_key` 不稳定导致伪变化 | 稳定子对象 UID、golden fixtures、禁止名称/下标/hash 入键 |
+| 依赖传播爆炸或形成环 | 关系白名单、visited set、hop/point/object 上限、升级 generation 重建 |
+| 依赖规则漏更新 | 时序黄金集、change path 审计、每日 source/point/chunk 巡检 |
+| 事件重复、乱序或并发 | source revision 单调、幂等 change set、同源对象串行激活 |
+| 增量发布暴露混合版本 | prepare/validate/activate,事务级切换全部 point/document/chunk |
+| 缓存保留旧知识或旧权限 | point dependency、权限范围失效、缺依赖时整域失效 |
+| LightRAG 删除残留 | tombstone、projection 状态、每日 audit |
+| LightRAG 不支持可靠局部删除 | 对象投影包重建或新 workspace generation 影子切换 |
+| LLM 抽取产生错误关系 | LightRAG 图只作召回投影,最终证据回到 canonical source |
+| Prompt Injection | evidence 隔离、系统指令、来源复核、负向测试 |
+| 查询内容进入日志 | 默认只存 query hash 和来源 UID |
+| 模型/侧车不可用 | 标准链路和 retrieval-only 降级 |
+| Outbox 被误当多消费者 | 单 KnowledgeIndexHandler + projection queue |
+
+## 18. 完成定义
+
+只有同时满足以下条件才算知识库落地完成:
+
+1. 五类治理对象都能生成稳定、可复现的知识点集合和依赖关系;
+2. 新增、修改、删除和权限变化都形成可审计 change set,并正确区分
+   added/modified/deleted/unchanged/impacted;
+3. 已声明依赖规则能够有界传播,超过阈值时自动升级为 generation 重建而不是发布
+   不完整结果;
+4. unchanged point 不重复生成 embedding,changed/impacted point 只重建必要产物;
+5. point/document/chunk/embedding 使用 prepare/validate/activate 原子切换,失败时旧
+   active 版本持续可用;
+6. 删除和权限收紧在批准 SLA 内使 canonical 内容不可见,缓存和 LightRAG 残留可
+   检测、可清理;
+7. 五类治理对象均可增量同步、删除、每日校验和安全回滚;
+8. 新旧索引 generation 可影子构建、原子切换和回退;
+9. viewer/editor/admin 与业务域授权均由服务端执行;
+10. search、ask、source、change set 和 admin API 契约稳定;
+11. 精确、语义、治理图、LightRAG、Diff、影响传播和缓存失效路径可观测;
+12. LightRAG 下线不影响标准检索,且旧投影上下文不能绕过 canonical 复核;
+13. 所有回答有合法 UID/version/point revision/generation 引用,或明确拒答;
+14. 权限、Prompt Injection、stale/deleted、动态更新和模型失败测试通过;
+15. 静态黄金集、时序变更黄金集、质量指标和性能门禁全部通过;
+16. 前端、后端、迁移、worker、相关容器和浏览器验收留下验证记录。
+
+## 19. 推荐的首个实现切片
+
+实施开始时不要先部署完整 LightRAG。首个切片固定为:
+
+1. V100 业务域授权、知识点/change set 表和 embedding profile;
+2. DataFlow/BusinessDomain 两类规范化文档与稳定 point builders;
+3. 用“修改 purpose、修改 owner、增删 READS_FROM、权限收紧、删除对象”验证
+   Diff、影响传播、原子切换和缓存失效;
+4. lexical + pgvector 的 LlamaIndex `/search`,引用返回 point revision 和 generation;
+5. 30–50 条静态黄金集 + 10–20 条时序变更黄金集;
+6. 单业务域 LightRAG shadow PoC,实测删除粒度和残留检测;
+7. 达到动态更新、来源映射和权限门槛后再进入 K3。
+
+这样可以先证明 DataOps 自身的知识身份、变化传播、发布一致性和检索基础正确,再
+判断 LightRAG 的真实增益,避免把知识点错配、陈旧缓存、基础分块、授权或引用问题
+误判为图算法问题。