# 2026-07-26

## AHKB-CPS — 解决 crosslink 被大模型超时截断问题

**问题**：`ahkb_crosslink.py` 执行知识元关联时运行时间超长（20分钟+），LLM shell 命令超时后直接杀进程，原先的心跳机制无效。

**根因**：
1. LLM shell 有固定超时（120s），crosslink 远超阈值
2. 心跳写 stdout，但 stdout 被 Tkinter GUI 重定向吞掉，LLM 管道完全静默
3. 即便心跳到达管道，也不能阻止 shell 超时

**方案**：Shell 先走，GUI 留下 — 子进程彻底解绑 + 文件 IPC

**改动文件**：
- `ahkb_crosslink.py`：心跳同时写 `_crosslink_progress.json`；增加 `--detached-child` 模式（PID 管理、result 文件、窗口关闭保护、跨平台 PID 存活检查）
- `ahkb.py`：增加 `--detached` 标志；跨平台子进程解绑启动（`DETACHED_PROCESS` / `start_new_session`）；`_is_pid_alive()` 跨平台实现
- `kb.md`：菜单 6 + 4 处 maintain 调用全部改为 `--detached` 模式 + LLM 轮询指令

**关键特性**：
- GUI 窗口保留（用户可见滚动效果）
- `--detached` 是可选 flag，不带时行为完全向后兼容
- 用户手动关窗 → 写 `"cancelled"` 状态，LLM 不再重试
- 残留 PID 检测 → 拒绝重复启动

## AHKB-CPS — crosslink GUI 五个体验优化

**改动文件**：
- `ahkb_crosslink.py`：
  1. 删除 `_heartbeat_worker()` 中向 stdout 写裸 JSON 的两行（心跳只写进度文件，GUI 不再出现乱入的 JSON）
  2. 暂停/继续按钮文字 `?` → `⏸`/`▶`（修复问号渲染问题，与 ahkb.py 一致）
  3. 删除 `TkRedirect._insert_line()` 中状态栏自动镜像文本区末行的逻辑（底行不再冗余重复）
  4. `run_task()` 中 `cross_link()` 成功后添加 9 声蜂鸣（三组×三声），确保处理完成后才响
  5. `run_task()` 中添加 5 秒倒计时自动关闭窗口（`root.after` 非阻塞）
- `ahkb.py`：
  - `cmd_maintain()` 删除蜂鸣代码（已移入 crosslink 内部）

# 2026-07-28

## AHKB-CPS — PyMuPDF 导入名统一 + 环境检测补充依赖检查

**改动文件**：
- `ahkb.py`：`_quick_count_text()` 中 `import fitz` → `import pymupdf`，统一使用 pymupdf 规范导入名
- `SKILL.md`：环境检测新增第 3 步「检测框架依赖」——执行 `check-env` 自动检测 pymupdf/pptx/docx/openpyxl/jieba/Pillow 等依赖，缺失时自动安装，通过后缓存状态

**确认**：
- `ahkb_extract_pdf.py` 一直使用 `import pymupdf`，无需修改
- `ahkb_extract_pptx.py` PDF 渲染路径也使用 `import pymupdf`，无需修改
- 代码中无 pdfplumber/PyPDF2/pikepdf/reportlab 等其他 PDF 库

## AHKB-CPS — 处理顺序选择改为 6 选项，禁止 AI 替用户决策

**改动文件**：`kb.md` 三处 Step 1.5（菜单 0 / 菜单 1 新增 Step 4.5 / 菜单 3）

**原问题**：只有「文字量从多到少/从少到多/原有顺序」3 个选项，且将「文字量从多到少」标为"推荐"并设置回车默认。

**修改后**：6 个选项 + 文件类型分布透视
1. 文字量从多到少
2. 文字量从少到多
3. 按文件类型分组（pptx→docx→pdf→md→xlsx→html→txt）
4. 指定文件类型优先（用户选类型）
5. 按原有顺序
6. 自定义顺序

**关键规则变更**：
- 删除所有"推荐"标签
- 删除所有"直接回车默认"行为 — 用户必须明确输入数字
- AI 严禁预设或推荐任何选项
- scan 后增加文件类型分布统计展示

## AHKB-CPS — 输出目录"成果"→"产品成果"全局重命名

**改动范围**：涉及 6 个文件，共 17 处修改。

| 文件 | 修改内容 |
|------|---------|
| `SKILL.md` | 标题和规则描述中的"成果/"→"产品成果/" |
| `kb.md` | 工作空间结构图中的目录名 |
| `kb/scripts/ahkb.py` | `init` 创建目录列表 + `SYSTEM_DIRS` 扫描排除集合（2 处） |
| `write/write.md` | 生成流程 + 格式表 + 完成提示（4 处） |
| `ppt/ppt.md` | build-ppt/verify-output 命令 + 完成提示 + Authoring rules（9 处） |
| `write/scripts/md2docx.py` | 硬编码输出路径（1 处） |

**排除项**：非目录引用的"成果"（如"基于...许可成果"、"中间成果"等中文叙述）保留不变。

## AHKB-CPS — 修正全自动不中断铁律与 Step 1.5 的冲突

**问题**：菜单 0/1/3 的铁律声称"全程无中断"，但 Step 1.5/4.5 需要用户选择处理顺序——互相矛盾。

**修改**：
- 菜单 0：铁律改为「Step 0+1 自动，Step 1.5 是唯一交互断点，Step 2 起全自动不中断」
- 菜单 1：铁律改为「Step 1 确认 + Step 4.5 选顺序是两个交互断点，Step 5 起全自动不中断」
- 菜单 3：铁律改为「Step 1 自动，Step 1.5 是唯一交互断点，Step 2 起全自动不中断」

## AHKB-CPS — 分离关联(crosslink)与重建地图步骤

**问题**：三个菜单中 maintain（关联）和 build-graph（构建根节点+地图）混在一个 Step 里，AI 可能在关联未完成时就开始构建。

**修改**：在 maintain 轮询和 build-graph 之间插入硬阻断——不改菜单项编号，只改内部 Step 结构。

| 菜单 | 原结构 | 新结构 |
|------|--------|--------|
| **0** | Step 3: 关联+重建（混在一起） | Step 3: 关联 → 🔴硬阻断 → Step 4: 构建根节点+重建地图 |
| **1** | Step 6: 关联+重建（混在一起） | Step 6: 关联 → 🔴硬阻断 → Step 7: 构建根节点+重建地图 |
| **3** | Step 4→5 无阻断 | Step 4→🔴硬阻断→Step 5（编号不变，加阻断规则） |

**硬阻断模板**（三处统一）：
```
🔴🔴 ═══════════════════════════════════════════════════
🔴🔴  硬阻断：必须轮询确认 maintain [完成] 后才能越过此线
🔴🔴  严禁在关联未完成时执行 build-graph 或 build-kg-html
🔴🔴 ═══════════════════════════════════════════════════
```

**关联副作用**：菜单 1 铁律中 "Step 6" → "Step 7"，轮询提示中的 "进入第 3 步" → "进入 Step 7"

## AHKB-CPS — 强化进度透明铁律 + Crosslink 心跳输出

**SKILL.md**：将「进度透明规则」从一段话扩展为分层级的强制要求：
- 每完成一步必须报告（开始/完成双向通报）
- 🔴🔴 Crosslink 轮询每回合必须向用户原文展示轮询结果
- 禁止静默处理 / 后台运行 / 只内部检查不输出
- 思考过程可见：长时间操作前先告知"正在做 X..."

**kb.md**：5 处 maintain 轮询段全部加上强制心跳输出规则：
| 位置 | 菜单 | 改动 |
|------|------|------|
| Step 3 | 菜单 0 | "告知用户进度" → 🔴 必须原文展示本轮结果 |
| Step 6 | 菜单 1 | 同上 |
| Step 4 | 菜单 3 | 新增处理分支 + 🔴 心跳输出（原来完全缺失） |
| Step 5 | 菜单 4 | 新增处理分支 + 🔴 心跳输出（原来完全缺失） |
| LLM执行步骤 | 菜单 6 | "告知用户进度" → 🔴 必须原文展示本轮结果 |

全局 0 残留"告知用户进度"弱提示。

## AHKB-CPS — 损坏/不可读 .ctx 文件直接删除

**审查结论**：`ahkb_crosslink.py` 中"单身 .ctx"清理逻辑**本身就正确**——判断依据始终是"媒体文件存在与否"，不涉及知识元引用。

**改进**：两处 `except Exception: continue`（损坏 .ctx 被静默跳过、永久残留）→ 改为直接删除：

| 位置 | 改动 |
|------|------|
| 清理阶段 (L491) | `continue` → 删除 + `deleted.append()` 计入统计 |
| 加载阶段 (L713) | `continue` → 删除 + stderr 日志 |

**注意**：`replace_all` 误伤了一处 .md 知识元文件的异常处理，已回滚。该处的 `continue` 是正确的——知识元文件损坏不应删除。

## AHKB-CPS — 删除 crosslink 结束时多余的尾部输出

**仅删除**：结尾横幅下方的 `===` 分隔线 + 空行（`\n`）——两条无信息量的尾巴。

## AHKB-CPS — 新增「严禁简化处理」铁律

**问题**：菜单 1 重建时 AI 偷懒做"简化处理"——11 个文档只产出 3 个知识元。

**修改**：
- `SKILL.md`：新增全局铁律「严禁简化处理」——逐段完整分析，严禁以任何理由跳过。重建质量≥首次构建。
- `kb.md` 菜单 1：新增 🔴🔴🔴 铁律——重建=推倒重来，严禁简化/敷衍/跳步，全程 A→F

**保留**：有颜色的结束横幅（统计信息完整）、stdout 心跳 JSON、开头横幅。

## AHKB-CPS — 修复重建时不删除图片等资源

**根因**：
1. `ahkb_purge.py`：`shutil.rmtree(ignore_errors=True)` 在 Windows 上文件被占用时静默失败，但仍报告 `"resources": "all"`
2. `kb.md` Step 2 手动清理命令：漏了 `图片及其他资源/` 目录

**修复**：
1. `ahkb_purge.py`：先试 `ignore_errors=False`，失败再用 `True` 兜底，兜底后检查目录是否真的没了，仍在则报告错误
2. `kb.md`：手动清理命令补上 `shutil.rmtree('<工作空间>/图片及其他资源')`

## AHKB-CPS — 统一关联资源显示格式

**改动**：`ahkb_crosslink.py` 关联资源的 stderr 显示从：
```
o 关联资源: 15个: [1:85]file1.png, [2:72]file2.png, ...
```
改为与"关联原始文件"一致的逐行格式：
```
o 关联资源: 15个
    -> file1.png
    -> file2.png
```
去掉排名、得分，每行一条，干净对齐。

## AHKB-CPS — crosslink TF-IDF 预缓存性能优化

**改动文件**：`ahkb_crosslink.py` + `ahkb_chunk_match.py`

**新增函数**：`_build_tfidf_vector(text)` 预提取向量；`_vec_cosine(a, b)` 纯字典余弦。`_tfidf_similarity()` 保留兼容。

**核心优化**：匹配循环前一次性预建所有 KE/ctx/chunk 的 TF-IDF 向量字典。匹配时走 `_vec_cosine` 不再调 jieba。

**性能效果**：O(N²×2) jieba → O(N) jieba + O(N²) 字典运算。N=50 约 30s→3s。

**等效性**：jieba TF-IDF 权重来自内置固定 IDF 词典，预提取与现场提取结果完全相同。
