Răsfoiți Sursa

docs: 记录 2026-11-01 夜间同步核查结果(用户主动停用,未运行无回执)

彭峰 14 ore în urmă
părinte
comite
89cdbeec25
1 a modificat fișierele cu 115 adăugiri și 0 ștergeri
  1. 115 0
      docs/migration/nightly-legacy-sync-check-2026-11-01.md

+ 115 - 0
docs/migration/nightly-legacy-sync-check-2026-11-01.md

@@ -0,0 +1,115 @@
+# 夜间同步核查记录 · 业务日 2026-11-01
+
+> 性质:只监测、不重复执行的核查。本轮未启动任何同步、未走同步桥、未 claim、未抢租约、未删除目录锁、未读取或输出任何凭据。
+
+## 一、结论
+
+**业务日 2026-11-01(Asia/Shanghai)夜间同步:未运行(not_run),无成功回执。**
+
+未运行的原因经定位为 **用户主动停用**:用户于 2026-11-01 16:57(本地时间)要求「从今天起先停止每日 23:00 的同步任务」,并执行了 `launchctl disable` + `launchctl unload`。LaunchAgent 处于 disabled 状态属**预期状态**,不构成同步系统故障。
+
+因此本轮**不判定为失败**,也**不触发打扰式通知**;仅按核查要求留档。
+
+需要留意的前提事实:业务日 2026-11-01 全天**没有任何一次同步执行**,新系统该日数据未从旧系统补齐。
+
+## 二、LaunchAgent 定义与实际触发
+
+| 项目 | 核查结果 |
+| --- | --- |
+| plist 路径 | `/Users/mac/Library/LaunchAgents/cn.xiaoshu.legacy-direct-sync-nightly.plist`(存在,mtime 2026-10-15 00:04) |
+| 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` —— **与预期一致** |
+| RunAtLoad / KeepAlive / ThrottleInterval | `true` / `SuccessfulExit=false` / `300` —— 每 5 分钟失败重试的定义仍在 |
+| node 可用性 | `/usr/local/bin/node` 存在,v22.17.0 |
+| 独立运行目录 | `~/Library/Application Support/XiaoshuSync/scripts/` 完整,含 `lib/legacy-direct-projection.mjs`、`lib/legacy-direct-specs.mjs`、`lib/sync-alerts.mjs` |
+
+**实际触发情况:**
+
+- `launchctl print gui/501/cn.xiaoshu.legacy-direct-sync-nightly` → `Could not find service ... in domain for user gui: 501`,即该 job **未注册**(已被 unload)。
+- `launchctl list` 中 530 个 job 内**无**该服务。
+- `launchctl print gui/501` 的 disabled 列表中明确列出 `"cn.xiaoshu.legacy-direct-sync-nightly" => disabled`。
+- `/var/db/com.apple.xpc.launchd/disabled.501.plist` 中该键值为 `<true/>`,文件 mtime **2026-11-01 16:57(本地时间)**。
+- 因服务未加载,`runs` 计数与 `last exit code` 无法取得。
+
+**停用来源(关键):** 工作区日志 `.workbuddy/memory/2026-11-01.md`(mtime 同为 2026-11-01 16:57)记载:用户要求「从今天起先停止每日 23:00 的同步任务」,已执行 `launchctl disable gui/501/cn.xiaoshu.legacy-direct-sync-nightly` 与 `launchctl unload` 同 plist,当前会话已卸载、无运行实例,plist 文件保留可恢复。
+
+**环境前提核查(排除「未开机/未登录」误判):** 机器 uptime 2 天 15 小时,控制台会话自 2026-10-30 07:51 起持续存在。本次未运行**不是**关机或未登录造成,也与凭据、网络、桥无关,纯粹是调度被主动停用。
+
+**23:08 观察点复验(确认 23:00 确未触发):** 23:08:42 CST 复查 —— 22:55 之后无新报告文件;`launchagent.log` mtime 仍为 `2026-11-01 01:29:26`(未追加);`launchctl print gui/501` 仍显示 `disabled`;无残留目录锁。属确定性终态,无需继续轮询。
+
+## 三、本机私有状态目录(业务日 2026-11-01)
+
+业务日 2026-11-01 共 5 份运行报告,**全部为 blocked**,均发生在停用之前(当日凌晨),被上一业务日运行的服务端租约阻塞:
+
+| 报告文件 | 起(CST) | 状态 | 原因 | failed |
+| --- | --- | --- | --- | --- |
+| `2026-11-01-direct-1ff12f46….json` | 11-01 00:05:10 | blocked | `another_sync_running` | 1 |
+| `2026-11-01-direct-e4d663c5….json` | 11-01 00:15:11 | blocked | `another_sync_running` | 1 |
+| `2026-11-01-direct-5cf5ba2a….json` | 11-01 00:25:11 | blocked | `another_sync_running` | 1 |
+| `2026-11-01-direct-ce49018b….json` | 11-01 00:35:11 | blocked | `another_sync_running` | 1 |
+| `2026-11-01-direct-645dd2fe….json` | 11-01 00:45:13 | blocked | `another_sync_running` | 1 |
+
+这 5 次为 5 分钟间隔重试,被业务日 2026-10-31 的 runId `579148c2…`(直至 11-01 01:29 才完成)所持的服务端租约阻塞。按约束,**本轮未干预该租约**。
+
+- 00:45 之后至 23:0x,**无任何新的运行报告、无新的日志写入**;16:00 之后目录内除停用相关外无新运行结果。
+- 当日**不存在**人工批次验收文件(不把任何下午/凌晨人工批次计为当晚 23 点运行)。
+- **目录锁**:`~/.local/state/xiaoshu/legacy-sync/direct-nightly.lock` **不存在**,无残留锁需要清理,本轮未删除任何锁。
+- `direct-alert-state.json` 仍为 `{"failed":false,"lastKey":"recovered",...}`(01:29 成功时写入),**尚未反映本日未运行**——告警状态只在进程实际运行时更新,本次因进程从未启动而无更新。后续核查应以服务端 runs 与本机报告为准,不以该文件判定当日结果。
+
+### 关于 `launchagent-error.log` 的排除说明
+
+错误日志尾部存在 `ERR_MODULE_NOT_FOUND: …/scripts/lib/sync-alerts.mjs`。经核对,该日志文件 mtime 为 **2026-10-17 23:01**,属 10-17 的**历史**错误;当前 `lib/sync-alerts.mjs` 实际存在(1,989 字节,mtime 2026-10-15 00:04)。**该错误与 2026-11-01 状态无关**,不作为本次根因。
+
+## 四、服务端只读状态(`action:'status'`,无写操作)
+
+只读查询 `xiaoshu/sync/direct-v1`,返回 `version=2026-10-14-finance-ledger-v3`、`source=old-api/WXAPP`、`bridgeUsed=false`。运行记录仅 3 条:
+
+| 业务日 | runId | 状态 | startedAt(Z) | finishedAt(Z) | failed | 9 数据集 reconciled |
+| --- | --- | --- | --- | --- | --- | --- |
+| 2026-10-31 | `579148c2…` | completed-with-preserved-conflicts | 2026-10-31T15:00:06.098Z | 2026-10-31T17:29:15.274Z | 0 | 全部 true |
+| 2026-10-30 | `fcb3e9d7…` | completed-with-preserved-conflicts | 2026-10-30T15:00:07.266Z | 2026-10-30T16:06:17.358Z | 0 | 全部 true |
+| 2026-10-29 | `5a26a6c5…` | completed-with-preserved-conflicts | 2026-10-29T15:00:04.935Z | 2026-10-29T15:35:05.711Z | 0 | 全部 true |
+
+**服务端不存在业务日 2026-11-01 的任何运行记录**(无 runId、无 startedAt、无 finishedAt、无回执)。这与本机「零次成功执行」完全一致。最近一次成功回执仍为业务日 **2026-10-31**。
+
+## 五、成功回执验收清单(业务日 2026-11-01)
+
+| 验收项 | 结果 | 说明 |
+| --- | --- | --- |
+| 9 个业务数据集(专项训练、词库、课程绑定、每日学习、练习、抗遗忘、预约、上课、测评)业务 ID / 主附表 / 校验和核验 | ✗ 未执行 | 服务端与本机均无当日数据集记录 |
+| 每个数据集 `reconciled=true` 且每业务编号恰一份主表 | ✗ 未执行 | 同上 |
+| 账号只新增并匹配旧用户编号、栏目只补缺 | ✗ 未执行 | 无补缺结果 |
+| 财务分组(stype=1/2/3/4)回读核对 | ✗ 未执行 | 当日回执不包含 |
+| `failed=0` | ✗ | 5 次尝试均 `failed=1`(blocked) |
+| 锁已释放 | ✓ | 目录锁不存在;但非因成功释放 |
+| 来源 `old-api/WXAPP` 且 `bridgeUsed=false` | — | 未产生运行,无从判定 |
+| `settlementReady` | — | 未设置(本方案本就不设置) |
+
+**结论:验收清单全部不满足,不存在 2026-11-01 成功回执,不得报成功。**
+
+## 六、与上次状态的差异
+
+- 上一基线:业务日 **2026-10-31** = `completed-with-preserved-conflicts`,runId `579148c2…`,新增 1,072 / 更新 182 / 失败 0 / 保留冲突 4,204,9 数据集与财务分组全部 reconciled,锁已释放,真实 23:00 触发(23:00:06 起)。身份冲突(旧编号 1871)已于 11-01 00:50 处置完成。
+- 本次:业务日 **2026-11-01** = **未运行**,原因 `launchagent_disabled_by_user_request`。
+- 变化类别:**`success_to_stopped_by_user_request`** —— 由成功转为主动停运,非系统故障。上一阻塞项 `legacy_account_identity_conflict` 已彻底消除(10-31 处置后 identityConflicts=0),当前不存在任何数据层阻塞。
+
+## 七、状态与待办(本轮未执行)
+
+1. **停用状态持续**。在用户重新启用前,2026-11-02 及以后的 23:00 均不会触发,逐日数据缺口会持续累积。
+2. 恢复命令(**本轮未执行**,需用户决定):
+   ```bash
+   launchctl enable gui/$(id -u)/cn.xiaoshu.legacy-direct-sync-nightly
+   launchctl load ~/Library/LaunchAgents/cn.xiaoshu.legacy-direct-sync-nightly.plist
+   ```
+   **提示**:该 plist 含 `RunAtLoad=true`,启用并加载后 launchd 会**立即补跑一次当前业务日的同步**。这是真实执行动作,超出「只监测」边界,故本轮未执行。
+3. 停运期间逐日缺口:2026-11-01 已产生 1 天空档;恢复后如需补齐,应按业务日逐日回溯执行,而非一次性覆盖。
+4. 夜间核查自动化本身**未被停用**,仍会每夜留档。若用户希望一并停止核查自动化,需另行处理。
+
+## 八、通知判定
+
+本次**不触发打扰式通知**。依据:未运行系用户当日 16:57 明确要求停用所致,属预期状态,非「重大失败变化」;用户已知晓该操作,重复提醒属噪音。本结果仅写入本地私有报告、本核查记录与自动化概览。
+
+---
+
+*本报告不含任何凭据、会话令牌或主密钥内容。*