Files
knowledge-governance/docs/library-sync-acceptance.md
T
2026-10-28 08:32:23 +08:00

134 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 知识库级版本同步:开发与验收清单
## 交付边界
本清单记录已确认需求与验收条件,不表示功能已实现。日常编辑按文档,生产版本及恢复按知识库完整状态;发布管理仅有对内、对外两个目标。开发授权不包含生产同步、生产恢复或真实数据清理。生产执行仍须在发布管理经管理员授权;保留数量、天数、容量预算未设置,自动清理默认关闭。
现有文档包发布与执行级补偿只能作为复用基础,不能作为本清单完成证据。静态样图不作为产品运行证据。组织绩效与周报外发不在本次范围。
## 已确认:验收口径 A(原始产物)
用户选择不修改 WeKnora,以冻结的完整知识版本绑定内容、问答与性能验收。源端索引可能含未持久化的生成上下文,不再要求从 PostgreSQL 正文反推每条正文索引的生成过程。
- 原样归档索引内容与向量,不重新生成;继续校验库/文档/分块身份关联、覆盖、数量、资源及摘要。已持久化生成问题仍按 ID 和原文精确校验。
- 新候选清单记录 `validation_policy=artifact-acceptance-v1`,该字段纳入内容寻址身份;历史无该字段的快照不冒称执行了新口径。
- 候选归档成功不证明冻结、内容质量、问答正确性或性能通过。测试验收必须绑定具体快照身份;旧快照验收不得放行新快照。生产发布仍须独立授权。
- 本次只完成候选产物保留和口径记录,真实冻结业务接线与持久化验收绑定尚未完成,不能因此放行生产。
## 已确认:封存隔离方案 A
用户选择封存期间自动暂停测试 WeKnora 服务,封存后恢复,不修改 WeKnora 源码。测试问答在暂停期间暂不可用,停用时长须实测;不暂停生产服务,也不因此取得生产同步、恢复或真实清理授权。
实现要求:先等待处理任务完成,枚举并核实全部测试写入者和副本;暂停后重新检查状态,数据库、索引和对象存储保持可读。持久记录暂停前运行状态及作业归属,覆盖成功、失败、取消和进程重启后的恢复;仅恢复本作业暂停的服务,并读回服务健康。完整归档封存后即可恢复测试服务,后续生产传输从归档读取,不延长测试停用时间。
方案已确认不等于暂停/恢复功能已实现;恢复保障验证前不停止运行中的测试服务。
## 开发与测试顺序
1. 核查实际 WeKnora 的文档删除、Wiki 更新与完成信号,以及跨数据库、对象、索引的快照与恢复契约。
2. 实现完整版本清单、一致性校验、授权与持久化作业;逐项运行失败用例再实现通过。
3. 接通实际导出、独立生产预备份、传输、验证、恢复及持久化进度;隔离环境演练故障、重启与重试。
4. 发布管理接真实接口,存储管理接真实测量及依赖保护;验证浏览器交互与权限。
5. 完整回归、审查、提交交付;生产实测单列等待授权,不以隔离验收代替。
## 验收项目
| ID | 范围 | 必须证明的行为 | 状态 |
| --- | --- | --- | --- |
| V01 | 两个目标 | 只按对内、对外操作;身份来自已配置映射,不按名称猜测 | 待验证 |
| V02 | 测试就绪 | 全部解析、索引及 Wiki 就绪;问答与性能验收绑定本版,旧验收不能放行新变化 | 待验证 |
| V03 | Wiki 撤销 | 删除文档后验证共享正文、实体、概念、边与引用的实际变化;删除成功或引用剥离不能代替此证据 | 待验证 |
| V04 | 完整固定版本 | 清单覆盖文档集合、处理结果、资源、索引、完整 Wiki;无部分文档配整库 Wiki 的路径 | 待验证 |
| V05 | 并发修改 | 导出中发生源变更时拒绝不一致版本,或由已证明的固定快照协议隔离;导出前后表面计数相同不算充分证明 | 待验证 |
| V06 | 内容范围 | 仅允许知识数据;账号、会话、凭据及无关知识库不被同步或恢复 | 待验证 |
| B01 | 写前预备份 | 每次生产变更前创建旧状态完整备份,校验恢复资料完整性;失败时零生产知识写入 | 待验证 |
| B02 | 独立恢复依赖 | 资源在测试侧删除后,保留版本仍能恢复,不依赖测试临时对象或短期签名地址 | 待验证 |
| B03 | 完整 Wiki 资产 | 每版保存完整 Wiki 及引用关联,校验摘要、数量和版本绑定 | 待验证 |
| S01 | 数据同步 | 数据库、资源、索引、Wiki 均真实落地并校验,增量仅为传输优化 | 待验证 |
| S02 | 无生产再计算 | 生产侧不解析、Embedding 或生成 Wiki,使用测试验收结果 | 待验证 |
| S03 | 一致生效 | 不宣称不存在的跨系统原子性;明确可见性保护、失败补偿与验证边界 | 待验证 |
| S04 | 故障与恢复 | 各阶段失败、超时与进程重启后可追溯、可恢复,不重复破坏性动作 | 待验证 |
| S05 | 幂等与互斥 | 重复请求不启动重复同步;同目标同步、恢复、清理之间互斥;不同请求体复用键被拒绝 | 待验证 |
| R01 | 版本恢复 | 恢复生产整套文档、资源、索引与 Wiki;测试知识库不回退 | 待验证 |
| R02 | 恢复失败 | 不标记成功、不丢旧恢复依据,明确受影响阶段及后续可执行措施 | 待验证 |
| R03 | 速度 | 分开实测备份与恢复耗时、数据量、吞吐及环境;未经测量不承诺快速 | 待验证 |
| P01 | 作业阶段 | 持久化准备、备份、同步、验证、恢复阶段与开始/更新时间、错误;生产验证成功才完成 | 待验证 |
| P02 | 四类进度 | 数据库记录、资源文件/字节、索引分块、Wiki 页面/关联数据来自实际测量;总量未知不造百分比 | 待验证 |
| P03 | 明细 | 可查看实际对象、数量、字节、校验及异常;筛选与总量不依赖前端当前页 | 待验证 |
| U01 | 主要入口 | 对内/对外切换、启动同步、版本与快照、当前作业预备份入口均可见;旧版历史可追溯 | 待验证 |
| U02 | 权限 | 未就绪明确阻断原因;会话注入操作者;只读/工程师不能获得生产执行权限 | 待验证 |
| U03 | 操作确认 | 启动、恢复显示准确目标及影响并保留授权;运行中禁止重复启动 | 待验证 |
| D01 | 存储策略 | 未设阈值如实显示未设置,自动清理默认关闭,不隐含年龄删除 | 待验证 |
| D02 | 占用测量 | 区分逻辑大小、独占、共享、实际占用;无法测量显示未知,不当成零 | 待验证 |
| D03 | 保护引用 | 当前恢复依据、活跃作业、锁定/保留版本及共享资源受到保护 | 待验证 |
| D04 | 清理预览 | 列明对象、依赖、受影响版本及可测释放量;执行前重新核验引用与活跃作业 | 待验证 |
| D05 | 容量门禁 | 空间不足告警或阻断,不为继续作业偷删受保护备份 | 待验证 |
| D06 | 测试残留 | 覆盖取件缓存、临时解析、同步暂存、失败上传、删除/重解析残留,不删除源文件 | 待验证 |
| D07 | 实际回收 | 区分逻辑删除与实际释放,核查对象历史版本/分片及数据库、索引回收;保留版本清理后仍可恢复 | 待验证 |
## 证据登记规则
每项完成需附实现位置、运行命令与退出码、可回看的证据路径、验证环境及尚未覆盖范围。单元测试、隔离数据库集成、模拟外部服务、真实测试知识库、生产验收分别标注,不能相互替代。
真实清理和生产恢复尚未授权的项目保持待授权/待验证;不得为了打勾执行。整项范围未覆盖不得以子切片通过称为本阶段完成。
## 已运行的基础模块证据(不等于整体验收)
实现位置:`internal/librarysnapshot/` 与 `internal/releaseadapter/v071/library_*.go`。
- PostgreSQL 整库只读 Repeatable Read 导出:显式包含空 Wiki 表;未完成解析、删除文档残留任务、死信、未知 schema、Neo4j 启用场景拒绝自动放行。
- Elasticsearch 使用 PIT 与 search_after,核查精确总量、返回范围、重复项与部分结果;PIT 只证明索引自身的视图。
- 候选归档独立持有资源字节,校验表、scope、资源依赖、索引关联及摘要;内容寻址复用、重开加载、同一文件描述符校验读取、共享/独占引用字节已测试。引用字节不是物理占用或实际可回收字节。
- `go test -race ./internal/librarysnapshot ./internal/releaseadapter/v071 -count=1`:退出码 0;默认跳过需要显式配置的隔离集成,不能据此声称集成通过。
- 隔离 PostgreSQL + Elasticsearch 集成另行运行,退出码 0。只创建随机 `kg_library_test_` 前缀夹具;结束后 PostgreSQL 同前缀库残留计数为 0。
- MVCC 反向自检:仅通过 Go overlay 把 Repeatable Read 改为 Read Committed,同一真实隔离集成退出码 1,失败断言为 `mixed PostgreSQL versions during export`。原始实现复跑退出码 0。
- `make verify`:退出码 0。本地门禁不是远端 CI,也不是新 UI 或真实知识库完整验收。
证据保存在本机仓库忽略目录 `backups/library-sync-foundation-20261027/`:`unit-tests.jsonl`、`kg-library-integration.log`、`kg-library-mvcc-negative.log`、`kg-library-verify.log`。隔离执行脚本副本同目录留存,不含静态凭据;运行时从本地测试容器读取。
### 当前不能放行的边界
1. `ArchiveLibraryCandidate` 的 seal 只代表归档完整性,不代表跨系统同一时点、Wiki 语义验收通过或生产授权。尚未接到生产执行器。
2. 数据库 MVCC 与 ES PIT 是各自独立的快照,不能把两者拼接视为一致整版。用户已确认方案 A:封存期间自动暂停测试服务;全部写入者隔离、异常恢复及实际停用时长尚待实现与验证,不修改 WeKnora 源码,不暂停生产。
3. 已检查本地 v0.7.1 源码:`EnqueueWikiRetract` 在持久化 pending op 失败时记录警告后返回;因此 pending/dead-letter 都为空仍不证明撤销语义已处理。必须补充删除后共享 Wiki 内容的实测与验收绑定。
4. 生产预备份、独立恢复演练、持久化协调作业、授权 API、真实进度、发布页面与完整存储治理仍未交付;以上验收项目保持待验证。
5. 基础模块已随 `0.1.96 / 9105f8316cc870a62b5ddacd1496f0cb0f798d87` 提交、推送并部署到本地测试治理平台;运行 API/worker 的二进制摘要已读回校验。该部署不等于业务功能接线或完整验收通过;未执行生产同步、恢复或真实业务清理。完整验收仍受本节及下述缺失接线阻塞。
## 真实测试源只读诊断(未通过)
`TestLibrarySourceReadOnlyDiagnostic` 仅在明确 opt-in 下运行,数据库连接强制只读;只调用 ES 查询/PIT 和 OSS 对象读取,不执行生产操作、源数据清理或服务暂停。测试凭据仅通过子进程环境注入,不记录配置值。
本次实际执行退出码 1:对内库 125 条索引记录中有 13 条关联到未被完整文档集合纳入的分块;进一步只读查询定位为 4 个未删除分块(3 个 text、1 个 summary)缺少同租户的父文档,不是临时上下文内容比较失败。现有身份校验保持拒绝,没有忽略这些记录或据此放行。独立 OSS 读取校验覆盖 21 个资源、53,490,166 字节。对外库读到 0 文档、0 分块、1 个 Wiki 页面,候选结构归档可读回,但未冻结且模型兼容身份为明确诊断占位,不能当作版本验收通过。
证据:`backups/library-source-readonly-20261028/`。真实源诊断失败与默认 CI 的环境跳过分别记录;此次发现不授权清理这批分块或索引,之前仅限死信 ID 1 的授权不扩展使用。
## 联合隔离捕获验收
新增 `TestLibraryCaptureIsolatedStack`,在同一次 `CaptureLibrary` 调用中连接真实隔离 PostgreSQL、随机 Elasticsearch 索引、真实 Docker 暂停/恢复控制器和本地资源文件读取器。写入服务使用无网络、无宿主挂载的 busybox 夹具,不是实际 WeKnora;资源读取不是实际 OSS/S3 验收。
- 非空文档、分块、资源、Wiki 正文及字符串状态归档后读回;检查无跨租户记录或会话数据泄漏。
- 删除真实夹具索引记录后,新捕获必须失败,原运行容器仍恢复健康。
- 删除源资源文件、修改源 PostgreSQL、删除源 ES 文档后,成功作业重放仍返回原快照,不再调用源端就绪检查或资源读取;归档重新加载通过。
- 反向自检使用 Go overlay 仅关闭 legacy 索引覆盖检查:同一联合用例退出码 1,明确报 `missing real index accepted`;未修改的实现复跑退出码 0。
- `make verify` 与三包 race 回归退出码 0;新用例在默认 CI 中显式声明环境跳过,本地单独实际执行。夹具索引和容器删除后读回不存在,随机隔离数据库已删除。
证据:`backups/library-stack-acceptance-20261028/`。该联合用例补充捕获协调证据,不证明真实源全部写入者受控、Wiki 撤销语义、内容/问答/性能验收绑定或生产同步恢复已经完成。
## 方案 A:暂停与恢复原语的实测证据
新增 `internal/libraryfreeze/`,包含持久化作业日志、源服务组互斥、暂停前原运行状态、不可变容器 ID、恢复读回,以及本地 Unix socket Docker 控制器。Docker 控制器只接受对应 source 且 `environment=test`、`freeze-role=writer` 的容器;不按模糊名称选取,不控制数据库/索引存储,不使用远程默认 Docker context。运行容器必须有健康检查。
已经执行的验证:
- `go test -race ./internal/libraryfreeze ./internal/librarysnapshot ./internal/releaseadapter/v071 -count=1`,退出码 0。
- `KG_FREEZE_DOCKER_ISOLATED=1 go test -race -v ./internal/libraryfreeze -run '^TestFreezeIsolatedDocker$' -count=1`,退出码 0。使用已缓存 busybox 创建随机标签、无网络、无宿主挂载的一次性容器,真实验证停止→捕获窗口→重启健康、原本停止容器不启动;控制子进程在停止后退出,再由新恢复调用读持久日志启动原容器。清理后按标签读回无残留。
- 异常覆盖:停止回包丢失、停止未生效、新副本出现、容器被替换、捕获错误/panic/取消、日志写入失败、恢复健康失败、畸形日志、同源并发及重复恢复。捕获 panic 和日志失写故障先实际报红,修复后通过。
- 不使用有延迟强杀计时器的停止方式;仅发送 SIGTERM 并等待实际停止。若停止结果不明且服务仍运行,不把“现在运行”误判为已恢复,日志保持待恢复,防止随后迟到的停止把服务留在关闭状态。
- 新增 Docker 集成用例已在 `scripts/test-scope.json` 精确声明 opt-in;普通 CI 明确跳过,不冒称执行。完整 `make verify` 退出码 0,属于本地门禁。
证据:本机 `backups/library-sync-foundation-20261027/kg-freeze-docker-integration.log`、`kg-library-freeze-verify.log`。
已新增 `internal/releaseadapter/v071/library_capture.go`,在源服务组互斥下串起预检、暂停、停后复检、PG/ES 导出、独立归档和恢复。协调测试使用 PG/服务控制夹具与 HTTP 搜索夹具,覆盖预检忙时零停止、暂停前后新增任务阻断、搜索失败恢复、旧作业重放不重新暂停、跨 scope 复用拒绝、归档丢失不返回成功;不把这组夹具当成实际业务知识库全链路验收。最终竞态回归、隔离 Docker 重跑与 `make verify` 均退出码 0,最终日志为同目录 `kg-freeze-docker-final.log`、`kg-library-freeze-final-verify.log`。
**仍缺少的接线**:真实测试部署的全部写入者枚举及标签/健康契约、部署侧入口及后台作业就绪检查的实际提供方、worker 调用捕获协调函数、启动恢复入口和持续恢复调度。`CaptureLibrary` 已强制在暂停前后检查整个源数据库的解析、pending 与 dead-letter 状态(跨库、跨租户及未知/删除范围);此检查不能代替入口隔离与 Wiki 语义验收。单独的本地 Docker 控制器不能控制远端测试主机;远端场景需在测试主机运行受限执行器,不能向浏览器或普通 API 暴露 Docker socket。上述测试不能证明这些接线已完成,尚未暂停实际测试 WeKnora。