Files
knowledge-governance/cmd/libraryctl
姚章浩 9300865d23 fix(library): 搬运复用前复验字节、回传游标分页与发布队列事务交接
父独立审查退回的四个 finding,逐项修在本包内,不改架构。

1 复用路径没复验字节:remoteEvidence 只读清单+摘要就宣布可用。现在新增
libraryctl snapshot-verify(整版逐部件重算)并在复用前调用;blob 缺失/篡改必须
在入发布队列之前失败。新增真实 local 跨进程用例:清单不动、删 blob / 改 blob 后
再 Push 必须拒绝。

2 回传枚举被固定 LIMIT 50 截断:LibraryJobSnapshots 只取成功作业且按摘要字典序。
改为 LibrarySnapshotCandidates:合并 library_versions、library_jobs.snapshot_id、
library_jobs.target_snapshot_id 三处引用,按 (created_at, snapshot_id) 游标分页;
回传循环翻页到不足一页为止。失败/待恢复作业留下的预备份、第 51 条以后、历史恢复
输入快照都能被枚举。另修"本地只有清单、blob 已损坏就永远跳过":改用整版 Load 判定,
并给 Unpack 增加显式 RepairCorruptBlobs(只在权威云端读回时开启)。

3 身份映射错误:搬运拿目标 tenant/KB 去核对封存快照,而封存清单写的是**源**身份
(云测试验收目标 a8e9c8ad/2e980686 与源 KB 必然不同)。现在 expectedSnapshotIdentity
按版本台账判定:test_sealed → 用部署注入的源绑定(LIBRARY_SOURCE_TENANT_ID /
LIBRARY_SOURCE_KB_*);预备份/生效/恢复版本 → 用目标绑定;没有登记或两类冲突一律拒绝。
身份永远来自独立绑定与台账,不接受包自证。

4 两步入队有竞态:Enqueue 成功后云执行器可能立刻领取并开始维护,Attach 失败却把作业
标失败并声称"未维护"。改为 EnqueueAndAttachLibraryJob 单事务(锁行 + 插入 + 关联 +
状态守卫),要么都成功要么都不发生;重复执行幂等,已关联别的队列作业则拒绝。
另修终态重放:AdvanceLibraryJob 无状态守卫,迟到的失败出口会把已成功作业改写;
新增 AdvanceLibraryJobIfActive(仅 pending/running 可推进),拿不到就明确记录"未覆盖"。

测试:libraryhandoff 用例覆盖跨租户/错误 scope/清单在而字节坏/本地损坏自愈;
隔离 fixture 库覆盖"校验通过才入队、失败不入队"、>50 条分页与失败作业预备份、
幂等重放不重复投递、迟到失败不改写终态。

未部署、未推送、未构建镜像;真实跨主机 SSH 链路仍未验证。
2026-10-30 19:10:02 +08:00
..