Files
knowledge-governance/internal
姚章浩 70c181370d fix(library): handoff 阶段事务化、回传空页重置与目标基线原产地
父复审确认的三个残余(原链路,不扩架构),本包按真实调用链修完。

1 回传空页不重置游标:引用数正好是 pageSize 整数倍时,最后一页为空,
len(items)==0 直接 break 而不清游标 ⇒ 游标永远停在最老处,下一轮仍为空,
之后新增的快照再也取不到。抽出单轮函数 pullRound:空页显式重置该 scope 游标,
游标跨轮保留(单轮 20 页只是预算)。测试用真实分页语义的假数据源跑 100/2000/2100
三档,遍历完再新增引用并断言下一轮能看到(不再只测 advance helper)。

2 目标权威基线被误拒:library_baseline 是目标侧真实捕获,但只登记
production_effective(证据 action=target_baseline_init / origin=target_baseline),
原实现把"只有 effective"一概拒绝。现在原产地按**捕获证据**判定:封存=源、
预备份=目标、带基线证据的 effective=目标;普通发布成功留下的 effective 与
recovery_verified 只是引用、不决定原产地;无捕获证据或源/目标同时成立仍拒绝。
测试走真实基线登记形状(内部为业务真实字段),并保留"纯普通 effective 仍拒绝"。

3 handoff 阶段写入不完整:SyncStages 没有 handoff 行,UpdateLibraryStage 只是 0 行;
初始 running 是"读 owner 再写"(有竞态);成功后按旧 owner 写阶段必 0 行。
现改为三个事务方法:BeginLibraryHandoff(建/推进 running 且在同一事务内确认所有权)、
CompleteLibraryHandoff(同一事务:投递发布作业 + 交接 queue_job_id + 阶段 succeeded)、
FailLibraryHandoff(同一事务:阶段 failed + 作业 failed,不留半条记录)。
阶段行 (job_id, stage) upsert。测试断言交接后 handoff 阶段行真实存在且为 succeeded、
迟到执行对 stage 与 job 零改写(用屏障确定性把所有权切给 release)。

清理:删除被上述事务方法取代的 AdvanceLibraryJobIfActive 与 FailLibraryHandoffIfOwner,
避免同一含义两套实现。

验证:隔离 fixture PostgreSQL(真实迁移/队列/完成事件)+ 本 SHA 的 libraryctl 实跑
cmd/worker 全包通过;internal 全包与 go vet 通过。未部署、未推送;云 SSH/UI 仍未验证。
2026-10-30 19:32:28 +08:00
..
2026-10-30 16:16:45 +08:00