性质:只监测、不重复执行的核查。本轮未启动任何同步、未走同步桥、未 claim、未抢占服务端租约、未删除目录锁、未自动解决冲突、未读取或输出任何凭据内容。凭据文件仅用于
node --env-file=加载。
业务日 2026-11-03(Asia/Shanghai)夜间同步:未完成 / 阻塞,无服务端成功回执。 终态未出现(本轮不宣称终态),验收清单全不满足。
--scheduled 入口拉起,runId 5f2ddc11-0139-4356-a2f6-052e1bfb5c33。blocked,原因 legacy_account_identity_conflict: resolve reading-generated IDs before syncing business records,identityConflicts=1、failed=1、datasets=[]。xiaoshu/sync/direct-v1 只读 status 中该 run 仍为 running,finishedAt=null、summary=null —— 没有成功回执。保留新系统修改、账户余额、课时、人工确认与复习计薪凭据的要求未被破坏:本次根本没有进入业务投影阶段。settlementReady 按设计始终为 false,未伪造。
| 项目 | 核查结果 |
|---|---|
| plist 路径 | /Users/mac/Library/LaunchAgents/cn.xiaoshu.legacy-direct-sync-nightly.plist |
| ProgramArguments | /usr/local/bin/node + --env-file=/Users/mac/.config/xiaoshu/legacy-sync-nightly.env + ~/Library/Application Support/XiaoshuSync/scripts/run-nightly-direct-sync.mjs + --scheduled —— 与预期一致 |
| EnvironmentVariables.TZ | Asia/Shanghai —— 与预期一致 |
| StartCalendarInterval | Hour=23 / Minute=0 —— 与预期一致 |
| 禁用状态 | launchctl print-disabled gui/501 中该 job 为 enabled(非 11-01 的用户停运态) |
| runs 计数 / last exit code | 23:00:53 首次读取 runs=2 / exit=1;23:40 收尾时 runs=10 / exit=1(每 5 分钟一次失败重试) |
| launchd 状态 | spawn scheduled,active count 在重试瞬间为 1;minimum runtime=300 |
实际触发证据(三重一致):
startedAt = 2026-11-03T15:00:07.605Z(北京时间 23:00:07),businessDate=2026-11-03,runId=5f2ddc11-…;startedAt = 2026-11-03T15:00:11.147Z(北京时间 23:00:11),业务日 2026-11-03;launchagent.log 尾部出现 {"status":"blocked","reason":"legacy_account_identity_conflict: …","runId":"5f2ddc11-…"},且 23:05/23:15/23:25/23:35 的 5 分钟重试报告均为 blocked。环境前提: 机器开机且该用户已登录控制台会话(launchctl print gui/501 可用),不是关机/未登录导致的「未运行」。这是真实 23:00 日历触发,不是唤醒补跑;Codex/聊天窗口是否关闭不影响 LaunchAgent。
launchagent-error.log: 文件 mtime 为 2026-10-17,尾部 ERR_MODULE_NOT_FOUND sync-alerts.mjs 与「同步通知发送失败」均为 10-17 历史残留,与本轮无关;该模块当前存在。本轮真实失败原因以 launchagent.log 的 blocked 行为准。direct-alert-state.json 为 {"failed":true,"lastKey":"failure","notifiedAt":1793718015856(23:00:15),"conflicts":3872,"lastSuccessAt":1793710469429(20:54:29)} —— 告警状态由 23:00 的失败运行置位,非新的独立故障。
主报告:~/.local/state/xiaoshu/legacy-sync/2026-11-03-direct-5f2ddc11-0139-4356-a2f6-052e1bfb5c33.json(0600)。该文件在每 10 分钟的主重试中被同一 runId 覆写,末次内容:
| 项目 | 值 |
|---|---|
| businessDate / runId | 2026-11-03 / 5f2ddc11-0139-4356-a2f6-052e1bfb5c33 |
| status | blocked |
| 末次起止(UTC / 北京) | 15:40:10.906Z → 15:40:16.227Z / 23:40:10 → 23:40:16 |
| reason | legacy_account_identity_conflict: resolve reading-generated IDs before syncing business records |
| failed / datasets | 1 / [](0 个数据集) |
| source / bridgeUsed | old-api/WXAPP / false |
| accounts 前置扫描 | source 750 / created 0 / matched 745 / missing 0 / conflicts 172 / excluded 4 / identityConflicts 1 |
| nodes 前置扫描 | source 461 / created 0 / matched 461 / missing 0 |
| existingAccountBalancesUntouched | true |
| settlementReady | 未设置(按设计为 false) |
5 分钟重试序列(全部 blocked,只记录、不干预):
| 时间(北京) | 原因 |
|---|---|
| 23:00 / 23:10 / 23:20 / 23:30 / 23:40 | legacy_account_identity_conflict(主 runId 报告被覆写) |
| 23:05 / 23:15 / 23:25 / 23:35 | another_sync_running(并发/服务端租约占用) |
another_sync_running 与服务端租约占用均按约束仅记录,未抢占租约、未删除目录锁。目录锁在运行器各次重试之间自行释放;23:40 观测到一次仍在运行的重试进程与短暂存在的锁目录,未对其做任何处置。
排除在终态判定之外的记录(不把下午/凌晨人工批次当 23 点运行):
| 文件 / runId | 时间(北京) | 状态 | 排除理由 |
|---|---|---|---|
2026-11-02-direct-22a1d53e-4943-4902-934e-85d8e0e60006.json |
11-03 20:54 | already_completed |
傍晚补跑/人工批次,业务日仍为 2026-11-02,仅回读既有成功回执,不是当晚 23:00 运行 |
12f01ee1-90b8-46d5-8f5a-73fe95515ee0 |
11-02 23:00–23:39 | completed-with-preserved-conflicts |
上一业务日成功回执,仅作基线比对 |
action:'status')查询方式:node --env-file=<凭据文件> tmp/direct-v1-status-check.mjs(只发 action:'status',不建锁、不抢租约、不启动同步;输出对 token/secret/key/password/session 类字段脱敏)。全程未读取或输出凭据内容。
| 项目 | 服务端 | 本机 |
|---|---|---|
| businessDate | 2026-11-03 |
2026-11-03 |
| runId | 5f2ddc11-0139-4356-a2f6-052e1bfb5c33 |
同 |
| status | running |
blocked |
| startedAt | 2026-11-03T15:00:11.147Z |
15:00:07.605Z(首次) |
| finishedAt | null |
每轮重试有 finishedAt(仅表示单轮退出,非成功回执) |
| summary | null |
无(datasets 为空) |
| 9 数据集 / 财务回读 | 无 | 无 |
服务端仅返回 10-29/10-30/10-31、11-01/11-02 与本次 11-03 的 run;11-03 无 finishedAt、无 summary,因此不存在可验收的成功回执。服务端 status=running 与本机 status=blocked 不一致,不满足「终态判定必须基于服务端回执 + 本机报告一致」的条件,故本轮不判定为终态。
| # | 验收项 | 结果 | 证据 |
|---|---|---|---|
| 1 | 9 个业务数据集服务端业务 ID、主表与关联附表、校验和核验 | 未通过 | 9/9 未执行;无 reconciled、无 sourceIdChecksum/targetChecksum |
| 2 | 每个业务编号恰有一份主表 | 未通过 | 无 allCapturedSourceIdsReconciled,无对账证据 |
| 3 | 账号只新增并匹配旧用户编号 | 未通过 | 前置扫描 identityConflicts=1,身份冲突未解决,业务投影被中断;created=0 但无法核验通过 |
| 4 | 栏目只补缺 | 未通过 | 前置扫描 461/461 / created 0 / missing 0,但未进入写入与回读核验 |
| 5 | 财务分组(会员流水 stype=1/2/3/4)回读核对 | 未执行 | datasets=[],无 finance 字段、无 reconciled |
| 6 | failed=0 |
未通过 | 本机每轮 failed=1 |
| 7 | 锁已释放 | 未通过(服务端租约仍占用) | 服务端 run status=running、finishedAt=null;目录锁在重试间隙释放,本轮未删除任何锁 |
| 8 | 来源 old-api/WXAPP 且 bridgeUsed=false |
元数据一致但不构成成功 | 两份报告均标注该来源与 false,但未走同步桥 |
| 9 | 保留新系统修改、余额、课时、人工确认、复习计薪凭据 | 未被破坏 | existingAccountBalancesUntouched=true;未发生业务写入;冲突仅记录、不自动解决 |
9 个数据集明细(全部 executed=false / reconciled=false):专项训练、词库、课程绑定、每日学习、练习记录、抗遗忘、预约、上课、测评。
running/finishedAt=null;主报告始终 blocked / legacy_account_identity_conflict / identityConflicts=1 / failed=1 / datasets=0;runs 由 3→5→7→9(23:40 收尾时为 10),last exit code 恒为 1。incomplete_blocked / failure_no_success_receipt;不宣称同步彻底失败(重试仍在进行、租约仍被持有),但按「没有服务端真实回执就报失败/未完成」如实报告未完成。legacy_account_identity_conflict,新增 1 处阅读账号生成的编号与旧系统身份冲突(11-02 时 identityConflicts=0)。| 维度 | 2026-11-02(上次核查) | 2026-11-03(本次) |
|---|---|---|
| 终态 | completed-with-preserved-conflicts(成功回执) |
未出现终态,incomplete_blocked |
| 服务端回执 | finishedAt 非空、summary 完整 |
finishedAt=null、summary=null |
| 9 数据集 / 财务 | 9/9 reconciled=true,财务 rows 42,282 reconciled=true |
0/9 执行,财务未执行 |
| failed | 0 | 1(每轮重试) |
| 阻塞项 | 无 | legacy_account_identity_conflict |
| 账号 source / conflicts / identityConflicts | 749 / 170 / 0 | 750 / 172 / 1 |
| runs / last exit code | 2 / 0 | 10 / 1 |
| 变化分类 | — | success_to_failure_new_identity_conflict,严重级别:重大 |
identityConflicts=0 变为 1,与上次状态不同。another_sync_running 继续被阻断;工资结算所需新鲜度高于本任务的一日一次节奏,settlementReady 按设计始终为 false。~/.local/state/xiaoshu/legacy-sync/heartbeat-23-status-2026-11-03.json(0600,含业务日、runId、终态、失败原因、9 数据集与账号/栏目补缺核验、差异、通知判定,不含任何凭据)~/.local/state/xiaoshu/legacy-sync/2026-11-03-direct-5f2ddc11-0139-4356-a2f6-052e1bfb5c33.json(0600)docs/migration/nightly-legacy-sync-check-2026-11-03.md