# 待办 / 问题登记（TODO_ISSUES）

> **用途**：集中登记**已知但尚未解决**的问题。cronjob 发现的问题与平时排查发现的问题**一律写入本文件并标注日期**，慢慢消灭。
> **约定**：
> 1. 人工登记写进「一、人工登记」区，**按日期倒序**（最新在最上面），每条标 `日期 / 问题 / 位置 / 严重度 / 状态`。
> 2. 「二、日跑自动记录」区由 `~/.hermes/scripts/daily_run_log.py`（cron `06da696372dc`，每日 10:00）**自动追加**，勿手改该区块。
> 3. 状态用：`待办` / `进行中` / `已修复(日期)` / `不修(原因)`。修复后**不删行**，改状态并补日期——保留决策痕迹。
> 4. 三处同步（改完务必核 md5）：
>    - 服务器 `/root/gov_crawler/TODO_ISSUES.md`
>    - 本地 `~/Crawler/gov_crawler/TODO_ISSUES.md`
>    - 坚果云 `~/Nutstore Files/Crawler/gov_crawler/TODO_ISSUES.md`

**当前未解决条目数**：见下方各表 `状态=待办/进行中` 的行。

---

## 一、人工登记（按日期倒序）

### 2026-09-14

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 1 | **双向同步的推送方向未排除「服务器托管的状态文件」**：`notion_pushed_urls.json`(9.3MB) 与 `run_status.json`(566KB) 属日跑运行时状态（服务器写），却落在同步的 `*.json` 白名单内，而推送方向同样带 `--update`（＝本地较新即覆盖服务器）。若本地出现更新的同名副本（手动改、或本地跑一次相关脚本），就会把服务器生产状态**推回覆盖**——与 2026-08-24 ZC.db 被本地旧备份覆盖属同一类事故 | `~/.hermes/scripts/sync_gov_crawler.sh`（LOCAL_DIR=坚果云镜像，rsync include `*.json`） | 中 | 待办 | 2026-09-14 02:46 本 cron 巡检发现；本次运行**推送 0 文件**（未发生覆盖），当前两侧 mtime 相同故稳态无风险，属潜伏项。候选处置：仅对推送方向加 `--exclude=notion_pushed_urls.json --exclude=run_status.json`（拉取仍保留），或把状态文件移出 `gov_crawler` 目录 |
| 2 | 坚果云客户端 `all_sandbox_list` 中名为 **Crawler** 的同步根 `doNotSync=false`（同步已启用），但云端记账 `usedSpace=0`，而本地 `~/Nutstore Files/Crawler` 实体有 gov_crawler 镜像 87MB → 「该镜像是否真在云上」待核实 | 坚果云 `Crawler` sandbox（id 29897256，本地建根时间≈2026-08-26） | 低 | 待办（待核实） | 2026-09-14 巡检记录，未定性。核实方法：坚果云网页端查该同步文件夹内容与占用；另 `~/Nutstore Files/Mac-爬虫`（sandbox 29844236，usedSpace 2.3MB）本地无对应目录 → 本地↔根映射需一并确认。注意历史坑：仅「路径在 ~/Nutstore Files 下」不等于已上云 |
| 3 | **明文 root 密码散落**：已启用的 cron「每日爬虫配置校验」prompt 里明文写着服务器 root 密码（`sshpass -p '...'`），已删除的 `pull-gov-crawler-snapshot-to-onedrive` 同样带密码 → 消费方已全量清零，但旧密码仍存 **384 个文件 / 3,075 处**，**只有轮换能真正收尾** | `~/.hermes/cron/jobs.json` + `~/.hermes/sessions/*`(288 文件/2,904 处) + `cron/output`(69) + `skills`(17) + `logs`(3) + `.curator_backups`/`state-snapshots` + 备份树 | 中 | 待办（**消费方已清零，轮换已解锁**） | 2026-09-14 处置：①删除 `pull-gov-crawler-snapshot-to-onedrive`（目标目录 4.5GB 已由用户清理，且已有密钥通道）②`每日爬虫配置校验`(`8211569f7054`) 改 `ssh -o StrictHostKeyChecking=no hw-backup` 免密，实跑 `EXIT:0`（2101 条配置/2065 脚本/无孤儿）；`jobs.json` 内 `sshpass` 与密码值均 **0 次** ③实测密钥免密在 cron 环境可用（`env -i HOME PATH=… ssh -o BatchMode=yes` → `CRON_KEY_OK`；两私钥均无 passphrase）④`~/.hermes/scripts/backup_server_dbs.sh` 早已免密（2026-09-10 改，仅注释含 "sshpass" 一词，非调用）⑤服务器 crontab / 活目录无 sshpass，命中仅在 `Archive/legacy_sync_20260910` 与 `Archive/gov_crawler_DUP_20260910`。**剩余：用户自行在服务器 `passwd` 轮换 → 助理再验证旧值被服务端拒绝**（按技能规矩勿经聊天传新密码）。顺手修复技能脚本 bug：`scan_plaintext_secrets.py` 的 `scan_blob()` 对 str 调 `data.count(tok.encode())` → `TypeError: must be str, not bytes`，已改为先统一转 bytes |
| 4 | **IC13 导入被 1 条 id_code 冲突拖死整批**：`import_ic13_dedup.py` 的 `existing` 只查 `source='pharma'`，而 `idx_tsk_data_id_code` 是**全库**唯一索引 → 某 id_code 已作为 cpi/plant 存在时被误判为「新增」→ `executemany` 裸 INSERT 撞 UNIQUE → **整批回滚，同批其余新增记录一并丢失**（实测 20 文件中 18 条因此未入库；09-10 起每天可能静默发生） | `/root/scripts/import_ic13_dedup.py` ——**不在三处同步范围**（`sync_gov_crawler.sh` 的 `REMOTE_DIR` 只覆盖 `/root/gov_crawler`），且此前**无任何服务器外副本** | 高 | ✅ **已修复(2026-09-14)** | 三处改动，md5 `0aa4a83b` → `c17c39c2` → `cb9ec7fe`：①`existing` 改按 id_code **全库**取（与唯一索引语义一致：一个 id_code 只应有一行）②UPDATE 去掉 `AND source='pharma'`（否则命中 cpi/plant 行时该 id_code 的新内容永远进不来）③`conn.text_factory` 加容错解码——改成全库取之后会扫到历史坏行（content 非 UTF-8），默认 factory 直接抛 `sqlite3.OperationalError: Could not decode to UTF-8 column 'content'` 中断整批（这是修完①才暴露的第二层 bug）。**验证**：重跑 `Updates: 2 / New inserts: 36 / Skipped: 2 / Errors: 0`，`IMPORT_RC=0`；总数 **70054 → 70093**，此前被拖死的 301225594/301226004/301226696/301227454/301227828 等全部落入；冲突样本 `301001336` 保持 `source='cpi'` 且 content **815 → 2825**（新内容正确追加）；`HAVING COUNT(*)>1` 重复 id_code = **0**；完整编排器再跑 **rc=0 全静默**（两引擎无变化）。备份 `.bak_20260914_pre_unique` / `.bak_20260914_textfactory`；修复版已另存服务器外副本 `~/.hermes/backups/server_scripts/import_ic13_dedup.py`。**遗留建议**：`/root/scripts/` 整目录不在任何备份链路，宜纳入 |
| 5 | **坚果云 WebDAV PROPFIND【截断】→ ZC 数据 71% 对引擎不可见**：`zc_webdav_list()` 实测源目录有 **2634 个条目**，却只返回 **751 个 `<response>`（743 个 PDF）** —— 其余 1885 个文件等于不存在。表现为 `新增: 0, 跳过: 743`、**12 秒跑完、rc=0、无任何告警**（最危险处：完全静默）。用户报「/zc/ 没有 11 号的数据」即此因：那些文件一直躺在坚果云目录里，只是从未被看见 | `ccpc_zc_sync.py` 的 `zc_run()` / `zc_webdav_list()`；源目录 = 坚果云 `Downloads_nuc` | 高 | ✅ **已修复(2026-09-14)** | **工作流按用户指令改为「先走坚果云本地同步目录，走不通再回落 WebDAV」**：① 新增 Mac 端 `~/.hermes/scripts/zc_push_fresh.sh`（rsync 坚果云 `~/Nutstore Files/Downloads_nuc` → 服务器 `/mnt/data/zc_pdfs`，`--ignore-existing` 只补缺，成功时静默）+ cron **`043de840b37a` 每日 02:05**（`deliver=local` 成功静默 / `failure_deliver=telegram` 失败告警），排在服务器 ZC 段 02:30 之前 ② `zc_run()` 改为**优先迭代本地镜像目录**（日志 `源=local`），目录为空才回落 WebDAV 并在日志写明截断风险 ③ 顺带硬化：下载成功也记日志（原来成功不打日志，「到底下没下」无从判断）、下载失败由静默 `continue` 改为**计数 + rc=1**。**回填实测**：服务器镜像 1308 → **2628**（= 本地坚果云 PDF 数，rsync rc=0）；入库 `源=local 新增: 747, 跳过: 1881, 下载: 0, 失败: 0`，**ZC.db 1664 → 2411 条**（zc_contacts 8450）。**验收**：publish_date **09-11 由 0 → 3 条**、09-13 由 2 → 7、09-14 由 0 → 2 —— 用户报的问题消失。备份 `Archive/ccpc_zc_sync.py.bak_20260914_zclocal`、`/root/ZC.db.bak_20260914_presync`。⚠️ 附带坑：bash 中 `$VAR）`（中文全角括号紧跟变量名）会被当作变量名的一部分 → 未定义报错，必须写 `${VAR}`
| 6 | **CCPC 引擎同样被坚果云 WebDAV 截断**：本地坚果云三目录实测 **5688** 个 office 文件（4415 / 1048 / 225），WebDAV PROPFIND 只列到 **1587** 个（748 / 623 / 216）—— 仅 **27%**，约 4301 个文件对引擎不可见 | `ccpc_zc_sync.py` 的 `ccpc_run()` / `ccpc_webdav_list()`；源目录 = 坚果云 `Downloads` / `下载1` / `Downloads2` | 高 | ✅ **已改造(2026-09-14)** | 与 ZC 同一策略（用户指令「先走坚果云，走不通再 WebDAV」）：① 新增 Mac 端 `~/.hermes/scripts/ccpc_push_fresh.sh`（rsync 三个坚果云目录 → 服务器 `/mnt/data/ccpc_src/{Downloads,下载1,Downloads2}`，`--ignore-existing` 只补缺、**成功静默**）② `ccpc_run()` 列文件改为**本地镜像优先**（日志打 `[本地镜像] <子目录>: N files`），目录缺失/为空才回落 WebDAV（打 `[WebDAV]`）；取文件同样镜像优先 `shutil.copy2` 而非下载 ③ 与 ZC 推送器**合并为单 cron 入口** `push_nutstore_mirrors.sh`（符合用户既有偏好「同类每日同步合并为薄编排器：单 cron 入口 + 各引擎保留自身处理」），cron `043de840b37a` 每日 02:05（成功静默 / 失败 telegram 告警）。**回填实测**：镜像 5688 文件（rsync rc=0，25 秒）；入库 `Total: 5688 files → Done: +42 U5645 err1`（err1 = 一个源 docx 本身损坏：`Bad offset for central directory`），**ccpc.db 6122 → 6164 projects**、`cceup_contacts` **15053 → 16520**，rc=0，`search_app` active。备份 `Archive/ccpc_zc_sync.py.bak_20260914_ccpclocal`
| 7 | **正文双编码乱码（用户报样本）**：山东佳兆科技…第一次信息公示（id `2097613798365842865`，68883 字）正文为「UTF-8 字节被当 Latin-1 解码后又存成 UTF-8」（`å¾®è½¯é\x9b\x85é»\x91` = 「微软雅黑」），整篇不可读 | `search.db` → `gov_raw.content`（巨野县政府链路：`crawl_juye.py` 3119 / `crawl_juye_env.py` 88 / script_name 空 119） | 中 | ✅ **已修复(2026-09-14)** | 巨野站共 **259 条**双编码。用 Level-4 CP1252 逐字节映射修复。⚠️ **必须同时修 `gov_raw.summary`** —— 触发器 `trg_gov_raw_fts_upd` 是用 `new.summary` 同步 `gov_search` 的，只修 content 修不到搜索层（实测该站 summary 本身没乱，故 summary 实变 0 条）。**分两轮**：严格签名（拉丁字母**紧邻** C1 控制符）命中 **168** 条；第二轮发现**签名漏检** —— `å®\x8bä½\x93`（= 宋体）是**字母 + 字母 + C1**，严格签名匹配不到，改用「标记字符 `åæäãèéïð` 存在 + `is_good_fix` 把关」补修 **91** 条（0 条被拒）。**验收**：`仍含 å/æ/ä = 0`、严格签名 `= 0`，抽样已显示 `font-family: 宋体` / `微软雅黑`，`search_app` active；可回滚备份表 `gov_raw_moji_bak_20260914`（3326 行）。⚠️ **爬虫侧无需改动**（`crawl_juye.py:83` 与 `crawl_juye_env.py:34` 都已设 `r.encoding='utf-8'`）→ 属历史遗留数据。**方法论补充给技能**：检测双编码别只用「字母紧邻 C1」的严格签名，CSS 字体名里是「字母+字母+C1」，会整批漏掉
| 8 | **ZC「项目主要采购设备」被并进「建设内容」**：`extract_basic()` 收集「建设内容描述」时只在 `该项目可能` / `温馨提示` 处 break，**没把 PDF 里紧跟其后的独立小标题「项目主要采购设备」当边界** → 整段设备清单被拼进建设内容（实测 **2397 / 2411** 条中招，尾部形如 `…生产能力。项目主要采购设备炉类：裂解炉、气化炉…`），而 `equipment_list` 全库只有 **3** 条有值 | `ccpc_zc_sync.py` 的 `extract_basic()`（ZC 引擎）+ 展示端 `search_app.py` | 中 | ✅ **已修复(2026-09-14)** | 三处改动：① 解析器加 `DESC_STOPS`（`项目主要采购设备`/`精准采购设备`/`工艺流程`/`项目工期及阶段进展`/`该项目可能`/`主要设备`/`温馨提示`/`项目基本信息`），建设内容遇任一小标题即收工；② 新增 `PE_STOPS` 单独抽取「项目主要采购设备」块入 `equipment_list` ——⚠️ **PE 的终止词绝不能含 `该项目可能` / `主要设备`**，这两个词出现在该块**正文内部**（块首常是「该项目可能用到的设备如下，供参考…」或「主要设备：原料贮槽…」），当终止词会把块从中间截断；旧回退路径改为仅在未取到时才生效；③ 展示端 `设备清单` 模块改名为「**项目主要采购设备**」（`render_project_detail_body` 的 ZC 分支 + `/zc/` 抽屉片段两处；CCPC 的 `render_cceup_detail_body` 有意不动）。**回填**：因被吞内容**已完整存在库中**，采用**纯字符串切分**（不重读 PDF）→ **2390 条切分 + 4 条仅清尾巴**；验收 `construction_content 仍含该小标题 = 0`、`equipment_list 非空 = 2393`；示例 ZC0001391328 建设内容 **618 → 415** 字、设备清单 195 字。备份表 `zc_projects_pe_bak_20260914`（2411 行）+ `/root/ZC.db.bak_20260914_pe`；解析器改动已用 `--zc-preview` 在示例 PDF 上实测正确拆开。📎 另注：设备块中位长度仅 **206 字符** —— 与源站第 2 页「温馨提示：此处仅显示部分所需设备，更多信息请登录官网查看」吻合，**源本身只给预览片段**，库内照实保留

### 2026-09-13

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 1 | 日报脚本「今日页已存在」判重只取首页 50 个子块（无翻页）→ 父页子页数达 50 后，最新页落到第 2 页，判重失效 → 同日重跑/次日会**创建重复日报页** | `~/.hermes/scripts/notion_daily_report.py` L415 | 中 | **已修复(2026-09-13)** | 实测父页 `3b5399b8` 当日已有 **49 个子页**（2026-07-27 起每天 1 个），距 50 仅差 1 天 → 「即将触发」的潜伏 bug。修法：判重改为翻页遍历全部子块（`page_size=100` + `start_cursor` 循环）。验证：修复后同日重跑输出 `⚠️ 今日日报已存在 … 跳过创建` + `✅ 已更新页面内容`；Notion API 独立复核当日页仅 **1 个**（id `3d9399b8-3c5b-8137-975a-de7c5c1460b4`，40 blocks） |
| 2 | `gov_raw` 总量读数数分钟内波动 ±150（560,466 → 560,320 → 560,469），站点数 2206↔2205 抖动 | `/root/search.db` 的 `gov_raw` | 低 | 不修（非数据丢失） | 排查：`gov_raw` 是**真表非视图**；脚本 total 即 `SELECT COUNT(*)`（无估算/缓存）。定位为**站点批量刷新窗口**（`DELETE FROM gov_raw WHERE site_name=…` 后重新 INSERT，见 `batch_refresh_tables*.py` / `clear_*.py`）——读到的是「删完未插完」的中间态；静止期连读 3 次均 560,469 稳定。影响：日报「今日净增」基线若恰好采到刷新间隙会偏小数百条。候选改进：基线取当日多次读数最大值，或错峰推送（现 07:30） |
| 3 | 日报的 CCPC / ZC 状态**读的是 09-10 已合并的旧单引擎日志**（`/var/log/ccpc_sync.log`、`/var/log/sync_zc.log`，mtime 停在 09-10）→ 永远显示同一条 09-10 的「Done」且判为 `✅ 正常`，**合并引擎 02:30 每天的真实结果完全看不到**（假绿） | `~/.hermes/scripts/notion_daily_report.py` `get_ccpc_status`/`get_zc_status` | 中 | **已修复(2026-09-13)** | 改为读合并引擎日志 `/var/log/ccpc_zc_sync.log`（09-13 02:31 最新）：按 `===== CCPC [` / `===== ZC [` 切块取最后一次运行；**新增新鲜度判据**（日志 mtime 日期 ≠ 服务器当日日期 → `⚠️ 日志未更新`；缺 `* OK` 标记 → `❌ 异常`），不再无条件报绿。站点区文案同步修正为「CCPC/ZC/联系人 合并同步 (cron 02:30)」。实测页面显示：`2026-09-13 02:31:07 \| Done: +0 U1587 err0 \| ccpc.db: 6122 projects, 15053 contacts` / `(2026-09-13) 新增: 0, 跳过: 743, ZC.db 总计: 1661 条` |

### 2026-09-12

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 1 | 本地 cron「坚果云增量同步」01:00 秒退 rc=1：`ModuleNotFoundError: No module named 'fitz'`。根因 = `hermes update` 于 9-11 19:20 重建 venv，清掉了 venv 里的 `fitz`/`python-docx`/`openpyxl`（它们只在系统 python3.9 用户 site-packages 里），而 cron 用的是 venv 解释器（3.11） | `~/.hermes/scripts/incremental_sync.py` + venv | 高 | **已修复(2026-09-12)** | 修法：入口加解释器自愈 bootstrap（探测必需模块 → 缺则 `os.execve` 到 `/usr/bin/python3`，env 标记防递归）。⚠️ 验证必须用 **venv 解释器**跑（手工用 `python3`=3.9 跑成功是假阳性，9-11 就踩过）。已全量扫其余启用中本地 cron 脚本依赖：无其它缺失。坑已入 `data-sync-pipeline-audit` 技能 |
| 2 | 同类隐患：任何依赖非 venv 自带第三方包的本地 cron 脚本，都会在 `hermes update` 重建 venv 后静默失败（每天只报 Script Error，不重试） | 全部本地 `~/.hermes/scripts/*.py` cron 脚本 | 低 | 待办 | 候选动作：① 给其余脚本也加 bootstrap；② 建专用 `~/.hermes/scripts/.venv`（bootstrap 已把该路径列为候选解释器）；③ `hermes update` 后加一步依赖自检 |
| 3 | 双向同步的范围盲区：`sync_gov_crawler.sh` 只覆盖 **服务器 ↔ 坚果云镜像**，第三处副本 `~/Crawler/gov_crawler` 不在同步范围，长期漂移——同名不同内容 2 个：`import_jsonl.py`（镜像已含 09-11 批量补的 `timeout=120`，`~/Crawler` 缺）、`rebuild_fts.py`（`~/Crawler` 1275B 是内容表重建版；镜像 497B 是已知 no-op 的 `INSERT ...('rebuild')` 版）；仅 `~/Crawler` 有 46 个非 Archive 文件，仅镜像有 267 个（`data/`、`utils/`、`*.sh` 启动器） | `~/Crawler/gov_crawler`（＝ `backup_gov_crawler.sh` 03:00 备份源 + `originals_sync.py` 运行处） | 低 | 待办 | 2026-09-12 02:46 同步后扫描发现，非本次同步引入。两个脚本均无调度器引用（`rebuild_fts` 仅 `crawl_ahjx` 内部自定义同名函数）。候选处置：① 把该目录纳入同步，或明确标注「工作副本、无需与镜像一致」；② 两个差异脚本各以镜像为准拉一次。**2026-09-14 02:46 本 cron 复核**：内容不一致 **6** 个——非 Archive **2** 个＝`import_jsonl.py`（镜像 `2c788c53` / 工作 `40389d24`）、`rebuild_fts.py`（镜像 `60304ce3` / 工作 `6cc1526c`），与 09-12 记录**完全一致（仍未处置）**；另 4 个在 `Archive/`：`crawl_anyi_xsthjj.py`、`crawl_wwhjbh.py`、`crawl_zjg_jsxmv.py`、`search_app.py`。仅工作副本有 **46** 个非 Archive / 仅镜像有 **267** 个非 Archive（与 09-12 计数一致，本日无新增漂移）。同次复核确认 **服务器 ↔ 坚果云镜像 4146 文件 md5 全量 0 差异**（双向同步链路本身健康） |
| 4 | **FTS 全量重建语句拖垮日跑（系统性根因）**：28 个活跃爬虫 + 模板 `base_crawler.py` 每天执行冗余的 `INSERT INTO gov_search(gov_search) VALUES('rebuild')`（`gov_search` 是普通 FTS5 表、且有 3 条触发器 `trg_gov_raw_fts_ins/del/upd` 维护，重建纯属多余）→ 单次 **400~600s** 且**整段独占 SQLite 写锁** → 日跑并联 3 个时写锁被连续霸占数小时，其它脚本撞 `database is locked` 被 `classify_error` 判成「脚本异常」 | 28 个 `crawl_*.py` + `base_crawler.py` | **高** | **已修复(2026-09-12)** | 替换为 no-op `SELECT 1`（保留 try/except 与日志结构）；备份 `backups/gov_crawler_pre_ftsrebuild_20260912.tar.gz` + 每文件 `.bak_20260912_ftsrebuild`。实测提速：`heshan_gkmlpt` 600→8.4s、`bynesrmtzx` 600→8.6s、`sthjsh` 406→1.6s、`sxepb_spgs` 595→5.0s（**70~254×**，全 rc=0）。另修 `qhd_gggs`/`lixin_hp` 的 connect 锁等待 15/30→60。三处同步 md5 已验 |
| 5 | ✅ **已完成（2026-09-14）** `state.db` 瘦身：FTS 旧布局 → v23 external-content 迁移 + VACUUM | `~/.hermes/state.db` | — | **已解决：1527.8 MB → 465 MB（↓ 1,062.8 MB，−70%）**；`freelist_count=0`、`quick_check=ok`、messages 100,799 / sessions 3,944 完好。**执行三步**：① `sqlite3 state.db ".backup ~/state_db_snapshot_20260914.db"` 做一致性快照（1.5G，普通打开验 `quick_check ok`；⚠️ **`sqlite3 -readonly` 打开该快照会 rc=14 假失败**，非文件损坏）② `hermes sessions optimize-storage --yes --no-vacuum`（**限流跑，CPU 仅 0.4%**，旧表先改名 `fts_v22_trash_*` 保留 → **可回滚**，重建完自动清理）③ 单独 `sqlite3 state.db "PRAGMA busy_timeout=300000; VACUUM;"` 回收 **293,786 空闲页 = 1.20 GB**。**实测效果**：`messages_fts_trigram_data` **616.4→10.2 MB**、`messages_fts_data` 111.4→79.1 MB、`messages_fts_content` 与 `messages_fts_trigram_content`（各 207 MB 重复副本）**直接消失**。✍️ **纠正**：此前「VACUUM 只能回收约 16MB」**仅对「不迁移布局的单跑 VACUUM」成立**；迁移后 VACUUM 实收 **1.04 GB** —— 真问题是**布局**不是碎片，两步缺一不可。⚠️ 坑：macOS **无 `setsid`**（Linux 命令）；`rclone size` 列举 6 万文件 >300s 会撞 execute_code 上限，须走受管后台 |
| 6 | **OneDrive File Provider 长期挂死 —— 真因 = 单个 ~398MB `.db.gz` 卡在「已上传但报错」循环**（不是死锁、不是网络、不是代理，且**重启 Mac 无效**） | 本机 `OneDrive-个人` 同步目录；影响 `IC13 Project TXT` / `originals note` 两个源（日跑 `originals-route-daily-sync` 因此停摆，已暂停）| 中 | 待办 | 实测：重启后 33 分钟仍 **100–112% CPU**、GC/CS 两路径 listdir 与单文件 open **全挂死**。统一日志 `log show` 命中 `item.uploadingError` / `FP -2005` / `OneDriveItemError 58` / `doc sz:398340063` / `nsattr: ul:uploaded|error` → 一个 ~398MB `.db.gz` 反复重试。**已排除**：网络（graph.microsoft.com 301 / onedrive.live.com 403，均 ~1s）、代理（utun4 有 198.18.192.51 = 隧道已连）。处置（需 GUI，命令行无能为力）：① 菜单栏 OneDrive 图标看状态/待处理项 → ② **暂停同步→恢复同步** → ③ 无效则 **重置 OneDrive**（重建本地缓存，不动云端）→ ④ 最后退出重登。⚠️ **不阻塞 rclone 方案**（走 Graph API，不经 File Provider）。⚠️ 排查禁令：`find ~`（即使用 -not -path 排除）仍会下钻卡死目录并挂满 300s，一律改用 `log show`/`ps`/有界探针 |

### 2026-09-11

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 1 | 慢脚本（不崩但可能超时 600s）：`wudang` / `lufeng` / `jseia` / `hnccci` | `crawl_wudang.py` 等 4 个 | 中 | 待办 | `wudang` 修好 SQL 残片后仍 150s+；`jseia` 22 条详情逐条抓；`lufeng` 79 行输出；`hnccci` 12 条详情 > 260s。需逐条量耗时分布 |
| 2 | `hnccci` 有 12 条 URL 与库中记录不匹配（`source_url` UNIQUE 冲突但 `page_url` 不同）→ 每天重抓、正文回填不上 | `crawl_hnccci.py` `save_to_db` | 中 | 待办 | 已有回填 UPDATE 分支，但 12 条既不 INSERT 也不 UPDATE 命中，需打印实际 SQL 比对 |
| 3 | config 有**重复条目**且 `args=[]` → 脚本默认 50 页 | `daily_crawl_config.json` idx 1633/1634 `crawl_changshu_gsgg.py` | 中 | 待办 | 两条同名同名；`args=[]` 时 `max_pages=50`（`--incremental` 未传） |
| 4 | `crawl_huangchuan.py` 与 `jxlc_tzgg` 覆盖同一 `site_name`（临川区人民政府-社会公益事业）→ 疑似重复爬虫 | 两脚本 + `gov_raw.site_name` | 低 | 待办 | 前者 2280 行 / 后者新入库 6 行；需确认是否合并或分工 |
| 5 | 死站点 / WAF 的 config 处置未做 | `baixiang`(DNS 失效) / `wudang`(域名变更) / `sdharmony.cn`(双协议超时) / WAF 403 的 `anji` `shangyu` `cs_gz` | 中 | 待办 | 需决定：换域名 / `enabled=false` + note / 回填 Dis-db 脚本状态列 |
| 6 | 存量：`gov_raw.attachments` 列含 HTML 标签 | 全库 **64 行 / 5 站**（铜仁22·高唐14·贵州化工院12·扬州10·灵璧6） | 低 | 待办 | 来自「表格 HTML 误入 attachments」bug（脚本已修）。清洗：把 HTML 移入 content 或直接清空 |
| 7 | 搜索路由 Ctrl+K 目标路由错误（进主路由而非本路由）+ 主路由 ⌘K 冗余 | `search_app.py` L2463 / L2655 / `render_main_page` | 中 | **已修复(2026-09-11)** | 改 `__BASE__`/`meta['base']` 拼接 + 加 Ctrl+Enter + 移除主路由 ⌘K；四条路由实测通过 |
| 8 | ~~是否还有其它脚本在做无效 FTS rebuild 未全库排查~~ → **已全库排查并清理** | 全库 `*.py` | 低 | **已修复(2026-09-12)** | ⚠️ **原结论「实测是 no-op」是错的**（在小库上测的）。生产库 `gov_search` 有 **826,853 行**，`VALUES('rebuild')` 是**真实 FTS5 全量重建**，单次 400~600s 且全程独占写锁。活跃树命中 36 处 → 已清理 28 个爬虫+模板；余 8 个 `rebuild_fts*.py`/`fresh_db.py` 等是**重建工具本身**，属正常用途，不动。详见 2026-09-12 第 4 条 |
| 9 | `crawl_linli.py` 类：脚本引用不存在的 `gov_fts` 表（已修 1 处），未全库排查其它引用 | 全库 `*.py` | 低 | 待办 | `grep -rl 'gov_fts' --include='*.py' .` |

### 2026-09-11（第二轮 · 大丰新站上线 + 检索索引治理）

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 19 | **检索索引是离线预计算 → 新入库内容有约 20 小时"搜不到"窗口**。`gov_bigram`(1.42 亿行) 与 `gov_entity` **不是**触发器维护，只靠 cron `4:20 / 4:25` 重建；而日跑 `00:00 → 08:23` 才收工，于是「04:25 之后写入」的当天数据要等**次日**凌晨才进索引。症状：新站入库成功、FTS 也命中，但 `/crawler` 列表页搜不到 | `crawl_scheduler_v2.py` 日跑收尾 / `rebuild_bigram_inc2.py` / `rebuild_entity_inc.py` | **高** | **已修复(2026-09-11)** | ① 索引刷新挂到日跑收尾新增 `[IDX]` 块（收工即索引，不再猜 cron 时刻）；② bigram 脚本改写为水位线版；③ 已补录 2,869 行 bigram + 2,870 篇 entity；④ `4:20/4:25` cron **保留**作调度器异常时兜底 |
| 20 | `rebuild_bigram_inc2.py` 旧实现**内存 + 性能双缺陷**：`SELECT DISTINCT rowid FROM gov_bigram` 全扫 1.42 亿条索引项（实测**仅"查找缺失"就要 82s**，且 0 条缺失照跑）+ `fetchall()` 把缺失行全部读进内存（生产机仅 1.75GB） | `rebuild_bigram_inc2.py` | **高** | **已修复(2026-09-11)** | 新实现：`index_watermark(name,value)` meta 表 O(1) 读水位线 + keyset **200 行/批**流式。无新行 **0.03s**（原 82s）。⚠️ **禁用 `MAX(rowid)`**：`gov_bigram.rowid` 是**显式 INTEGER 列**、无以其打头的索引 → MAX 退化为全扫 **38s**；`MAX(_rowid_)` 虽 0.003s 但那是插入序号、**不是 doc id**，不可用 |
| 21 | `/crawler/?q=` **稀疏中文词 70s 全表扫**：`_list_term_preds` 的 bigram 分支一律用相关 `EXISTS`，查询计划 = `SCAN gov_raw USING idx_gov_raw_date` + 每行 2 次索引探测——只有匹配**足够稠密能快速凑满 LIMIT** 时才快；稀疏词凑不满 31 行就须扫完 55 万行。（Ctrl+K 修复后「查看全部结果」正好落在这条路径上，所以更刺眼） | `search_app.py` `_list_term_preds` / `_LIST_GRAM_IN_MAX` | **高** | **已修复(2026-09-11)** | 探测各 gram 基数取 min（**交集 ≤ min 是硬上界**）：min ≤ 2 万 → `r.id IN (SELECT rowid … INTERSECT …)` 物化小集合；否则沿用 EXISTS。实测 `大丰区` **74s → 0.041s**、`双随机` 27s → 0.33s；稠密词 0.03s → 0.16s（探测开销，可接受） |
| 22 | **`mailto:` / `tel:` 链接被当附件** → 写进 `attachments` 列 + 正文生成假附件段。大丰脚本首轮 **122/249 行**中招（正文「邮箱：xxx@163.com」） | `crawl_dafeng_sthj.py`（已修）；**其它 hanweb 系 / 同模板脚本未全库排查** | 中 | **待办**（大丰已修） | 判据：`attachments` 含 `mailto:` / `tel:` / 裸 `#`。排查：`sqlite3 search.db "SELECT count(*) FROM gov_raw WHERE attachments LIKE '%mailto:%'"`（走全表扫，慢）或 `grep -l '_link_repl' crawl_*.py` 逐个人工确认 |
| 24 | `[IDX]` 钩子**首次运行要初始化水位线**（`MAX(rowid)` 全扫 38s，一次性） | `rebuild_bigram_inc2.py` `get_watermark()` | 低 | 已修复(2026-09-11) | meta 表已写入。⚠️ 若做 DB 灾难恢复/换库，meta 表丢失 → 下次运行会再付一次 38s，属正常 |

### 2026-09-11 之前（历史遗留，来自会话/技能记录）

| # | 问题 | 位置 / 对象 | 严重度 | 状态 | 备注 |
|---|---|---|---|---|---|
| 10 | 存量正文含 HTML 注释 | `gov_raw.content` **66,354 行** | 低 | 待办 | 一直未动；清洗前需确认注释里是否有附件/图片信息 |
| 11 | 白名单覆盖面：62 个「绕过脚本」存量未重抓 | 爬虫侧 | 低 | 待办 | 与新站爬虫 10 步闭环一同处理 |
| 12 | `/api/*` 是否加 `Cache-Control: no-store` | `search_app.py` | 低 | 待办 | 未决策 |
| 13 | 独立详情页标题 28px vs 抽屉 20px 是否统一 | `search_app.py` `DETAIL_CSS` | 低 | 待办 | 目前**刻意不一致**（抽屉窄用 20px）；要统一改 `.dh h1` 一行 |
| 14 | `render_gov_page` 与 `render_main_page` 合并 | `search_app.py` | 低 | 待办 | 延后（属重构，收益有限） |
| 15 | ccpc 抽屉 19 字段 vs 独立页 25 字段（样式已统一、**内容集未统一**） | `render_ccpc_frag` vs `render_cceup_detail_body` | 低 | 待办 | 让抽屉复用 `render_cceup_detail_body` 即可 |
| 16 | `crawler-infrastructure-audit` 的 `## Audit Workflow`（4.3 万字符）是否下沉到 references | 技能库 | 低 | 待办 | 技能瘦身最后一块 |
| 17 | 决策点：四个爬虫技能是否合并成 umbrella | 技能库 | 低 | 待办 | 未定 |
| 18 | 坚果云镜像内 `gov_crawler/gov_crawler/` 嵌套重复树 1502 文件待清理 | 坚果云 | 低 | 待办 | 只占空间，不影响功能 |
| 19 | 服务器 root 密码待改（同步脚本已不依赖） | 服务器 | 中 | 待办 | 安全项 |
| 20 | `wal_checkpoint(TRUNCATE)` 回收 WAL 占用空间（曾 1.32GB，现 0） | `/mnt/data/search.db-wal` | 低 | 待办 | 属写操作，需人工确认；空间不急 |

---

<!-- AUTO:DAILY_LOG:BEGIN (由 daily_run_log.py 每日自动追加, 勿手改本区块) -->
## 二、日跑自动记录

| 日期 | 成功 | 失败 | 失败率 | 明细 |
|---|---|---|---|---|
| 2026-09-11 | 1912 | 71 | 3.6% | `daily_run_logs/2026-09-11.md` |
| 2026-09-12 | 1956 | 42 | 2.1% | `daily_run_logs/2026-09-12.md` |
| 2026-09-13 | 1968 | 30 | 1.5% | `daily_run_logs/2026-09-13.md` |
| 2026-09-14 | 1973 | 25 | 1.3% | `daily_run_logs/2026-09-14.md` |
<!-- AUTO:DAILY_LOG:END -->

---

## 三、已闭环（留着备查，勿重复处理）

| 日期 | 问题 | 处置 |
|---|---|---|
| 2026-09-11 | **上高县爬虫静默停更 3 周**：老 `crawl_shanggao.py` 用 `http://` + `curl -s`（**不跟 301**）→ 站点 http→https 迁移后 JSON 解析失败 → 每天 0 条、DB 停在 2026-08-19；且 332/346 行 `script_name` 为空、栏目与用户 URL 不同（镜像 `jsxmhjyjpj2` vs `jsxmhjyxpj`） | 按现代模板重写（https+请求库跟跳转、正文内联免详情、CUTOFF、--pages、push_to_searchdb 写 script_name）；按栏目分别抓 + 标题去重；备份旧 346 行到 `Archive/shanggao_rows_before_rebuild_20260911.sql` 后重建 → **316 条**（300 条用户栏目 + 16 条镜像独有）；config #265 args 改 `--pages=5`；Dis-db 两条记录回填 `crawl_shanggao.py` #265（旧记录编号 267 修正为 265） |
| 2026-09-11 | **TRS 附件 `oldsrc="/protect/..."` 不可达（404）**：模板 `real_href = a.get("oldsrc") or href` 在 TRS 站取到 CMS 内部路径 → 本批 longli/xiaogan/qdn_sphgs/qdn_spqgs **180 行附件全 404** | 改为优先 `href`（`javascript:`/`mailto:`/`#` 才回落 oldsrc），14 站全部 DELETE 重跑；实测每站附件 `curl` 全 200（含完整 Chrome UA + Referer，避免 UA 门禁 403 假阳性） |
| 2026-09-11 | **`createPageHTML` 第4参数(扩展名)猜错 → 第2页起静默 404**：孝感高新区分页是 `index_1.shtml`，脚本写成 `.html` → 只入 1 页（15 条 vs 应有 75 条） | 后缀改 `.shtml`，重跑 75 条；判据固化为「新增数 == 页数 × 每页条数」 |
| 2026-09-11 | 大丰新站 **Dis-db 回填**（`page_id=3d8399b8-3c5b-8141-9212-c7cb46add585`） | PATCH `Script_name=crawl_dafeng_sthj.py` + `配置编号=2087`；Url 精确匹配 `/col/col25839/index.html`（全库仅 1 条命中）→ 重新 query 复核通过。⚠️ 坑：Notion PATCH body 必须包一层 `properties`（写成 `{"Script_name":…}` 直接 400 validation_error） |
| 2026-09-11 | **Ctrl+K 目标路由错误**：v2 列表页外壳被四条路由共用，但「查看全部结果」硬编码 `/?q=`（L2463 click 处理器 + L2655 foot 链接）→ 在 `/crawler/` 里按 Ctrl+K 搜索后跳到了主路由；`/zc` `/ccpc` `/contact` 同病 | 改用 `'__BASE__' + '?q='`（JS）/ `meta['base'] + '?q='`（模板）→ 各进本路由；**新增 Ctrl+Enter 热键**直接进本路由搜索结果列表（并加 foot 提示）；**移除主路由 ⌘K**（主搜索页本身就是搜索页，无使用场景）。四条路由 HTTP 实测 + node JS 语法校验 + 结构校验 65 类方法全过；md5 `3cdd6794` → `6761c9b9` |
| 2026-09-11 | 6 个脚本被 09-02 批量编辑删掉 `CREATE VIRTUAL TABLE` 首行 → 0.3s 崩（`guiyang`/`gz_hpspgg`/`wudang`/`suixi_sthj`/`gemxizang`/`zjcx`）+ `linli` 引用不存在的 `gov_fts` | 删残片（完成半截重构），实跑 rc=0 |
| 2026-09-11 | 7 个脚本把表格 HTML 塞进 `attachments` 而非正文 `parts`（`linxixian` 崩、其余 6 个静默丢表格） | 改入 `parts` + 贯穿型补 `continue` |
| 2026-09-11 | `gxq_yl_tzgg` `UnboundLocalError: new_count`（空结果日崩） | 循环前初始化 |
| 2026-09-11 | `soochowchem` 每条记录 fork `sqlite3` CLI 且 `timeout=10` 未捕获 | `-cmd ".timeout 60000"` + try 住 |
| 2026-09-11 | `jxlc_tzgg` **抓完不入库**（`if args.db and push_to_searchdb` 恒假）→ 每天白跑 400s | 接通入库 + 预去重（383→6） |
| 2026-09-11 | 1391 个脚本 `sqlite3.connect` 缺 timeout（1096 处）+ 60 个 CLI 脚本缺 `.timeout`（121 处）→ 锁竞争即失败 | 批量补 `timeout=60` / `.timeout 60000` |
| 2026-09-11 | T2 类：89 文件未定义名（`urllib`/`json` 等缺 import、模板孤儿变量名）→ 表格静默丢失 | 全部修复（89→6，余 6 个非 config 引用） |
| 2026-09-11 | T1 类：14 个持续失败脚本（NameError/无 timeout/参数未生效/全量重抓/嵌套 `<a>` decompose） | 逐个修复并实跑验证 |
