# Workflow 系统性问题清单（2026-06-27 至 2026-07-01）

## 1. auto_notify 静默失效（模式B）

**表现**：进程在跑但 inotifywait 没有捕获事件，日志完全为空。
**根因**：inotifywait 文件描述符失效/内核事件丢失。
**现状**：watchdog cron (`63bb31d4f050`) 只能重启进程，无法修复内核级别的事件丢失。
**Fallback**：手动检查 `~/.hermes/cache/documents/` + relay 脚本串行启动 workflow。

## 2. 非合同文件误审

**表现**：香花桥家庭医生招标需求被当合同审查。
**根因**：classifier 的 `not_a_contract` 逻辑虽然写了（第13-19行），但 LLM 执行时没走到——可能因标题含"服务""项目"等关键词触发了合同判断。
**修复状态**：通知脚本已存在(`wecom_group_notify.py`)，routing 已配置(`$END`)。需加强 classifier prompt 中对招标/技术需求的识别。

## 3. 审查意见不该生成

**表现**：非卫生中心合同（如生育友好-计生协会）也自动生成了审查意见。
**根因**：workflow 对所有合同统一执行 editor 生成审查意见的逻辑，未按 ruleset_type 区分。
**修复方向**：在 editor procedure 中加条件判断——只有 ruleset_type=health-centers 且 review-rules.md 中明确要求"审查意见"交付物时才生成。

## 4. 文件名 hash 前缀残留

**表现**：`【修】doc_0ad4ee63bff5_印刷品制作合同2026.6(1).docx`
**根因**：deliverer 从 cache 路径取文件名时未剥离 `doc_[0-9a-f]{12}_` 前缀。
**修复状态**：editor procedure step 7 已有清理逻辑（第147-149行），但 deliverer 步骤可能绕过了 editor 的命名。

## 5. 新增条款插入位置错乱

**表现**：健康积分合同新增"数据归属""转包分包"条款标题和内容分离。
**根因**：editor 用 python-docx 插入段落时，对文档结构的理解不够（插入在错误的 anchor 位置）。
**自愈**：reviewer 第2轮检出并返回 editor 修复，第3轮通过。但多花了2轮=多花10分钟+token。

## 6. idle thread 不自动继续

**表现**：反委托代发的 thread 卡在 idle classifier。
**根因**：auto_notify 启动了 thread (`uwf thread start`) 但没有执行 (`uwf thread exec --count 20 --background`)。
**修复**：需要确保 relay/queue 脚本在 start 后立即 exec。

## 7. /tmp/contract-review 被僵尸线程污染（2026-07-01）

**表现**：新启动的 classifier 在 /tmp/contract-review/ 中看到旧线程残留的文件（其他合同的【修】文件、.py脚本、.pdf等），导致分类器混乱或长时间卡住。
**根因**：
- queue-runner.sh 和手动启动并存，多个 thread exec 进程同时操作 /tmp/contract-review/
- 僵尸线程（6月26日、6月30日的stuck threads）被queue-runner定期唤醒但无法推进，占用/tmp/contract-review/
- `uwf thread show` 显示 "running" 但实际 uwf-hermes 子进程已死或卡住

### 7b. Queue-runner 自动启动重复线程（2026-07-02 恭兴合同教训）

**表现**：手动启动的 thread `06FJ1DY529R7C85BDPBQG1QBBW` 和 queue-runner 自动启动的 `06FJ1DVM3PCZYVDXAAXE1DTYBG` 同时处理恭兴合同.docx，两个 uwf-hermes reviewer 进程同时写 /tmp/contract-review/【修】恭兴合同.docx。
**根因**：queue-runner.sh 检测到 Nextcloud 待审查目录中的新文件后自动 `uwf thread start + exec`，与手动操作撞车。
**症状**：`ps aux | grep uwf-hermes` 可以看到**两个**不同 thread-id 的 reviewer/editor 进程，prompt 里有相同的文件名。
**修复**：手动管理合同时，**必须先 kill queue-runner**：
```bash
kill $(ps aux | grep "[c]ontract-queue-runner" | awk '{print $2}') 2>/dev/null
```
确认只有自己的线程在跑后再继续。如果发现重复线程已经启动，cancel 它并 kill 其进程。
**教训**：仅 cancel thread 不够——对应的 uwf-hermes 子进程可能仍在运行（进程不感知 thread status 变化），必须同时 kill 进程 PID。

**清理步骤（批量开工前必做）**：
```bash
# 1. 查看正在运行的uwf进程
ps aux | grep "[u]wf-hermes" | grep -v grep
ps aux | grep "[u]wf.*thread exec" | grep -v grep

# 2. 杀死所有uwf-hermes子进程
kill $(ps aux | grep "[u]wf-hermes" | grep -v grep | awk '{print $2}') 2>/dev/null

# 3. 杀死queue-runner
kill $(ps aux | grep "[c]ontract-queue-runner" | awk '{print $2}') 2>/dev/null

# 4. 取消所有非当前的stuck threads
/home/maggie/.hermes/node/bin/uwf thread list | grep running
# 对每个非当前任务的thread: uwf thread cancel <id>

# 5. 清理/tmp/contract-review（保留rules/）
cd /tmp/contract-review
rm -f *.docx *.docx.bak *.py *.pdf *.png *.yaml *.xml 【修】*.docx 2>/dev/null

# 6. 确认干净
ls /tmp/contract-review/ | grep -v rules
# 应该为空

# 7. 复制新合同文件进去，启动thread
```

**预防**：串行处理合同（一份完成再启动下一份）。`uwf thread show` 显示 end 后再清理+启动下一份。

## 8. 批量合同串行处理实操（2026-07-01 四份合同）

**场景**：邱律师一次发2-4份合同，需要逐份串行审查。
**正确流程**：
1. 收到所有文件 → 上传Nextcloud待审查目录 → 复制到本地shared目录
2. 第1份：清理/tmp → 复制文件 → `uwf thread start` → `uwf thread exec --count 20 --background` → 等`status=end`
3. 第2份：清理/tmp → 复制文件 → 新thread → exec → 等end
4. 全部完成后：统一更新tracker、不逐份通知（通知只在全部完成后发一次）

**等待策略**：
- `sleep N && uwf thread show <id>` 轮询，每轮5-10分钟
- 典型合同全程约30-60分钟（classifier 2-3min → reviewer 5-10min → editor 5-10min → reviewer复核 5-10min → 可能再editor → final_review 3-5min → deliverer 2-3min）
- 如果同一个role卡超过15分钟没变化，检查 `ps aux | grep uwf-hermes` 进程是否存活

## 待修复优先级

1. 【高】加强 classifier 对非合同文件的识别（prompt 强化）
2. 【中】审查意见按 ruleset_type 条件生成
3. 【中】/tmp/contract-review 隔离（考虑按thread_id创建子目录，避免多线程冲突）
4. 【低】auto_notify 根因（可能需要换 inotifywait 为 polling 方案）
5. 【低】新增条款插入位置的准确性（需要更结构化的段落插入逻辑）
