Commit 8d6664c8 by luoqi

fix(sync): CLI 启动会清掉正在跑的同步锁 —— 生产实测夭折一轮增量

🔴 事故(2026-08-30 生产):在 pac-service 容器里 docker exec 跑 recompute-plans,
   08:17:11 起进程 → 08:17:13 正在跑的 08:15 那轮同步被标 failed。前 19 轮全 success,
   只死了撞上的这一轮。数据未丢(cursor_after=null,下轮同水位 catchup),但白丢一轮。

根因:每个 CLI 都 createApplicationContext(AppModule) → 跑一遍
SyncIncrementalScheduler.onModuleInit → reapStaleRunningLocks。
原判据是「startedAt < 本进程启动 = 僵尸锁」,注释里写着"两者的进程都不可能比本进程
启动得更早还活着"—— 但**长驻的 pac-service 恰恰就是那个更早启动还活着的进程**。
理由写反了方向,而且只在"回收逻辑跑在长驻服务里"时才成立。

两道防线:
① scheduler 加年龄阈值 REAP_MIN_AGE_MS=3h —— 真僵尸锁必然躺很久,正在跑的不会。
   用年龄区分,不靠猜进程身份。(生产单轮摄入实测 28~52 分钟)
② 新增 src/cli/bootstrap-flags.ts,16 个 CLI 在建上下文**之前**设
   PAC_SCHEDULER_DISABLED=1(该总闸本就会跳过回收,只是没人用)。
   豁免 sync-incremental.cli(它就是要触发同步),由 ① 兜底。

回归测试 tests/cli-scheduler-guard.spec.ts:遍历所有会建上下文的 CLI,
断言调用存在**且位置早于** createApplicationContext;并锁住年龄阈值 ≥2h。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
parent 0c76093a
Pipeline #3630 failed in 0 seconds