🔴 事故(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>
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| ai-gen-script.cli.ts | Loading commit data... | |
| backfill-plan-labels.cli.ts | Loading commit data... | |
| bootstrap-flags.ts | Loading commit data... | |
| cold-import.cli.ts | Loading commit data... | |
| dump-openapi.cli.ts | Loading commit data... | |
| host-admin.cli.ts | Loading commit data... | |
| import-patient.cli.ts | Loading commit data... | |
| import-real-phones.cli.ts | Loading commit data... | |
| recompute-persona.cli.ts | Loading commit data... | |
| recompute-plans.cli.ts | Loading commit data... | |
| refresh-clinic-names.cli.ts | Loading commit data... | |
| reparse-patients-file.ts | Loading commit data... | |
| reparse.cli.ts | Loading commit data... | |
| seed-assignment.cli.ts | Loading commit data... | |
| stale-scan.cli.ts | Loading commit data... | |
| sync-incremental.cli.ts | Loading commit data... | |
| sync-test.cli.ts | Loading commit data... | |
| timeline.cli.ts | Loading commit data... | |
| verify-chain.cli.ts | Loading commit data... | |
| verify-field-mapper.ts | Loading commit data... | |
| verify-gap-equivalence.cli.ts | Loading commit data... |