# Progress

## Session Log
- 开始 Agent 全文图片编排重构：用户再次确认不考虑旧逻辑和旧数据兼容，本轮将完整删除旧正文图片编排和实际配图代码；新阶段只输出并持久化最终图片计划，正文任务随后结束，实际图片生成留待下一阶段重新实现。
- Agent 全文图片编排重构和验证已完成：正文逐节计划升级 v4 并只保留写作/知识/事实/表格；旧 AI/Mermaid 候选、Mermaid 修复、实际生图、正文插图、图片统计和 `illustration_type` SQLite 路径全部删除；新增全文 Agent 输入投影、严格输出校验、HTML > Mermaid > AI 上限/冲突处理和文档级 `contentIllustrationPlan` 原子保存；暂停/失败重试直接重跑编排；Renderer 显示三步编排进度。5 个 CJS 语法检查、算法、任务原子保存、Store 生命周期、Electron SQLite v16->v17 migration smoke、客户端构建及 1440/390px UI 验证均通过，构建仅有既有 chunk 体积警告。
- 开始正文生成配置弹窗改版：HTML 生图按用户确认默认开启，但只增加并持久化 UI 配置，不实现生成业务；主配置弹窗删除全部二级说明；Mermaid 新增默认 10 张上限并接入 Main 侧保留数量扣减、候选分布和优先级择优。
- 正文生成配置弹窗改版主体已完成：配置新增 Mermaid/HTML 上限和 HTML 图片类型；主弹窗删除顶部及配置项说明，三个生图开关按状态显示上限；HTML 高级设置使用第二层 Dialog 和独立草稿；Main 侧 Mermaid 上限已接入保留数量扣减、编排可用性、AI 优先及分布择优。进入语法、构建和交互验证。
- 正文生成配置弹窗改版验证完成：Main CJS 语法检查和客户端构建通过；浏览器 mock 工作区验证三个开关条件显示、HTML 默认开启/默认 10、Mermaid 默认 10、高级设置取消与确认、保存后重开持久化均正常；1440px 双列和 640px 单列内部滚动无横向溢出。Vite 端口已存在时直接复用，首次 mock unsubscribe 问题已补事件 stub 后解决。
- 开始 Mermaid 图表类型收敛：按用户确认将其作为当前软件功能修改，不考虑旧数据兼容；目标是只保留流程图、层级图、职责关系图，统一使用 `flowchart` 语法，并在生成、前端预览和 Word 导出三个边界拒绝其他 Mermaid 类型。工作区已有未跟踪的 `client/doc/html图片.md` 和 `图表测试数据/`，本轮不修改。
- Mermaid 类型收敛主体已完成：新增 `process/hierarchy/responsibility` 业务类型和 Main 共享策略；正文编排提示词、归一化、校验、修复只允许三类图及 `flowchart` 语法；计划升级为 v3 并完整保存版本、计划和表格需求；前端预览和 Word 导出会在调用 Mermaid 引擎或缓存前拒绝其他语法；配置文案和提示词文档已同步。进入语法、构建和定向验证阶段。
- Mermaid 类型收敛验证完成：4 个相关 CJS 文件 `node --check` 通过；策略 smoke 确认三种业务类型、五种 flowchart 方向可用，graph/sequenceDiagram/timeline/gantt/pie/classDiagram 被拒绝；Word 导出不支持类型 warning smoke 通过；`cd client; npm run build` 通过且仅有既有 chunk 体积警告；`git diff --check` 仅有 LF/CRLF 提示。首次 Word smoke 因命令使用字面量 `\\n` 未形成代码块，修正为真实换行后通过。
- 开始客户端授权签名校验与统计实现：用户确认同一套签名密钥用于构建签名和 license 签发，当前实现采用 Electron/Node/Cloudflare Worker 都支持的 ECDSA P-256/SHA-256；免费授权默认 30 天、过期弹窗默认开启且不可关闭；客户端本版只记录不可信安装来源、保存授权配置，不做 UI 展示或功能阻断。已恢复文件型计划，session catchup 无输出。
- 客户端授权签名校验与统计主体已接入：客户端新增构建声明、公钥资源、构建签名脚本、`licenseService`、IPC/preload/types 和埋点授权字段；Worker 新增 `/license/activate`、`/api/license-config`、license 签名/配置服务，并把授权字段写入 AE `blob14-blob18` 与 D1 `stats_clients`；Dashboard 新增“授权管理”标签和客户端授权列；release workflow 会在 Windows/macOS 打包前强制要求 `YIBIAO_LICENSE_PRIVATE_KEY_JWK` 并生成签名。
- 已修正授权统计收尾问题：客户端上报可信来源必须同时满足 Worker 签发 payload 中 `sourceTrusted=true` 和本地构建验签可信；`recordTrackClient()` 保留新客户端实时入库计数逻辑，同时允许已存在客户端按授权字段快照实时覆盖，避免启动首个“缺授权/刷新中”状态卡住到夜间 Cron。
- 客户端授权签名校验与统计验证完成：`node --check` 覆盖客户端 `licenseService/licenseIpc/preload/generate-build-attestation`、Worker `analyticsStatsStore/license route/licenseCrypto/licenseStore/analyticsTrack` 和 Dashboard `pages/license.js`；`cd client; npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 Windows LF/CRLF 换行提示。
- 已完成 Step03 原方案目录 checkpoint 续跑：`technicalPlanStore.cjs` 新增 `original-outline-runtime.json` 读写清理，并在替换招标文件、切换投标范围、替换原方案、切换工作流、清空技术方案时清理；`outlineGenerationTask.cjs` 在旧方案目录滚动提取每段成功后保存原方案 hash、分段 hash、当前完整目录和下一段下标，再次生成目录时校验一致后从失败分段继续；`taskService.cjs` 会把异常关闭遗留的目录生成 `running/pausing` 状态标为 error，用户重新生成后自动使用 checkpoint。验证通过 3 个 CJS `node --check` 和 `cd client; npm run build`，构建仅有既有 chunk 体积警告。
- 已按用户要求收敛旧方案目录提取逻辑：`outlineGenerationTask.cjs` 删除动态预算二次拆分函数和滚动提取/补漏中的二次细分调用；旧方案目录提取失败不再切 Agent，直接失败；补漏阶段仍按初始分段逐段处理，补漏失败时沿用既有“使用首次提取目录”逻辑。Step05 的“原方案还原映射”和“已还原正文优化扩写”Agent 分支未改。验证通过 `node --check electron\services\outlineGenerationTask.cjs`、`node --check electron\services\contentGenerationTask.cjs`、`node --check electron\services\opencode\opencodeRuntimeService.cjs` 和 `cd client; npm run build`，构建仅有既有 chunk 体积警告。
- 已完成 Agent 任务队列评审修复：`opencodeRuntimeService.cjs` 将 `runTask()` 改为全局 FIFO 入队，内部 `runTaskNow()` 仍保持单 active Agent 执行；多个正文生成小节同时进入超阈值 Agent 路径时会排队等待，不再因 runtime busy 被标记失败；排队任务支持 AbortSignal 取消，关闭服务时会清空队列；自检在 active 或 queued 时继续返回 busy；Agent 状态类型和顶部状态条已显示排队数量。验证通过 `node --check electron\services\opencode\opencodeRuntimeService.cjs`、`node --check electron\services\contentGenerationTask.cjs`、`cd client; npm run build` 和 diff check，构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已完成 Step05 超长原方案还原切 Agent：`contentGenerationTask.cjs` 新增 messages 长度阈值判断（`context_length_limit * 0.7`）、Agent JSON 解析和可取消 Agent 调用包装；原方案还原映射超阈值时切 Agent 输出 `original-restore-result.json` 后复用 assignments 写回逻辑；已还原正文优化扩写超阈值时切 Agent 输出 `optimized-section.md` 后复用现有归一化、去标题和保存逻辑；短文本仍走原普通 AI 请求。验证通过 `node --check electron\services\contentGenerationTask.cjs`、`cd client; npm run build` 和 diff check，构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 开始旧方案目录提取长上下文分段改造：短原方案保持单次提取；长原方案改为滚动分段，每轮提交上一轮完整目录和当前段原文并输出截至当前段的完整目录；旧方案目录补漏也改为分段 additions，目录 JSON 不保留正文 content。
- 已完成旧方案目录提取长上下文分段改造：`outlineGenerationTask.cjs` 引入 `splitUserTextByContextLimit`；长原方案按“上一轮完整目录 + 当前段原文”滚动提取完整目录；补漏阶段按段返回 additions；旧方案专用 normalizer 会剥离 `content` 等非目录字段。验证通过 `node --check electron\services\outlineGenerationTask.cjs`、`cd client; npm run build` 和 diff check，构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已完成 Analytics IP 统计接入：`/track` 从 `CF-Connecting-IP` 读取公网 IP 并写入 AE `blob13`；`stats_clients` 新增 `last_access_ip`，新客户端实时入库和每日 Cron 都会写/更新；新增 `/api/ip-stats` 从 D1 按最后访问 IP 分组分页；Dashboard 客户端列表新增最后访问 IP，新增“IP 统计”标签页和独立分页。验证通过 Worker/脚本/Dashboard `node --check`、Worker 模块动态 import、IP blob smoke、Dashboard 本地 HTTP 页面加载和 `git diff --check`；仅有 LF/CRLF 提示。
- 已完成 AE 配置项键值对改造：客户端 `trackConfigUsage()` 现在按配置项拆分多条 `config_key/config_value` 事件；Worker `/track` 仅校验 `client_id/client_created_at/version`，`config_usage` 写入 `blob9/blob10`；近期配置查询和 Cron 汇总改为按 `blob9/blob10` 聚合，D1 `stats_configs` 历史保留不清空；Dashboard 增加“原方案覆盖审计”配置卡。验证通过 Worker/Dashboard `node --check`、Worker 动态 import、`cd client; npm run build`、旧 Worker 配置 blob 残留扫描和 `git diff --check`，仅有既有 chunk 体积警告与 LF/CRLF 提示。
- 开始执行 AE 配置项键值对改造：目标是释放 `blob13-blob20`，`config_usage` 改为 `blob9=config_key`、`blob10=config_value`；`ai_request` 和 `resource_click` 字段保持不变；D1 `stats_configs` 历史不清空，AE 旧格式不再兼容。
- 已完成 Analytics stats 两个字段补齐：schema 和 setup 自动补 `stats_versions.client_count`、`stats_models.total_tokens`；Cron 模型汇总写入 `total_tokens`，版本客户端数在客户端最近版本更新后从 `stats_clients.last_active_version` 分组覆盖；历史/近期查询和 Dashboard 展示已同步；新增 `backfill:analytics-stat-fields`，只补这两个字段。验证通过相关 `node --check`、模块动态 import、package JSON 解析和 `git diff --check`，仅有 LF/CRLF 提示。
- 继续补 Analytics stats 两个字段：已恢复计划上下文并读取核心实现，确认需要在 `rollupStatsDay()` 写入 `stats_models.total_tokens`，并在更新 `stats_clients.last_active_version` 后按当前最后活跃版本重算覆盖 `stats_versions.client_count`；Dashboard 需展示版本客户端数和模型 Total Tokens。
- 开始执行 Analytics 统计改造计划收敛实现：用户已手动删除线上 `openbidkit-analytics`，本轮直接按 `client/doc/统计改造计划.md` 简化新版 schema；计划删除 `stats_dimension_clients` 和维度客户端计数，资源累计点击量迁入 `openbidkit-resources.resources.click_count`，客户端资源页改为显示完整累计点击量。
- 已完成 Analytics 统计改造计划收敛实现：`ANALYTICS_DB` schema 删除维度客户端关系表、资源点击表和所有历史维度 `client_count`；Cron 只累加计划要求的页面/版本/配置/模型数量；`/track` 实时写客户端窗口改为当前业务日或前 1 天；资源点击历史写入 `RESOURCE_DB.resources.click_count`，接口展示 D1 累计 + AE 今天；Dashboard 和 Client 已同步展示完整累计点击量。验证通过 Worker/脚本/Dashboard `node --check`、Worker 模块 import、`cd client; npm run build` 和 `git diff --check`。
- 已修复 scheduled rollup 资源库异常影响核心统计的问题：核心 `stats_*` 汇总现在不查询资源点击，完成写入并 `markRollupSuccess()` 后才单独尝试资源点击累加；`RESOURCE_DB` 缺失或资源点击更新失败只记录 warning，不会让每日概览/访问/配置/模型统计失败或留下可重试重复累加风险。验证通过 `node --check` 和模块动态 import。
- 已增强 Analytics stats 回填脚本错误处理：AE 查询和 D1 REST 写入对 `429/500/502/503/504` 自动重试，错误日志包含 HTTP status、返回 body 和 SQL 片段；遇到历史 `failed/running` 状态时，如果当天没有 `stats_daily` 会清理状态并重试，如果已有 `stats_daily` 则停止，避免重复累加。`analyticsQuery.js` 同步增加 AE 查询重试和详细错误日志。验证通过脚本与 `analyticsQuery.js` 的 `node --check`，并验证脚本仍拒绝参数。
- 已新增并按要求简化 Analytics stats 历史回填脚本：`analytics/scripts/backfill-analytics-stats.mjs` 不接受参数，固定读取同目录 `.env`，固定项目 `yibiao-client`，自动发现 AE 中北京时间今天之前的所有有数据日期；脚本用 Cloudflare D1 REST API 封装远程 `ANALYTICS_DB.prepare().bind().run/all/first()`，复用线上 `rollupStatsDay()` 写入新版 `stats_*` 表；跳过 success 日期，遇到 running/failed 状态停止以避免重复累加。新增 `npm run backfill:analytics-stats` 命令并更新 README。验证通过 `node --check` 和参数拒绝检查；本机没有 `analytics/scripts/.env`，未执行真实回填。
- 已完成 Analytics 北京时间统一修复：客户端新生成 `analytics_created_at` 改为 `Asia/Shanghai` 日期；Worker 公共工具新增北京时间 SQL 表达式和自然日范围；`today/7/30/90` 近期 AE 查询、资源点击、项目兜底、最近事件、留存和 Cron 写入 `first_seen_at` 均统一为北京时间口径。验证通过相关 `node --check`、`cd client; npm run build`、北京时间边界用例和 `git diff --check`，仅有既有 chunk 体积警告与 LF/CRLF 提示。
- 优化 `/track` D1 热路径：`recordTrackClient()` 现在只对 `client_created_at` 最近 3 天内的客户端尝试实时写 D1；同一 Worker 实例内通过有上限的内存 Set 避免重复尝试；去掉老客户端每条事件的 D1 SELECT；真实插入新客户端后才更新 `stats_totals.total_clients`；D1 写入失败只 warning，`/track` 仍返回成功。验证通过相关 `node --check`、热路径 grep 复扫和 `git diff --check -- analytics`。
- 修复代码评审指出的历史维度客户端数重复累计问题：新版 migration 增加 `stats_dimension_clients`，Cron 汇总对页面/版本/配置/模型/资源写入 `dimension + client_id` 去重关系，聚合表只累加事件/点击/请求/token，`client_count` 改为从关系表重算累计唯一客户端数。验证通过 `node --check analytics/worker/src/services/analyticsStatsStore.js`、`node --check analytics/worker/src/index.js`、错误模式 grep 复扫和 `git diff --check -- analytics`。
- Analytics 统计新版完整重构已完成代码接入：旧 `analytics_*` migration、旧 D1 查询服务、旧 daily rollup 服务、旧 `/api/summary` 和旧 backfill 脚本已删除；新增 `stats_*` schema、`analyticsStatsStore.js`、`/api/clients`、`/api/client-detail`，`/track` 写 AE 后实时写 `stats_clients`，Cron 改为北京时间 02:00 汇总前一天数据。
- Analytics Dashboard 已改造为新版信息架构：概览去掉时间范围和旧冗余卡片；新增“客户端统计”标签页和客户端详情弹窗；访问/配置/模型范围改为历史/今天/7天/30天默认历史；模型使用增加服务商、域名、模型筛选；最近事件增加事件筛选。
- 文档已同步新版：`analytics/逻辑梳理.md` 改为新版 `stats_*` 数据库和查询逻辑；`analytics/README.md` 改为新版部署、删库重建、接口和口径说明。验证通过 Worker/脚本/Dashboard `node --check`，旧引用扫描通过；`git diff --check -- analytics` 通过，仅有 LF/CRLF 提示。全仓 `git diff --check` 只剩用户先改的 `client/doc/统计改造计划.md` EOF 空行提示，本轮未动该文件。
- 开始 Analytics 统计功能新版完整重构：已复读 `client/doc/统计改造计划.md`，用户确认 `ANALYTICS_DB` binding 名保留、旧 `openbidkit-analytics` 可直接删库重建；本轮会一次性替换统计 schema、Worker 接口、Cron、Dashboard，并同步 `analytics/逻辑梳理.md`。
- 开始执行 Analytics 长期统计与历史总数改造：已读取 `client/doc/统计改造计划.md`、恢复文件型计划并运行 session catchup 无输出；本轮范围为 analytics Worker/Dashboard/脚本/迁移，不改桌面客户端埋点入口。
- Analytics 长期统计 Worker 接入已推进：`/track` 改为先 `ANALYTICS_ROLLUP_QUEUE.send()` 成功后再写 Analytics Engine，Worker `queue()` 已接入 `consumeAnalyticsRollupBatch()`；D1 聚合服务语法检查通过，维度客户端累计改为按关系表重算 totals，D1 batch 超阈值时递归拆子批次并把 done 状态放在同一子批次事务内。
- Analytics D1 历史查询接口已新增/接入：新增 `analyticsD1Query.js`、`/api/overview`、`/api/traffic`，`/api/summary?range=history`、`/api/config-usage?range=history` 和 `/api/model-usage` 可读 D1，资源点击 `range=history` 读 D1，`/api/projects` 优先 D1 回退 Analytics Engine；相关 Worker JS `node --check` 通过。
- Analytics Dashboard 已改造为分区范围控制：顶部移除全局时间范围，概览页读 D1 长期累计并保留独立范围分析选择；访问分析、配置使用、模型使用、资源管理分别支持最近 7/30/90 天和历史总数；ADMIN_TOKEN 默认写 sessionStorage，勾选记住后才写 localStorage；生产看板 API 地址固定到 `https://analytics.agnet.top` 或同源。
- `analytics/README.md` 已补充 D1/Queue 长期统计架构、`setup:analytics-storage`、新增接口、`range=history` 数据源差异、Dashboard Token 存储和指标口径说明。
- Analytics 长期统计验证完成：Worker 新增/修改模块、Dashboard ES Module、setup/deploy 脚本均通过 `node --check`；`git diff --check` 通过，仅有 LF/CRLF 提示。
- 已新增 Analytics Engine 到 D1 历史回填脚本 `analytics/scripts/backfill-analytics-rollups.mjs` 和 `npm run backfill:analytics` 命令；脚本支持 `--remote/--local/--dry-run`、默认阻止回填当前业务日，月度聚合写 `source=backfill`，并重算维度客户端 totals。`node --check` 和 dry-run 验证通过。
- 尝试执行 `npm run setup:analytics-storage` 时 Wrangler 因当前非交互环境缺少 `CLOUDFLARE_API_TOKEN` 停止；远程 `ANALYTICS_DB`/`ANALYTICS_ROLLUP_QUEUE` 尚未在当前 `wrangler.jsonc` 中写入，真实回填需要先配置 Cloudflare 凭据后重跑 setup。
- 已修复 Analytics 访问分析版本分布与今日活跃口径不一致：近期 Analytics Engine 查询不再过滤空版本，空版本统一归为“未知版本”，今日判断改为 `Asia/Shanghai` 业务日；D1 历史模式也把空 `last_version` 归为“未知版本”，并把今日有活跃但不在版本排行中的版本补入结果。最近事件增加页码输入跳转，后端排序改为稳定时间倒排。
- 继续 Analytics 长期统计去 Queue 改造：`/track` 当前只写 Analytics Engine；Worker `scheduled()` 调用每日汇总；`analyticsD1Query.js` 已迁移到 `analytics_daily_*` 表和匿名 hash 索引；`setup-analytics-storage.mjs` 已改成只创建/复用 D1、确认 Cron、执行 migration；`wrangler.jsonc` 已加入 `15 18 * * *`。
- 已重写 `backfill-analytics-rollups.mjs` 为 daily rollup 回填：按上海业务日逐日查询 Analytics Engine，写入 `analytics_daily_summary/page/version/config/model/resource` 和匿名客户端/维度索引，统一 `source=rollup`；`client/doc/统计改造计划.md` 与 `analytics/README.md` 已更新为 D1 + Cron 最终方案，并补充旧 Queue 安全下线顺序。
- Analytics 去 Queue 改造验证完成：`node --check` 覆盖 `analyticsTrack`、`analyticsDailyRollup`、`analyticsD1Query`、Worker 入口、相关 routes、setup/backfill/deploy 脚本；回填 dry-run 覆盖 2026-03-15 到 2026-06-12 共 90 天；`git diff --check` 通过，仅有 LF/CRLF 提示。
- 已修复今日活跃客户端与版本分布不一致残留：`/api/summary` 仍过滤 `blob4 != ''` 且按 UTC 判断今日，已改为和 `/api/traffic` 一样把空版本归为“未知版本”、按 `Asia/Shanghai` 判断今日，并补入只在今日活跃但不在范围版本列表中的版本；`/api/traffic` 今日版本查询去掉 `LIMIT 100`，避免版本组被截断。验证通过 `node --check` 和相关 diff check。
- 已修复“日活客户端大于打开量”的口径漏洞：新增 `analytics_daily_event_client_stats`，Cron/backfill 写入每天每事件去重客户端数；概览今日/昨日/近 7/30 天和每日统计改为按 `app_open` 去重客户端展示，旧行未回填新表时用 `min(active_clients, app_open_count)` 兜底；看板文案从“活跃客户端/客户端数”改为“打开客户端”。验证通过相关 `node --check`、backfill dry-run 和 diff check。
- 开始废标项检查多投标文件支持：已读取现有计划、确认 catchup 无输出，并记录当前单投标文件边界；下一步从类型和 Store/SQLite schema 开始改造，确保 UI 与后台任务共用同一多文件模型。
- 继续废标项检查多投标文件支持收尾：`npm run build` 已通过后，复核发现 v12 迁移提前创建 `role/sort_order` 索引会卡住旧库；已改为先处理旧表结构，再创建完整 schema，并用 Electron runtime 冒烟测试确认旧 v11 库可升级到 v12、旧 bid 迁为 `bid-1`、旧结果写入 `bid_document_id=bid-1`。
- 废标项检查多投标文件支持已完成收尾验证：CJS `node --check` 覆盖 SQLite、fileService、rejectionCheckStore、rejectionCheckTask 和 preload；`cd client; npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 LF/CRLF 提示；旧单文件字段残留复扫无业务依赖。
- 开始已有方案扩写 Step05 正文还原与扩写改造：已将文件型计划切换到本轮任务；目标是在扩写模式中新增原方案还原、基于原文优化扩写、补目录锁定和可选原方案覆盖审计，普通生成技术方案保持不变。
- 已完成前端配置接入：`ContentGenerationOptions` 新增 `enableOriginalPlanCoverageAudit`，正文任务 phase 类型新增 `restoring/original-auditing`；`ContentEditPage` 接收 `workflowKind`，仅扩写模式显示“原方案覆盖审计”开关，启动正文生成和单章重生成时会传递该配置。
- 已完成 Main 侧主体接入：`contentGenerationTask.cjs` 已支持 `original_material` 编排状态、原方案段落拆分、原方案还原映射 Prompt、还原阶段、已还原节点首轮优化扩写分支、`restored && !optimized` 续跑判断，以及补目录 `locked-restored` 锁定规则；`taskService` 已识别新增阶段。
- 已完成已有方案扩写 Step05 收尾：扩写模式可选“原方案覆盖审计”已接入最低字数扩充之后、一致性审计之前；覆盖审计按已还原小节和 `source_ids` 检查 covered/partial/missing/conflict，partial/missing 通过现有 insert/replace 局部补写，conflict 只记录日志；单章重新生成也按目标小节审计。前端进度展示和埋点 payload 类型已同步。验证通过 `node --check electron\services\contentGenerationTask.cjs`、`node --check electron\services\taskService.cjs`、`cd client; npm run build` 和 `git diff --check`；构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已修复 Step05 原方案状态续跑一致性风险：新增原方案运行态校验，续跑和待生成判断同时检查正文、`source_ids` 和 `original_material`；原方案还原正文与 plan、优化正文与 `optimized=true` 改为同一次 Store transaction 落盘；单章重新生成已还原小节会先用真实原文重建并重新优化；覆盖审计只审计有效且已优化的原方案小节。验证通过 `node --check electron\services\contentGenerationTask.cjs`、`node --check electron\services\taskService.cjs`、`cd client; npm run build` 和 `git diff --check`；构建仍只有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已完成 Step05 评审补漏：替换“原方案”后会清空 Step03 目录、Step04 全局事实、Step05 正文/编排/还原/runtime 和相关技术方案任务，保留招标文件、Step02 招标解析结果和参考知识库选择；Analytics Dashboard 补齐 `existing-plan-expansion/*` 子步骤中文映射。验证通过 `node --check electron\services\technicalPlanStore.cjs`、`node --check analytics\dashboard\public\src\pages\traffic.js`、`cd client; npm run build` 和 `git diff --check`；构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已完成两种技术方案模式切换确认：从“生成技术方案”和“已有方案扩写”互相切换时，若存在模式相关进度会弹窗说明保留招标文件、Step02 解析和参考知识库选择，并清空原方案、目录、全局事实、正文、正文生成配置/计划/runtime 和 Step03-Step05 任务；无模式相关进度时静默安全切换；技术方案任务运行中会阻止切换。已通过 `node --check electron\services\technicalPlanStore.cjs`、`node --check electron\ipc\technicalPlanIpc.cjs`、`node --check electron\preload.cjs`、`cd client; npm run build` 和 `git diff --check`，构建仅有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 开始资源管理 D1/R2 与客户端资源下载实现：已确认资源全局一套、R2 bucket 用 `openbidkit`、弹窗内容按 Markdown 渲染；进入文件型计划跟踪，先做 Analytics 自动化存储与 Worker 接口。
- 已完成资源管理主体代码接入：新增 D1 `resources` migration、`setup-resource-storage.mjs` 自动创建/复用 D1 与 R2 并应用 migration；Worker 新增 `/resources`、`/resource-image`、`/api/resources`；Dashboard 新增资源管理 Tab 和 multipart 图片上传表单；Client 资源页改为接口读取、搜索和 Markdown 弹窗。第一轮 `node --check` 覆盖脚本、Worker routes/services/index 和 Dashboard resources 页面均通过。
- 资源管理实现验证完成：`node --check` 覆盖 Analytics 部署脚本、资源 setup 脚本、Worker 入口/资源路由/资源 Store、Dashboard 主脚本/API/资源页；`cd client; npm run build` 通过；`git diff --check` 通过且仅有 LF/CRLF 提示，客户端构建仍只有既有 chunk 体积警告。
- 客户端资源下载页图片展示收尾完成：真实图片由裁切填充改为 `object-fit: contain` 并增加内边距，列表和详情弹窗共用封面组件因此都会完整显示图片；`cd client; npm run build` 通过，`git diff --check -- client/src/styles.css` 仅有 LF/CRLF 提示。
- 开始 Step03 目录排序与局部正文保留实现：目标是不新增 IPC 通道，改造 `saveOutline()` 语义，排序保留正文并支持未保存排序离开确认；当前工作区存在非本次修改的 `文章/新系列一：关于AI知识库的一点拙见.md`，本轮不触碰。
- 已完成 Step03 目录排序与局部正文保留实现：`saveOutline()` 改为 `outlineData/reason/idMap/affectedNodeIds` 入参；排序按旧 ID 到新 ID 映射迁移正文、章节状态和正文规划；编辑、删除、添加子目录只清空涉及正文；全局事实不再受目录操作影响；Step03 支持同级拖拽排序、保存排序、切换步骤/主菜单时询问“排序结果是否保存”。验证通过 4 个 CJS `node --check`、`npm run build` 和 `git diff --check`，构建仍只有既有 chunk 体积警告，diff check 只有 LF/CRLF 提示。
- 开始执行多模块开发者模式文件日志：范围扩展到文件解析、标书查重、废标项检查和 Word 导出；日志统一放入 `userData/logs/<module>/`，不写 SQLite，不改变业务逻辑。
- 已完成多模块开发者模式文件日志：新增通用 `electron/utils/developerLog.cjs`，`paths.cjs` 提供 `getDeveloperLogsDir()`；`aiService` 暴露通用 `createDeveloperLogger()` 并保持 technical-plan 日志行为；文件解析写入 `logs/file-parser/`，标书查重写入 `logs/duplicate-check/`，废标项检查写入 `logs/rejection-check/`，Word 导出写入 `logs/export/`。日志只在开发者模式开启时写 JSONL，记录计数、hash、耗时、warning 和错误，不写 API Key/Token/Base URL/完整输出路径。验证通过相关 CJS `node --check`、`npm run build` 和 `git diff --check`；构建仍只有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 开始实现技术方案开发者模式文件日志：用户明确需要类似 AI 日志的详细程序执行日志，放入 `logs` 文件夹，不写 SQLite；已确认当前 SQLite 只适合任务状态和界面日志。
- 已完成技术方案开发者模式文件日志：新增 `userData/logs/technical-plan/*.jsonl` 写入能力；正文生成任务会记录任务启动/完成/失败、章节保存、一致性审计分组和冲突、一致性修复最终 patches、每个 patch 的 old/new 文本、匹配次数、行号命中、应用结果和保存后的正文 hash。验证通过 `node --check electron\services\aiService.cjs`、`node --check electron\services\contentGenerationTask.cjs`、`node --check electron\utils\paths.cjs`、`npm run build` 和 `git diff --check`；构建仍只有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 开始执行 Step05 全文一致性审计实现：已确认默认开启、单章重新生成也审计；修复策略改为 opencode 风格的 `old_text/new_text` 精确唯一替换，不使用 anchor 模糊定位或 replaceAll。
- 已完成全文一致性审计代码接入：`ContentGenerationOptions` 新增 `enableConsistencyAudit`；正文生成配置弹窗新增开关；任务 stats 新增 `auditing` 阶段和审计/修复计数；全文生成、补字数和单章重生成都会把开关传给 Main。
- Main 侧已新增审计分组、审计 JSON、修复 JSON、行号辅助、精确唯一替换和失败重试逻辑；审计插入在最低字数补足后、配图前；修复失败只记录日志，不阻塞配图；修复后若低于最低字数会补足一次并复审一次。
- 已更新 `taskService.cjs` 中断恢复阶段识别 `auditing`；验证通过 `node --check electron\services\contentGenerationTask.cjs`、`node --check electron\services\taskService.cjs` 和 `cd client; npm run build`，构建仅有既有 chunk 体积警告。
- 已补充审计阶段进度条配色，并在样式变更后重跑 `cd client; npm run build` 通过，仍仅有既有 chunk 体积警告。
- 最终 `git diff --check` 通过，仅输出既有 LF/CRLF 提示。
- 开始 Step04 全局事实设定实现：已确认需要新增 `global-facts` 步骤、SQLite v4 表、Main 后台任务、Renderer 页面、IPC/preload 类型，以及后续正文生成 prompt 注入和前置校验。
- 已完成 Step04 全局事实设定：Main 侧新增 `global-facts-generation` 两轮 AI 任务并接入任务组；SQLite v4 新增 `technical_plan_global_fact_groups`；Renderer 新增 `GlobalFactsPage`，进入时无内容自动启动，支持左侧事实大项、进度、右侧 Markdown 编辑/预览/保存/重解析；`TechnicalPlanHome` 插入 Step04 并要求全局事实完成后才能进入正文生成。
- 已将全局事实注入后续正文链路：`contentGenerationTask.cjs` 启动正文生成前校验 `globalFactsTask.status === success` 且事实非空，并把事实注入正文编排、正文生成、最低字数补目录、正文扩写和 Mermaid 修复提示词。上游招标解析全量重跑、目录生成/编辑会清空全局事实和后续正文缓存；手动保存事实会清空旧正文缓存。
- 验证完成：`node --check` 覆盖 `electron\services\globalFactsTask.cjs`、`taskService.cjs`、`contentGenerationTask.cjs`、`technicalPlanStore.cjs`、`sqliteDatabase.cjs`、`electron\ipc\taskIpc.cjs`、`technicalPlanIpc.cjs`、`index.cjs` 和 `electron\preload.cjs`；`cd client; npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 LF/CRLF 提示。
- 已完成 Step05 正文编排事实选择改造：`ContentGenerationPlanData` 新增 `facts.titles`；编排阶段额外传入 Step02 项目信息、甲方信息、交货和服务要求，以及 Step04 全局事实标题清单；正文生成、单章重新生成、正文扩写和 Mermaid 修复按编排选中的标题解析事实详情后注入 prompt。验证通过 `node --check electron\services\contentGenerationTask.cjs`、`cd client; npm run build` 和 `git diff --check`，构建仍只有既有 chunk 体积警告，diff check 仍只有 LF/CRLF 提示。
- 开始技术方案 SQLite 存储改造：范围限定技术方案模块；已读取既有文件型计划，确认本轮要移除旧 `technical_plan.json` 兼容、招标 Markdown 文件化、结构化数据进入 SQLite，并按方案分批改造 Main/IPC/Renderer/任务服务。
- 已完成技术方案 SQLite 存储改造收尾：新增 `sqliteDatabase.cjs`、`technicalPlanStore.cjs`、`technicalPlanIpc.cjs`，接入 `window.yibiao.technicalPlan`；技术方案招标文件 Markdown 保存到 `workspace/technical-plan/tender.md`，结构化状态保存到 `workspace/yibiao.sqlite`。
- 已清理旧技术方案 workspace API：Renderer 不再调用 `window.yibiao.workspace.load/save/update/clearTechnicalPlan`；`workspaceStore.cjs` 只保留标书查重和废标项检查；废标项检查从技术方案读取招标文件时改用 `technicalPlan.loadState()` 和 `readTenderMarkdown()`。
- 已收紧技术方案后台任务输入：Step02 招标解析只从 Main 侧 Markdown 文件读取；Step03 只从 SQLite 读取项目概述和技术评分要求；Step04 只从 SQLite 读取目录、项目概述、技术要求和参考知识库配置，不再接收 Renderer 传完整目录或大文本。
- 已补强目录保存规则：`technicalPlanStore.saveOutline()` 在 Main 侧强制清空目录正文和正文生成缓存，避免目录编辑/重生成后旧正文污染导出。
- 验证完成：`node --check` 覆盖 SQLite、技术方案 Store/IPC、任务服务、Step02/Step03/Step04 任务和 preload；SQLite Store 冒烟测试通过；`cd client; npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 仅有 LF/CRLF 提示；`npm audit` 仍为 3 个漏洞（2 moderate、1 high），未自动修复。
- 已修复 Electron 启动后 `config:load` 未注册：复现日志显示 `better-sqlite3.node` ABI 不匹配（Node 137 vs Electron 145）导致 SQLite 初始化在 IPC 注册前抛错；已新增 `postinstall` 自动执行 `electron-builder install-app-deps`，本地已重建 native 依赖，并调整 IPC 注册顺序让基础配置接口先注册；`client/开发说明.md` 已补充 native 依赖重建说明。验证通过 `npm run postinstall`、`npm run start`、`npm run dev`、`npm run build`、相关 `node --check`。
- 已按用户要求只落文档、不改代码：新增 `client/doc/sqlite改造方案_废标项检查和标书查重.md`，明确旧 `duplicate_check.json` / `rejection_check.json` 不迁移、不读取、不 fallback；将 SQL 说明从 `sql/technical_plan_schema.sql` 重命名为 `sql/workspace_schema.sql` 并写入 v2 目标表结构；同步更新 `client/开发说明.md` 和技术方案 SQLite 文档中的 SQL 文件引用。
- 开始 Step04 正文生成暂停与继续：目标是在不强制中断当前 AI 请求的前提下，点击暂停立即显示“正在暂停中”，当前并发请求完成后进入 paused 并允许导出；继续时从 workspace 恢复扩写/配图进度。
- 已完成暂停/继续第一轮代码接入：`taskService` 增加 content-generation 暂停控制器和 `tasks:pause-content-generation` IPC；正文生成任务增加 `contentGenerationRuntime`、安全检查点、扩写轮次持久化、pausing/paused 落盘和 resume 恢复。CJS 语法检查已通过 `taskService.cjs`、`contentGenerationTask.cjs`、`taskIpc.cjs`、`preload.cjs`。
- 已修复并验证暂停/继续恢复细节：resume 时改用任务启动前的 workspace 快照，避免 taskService 先写入 running 后让 runner 看不到 paused；扩写恢复保持首批仅中位数、后续左右扩散。暂停/继续 smoke test 和扩写进度恢复 smoke test 均通过。
- Step04 正文生成暂停与继续验证完成：`node --check` 覆盖 `taskService.cjs`、`contentGenerationTask.cjs`、`taskIpc.cjs`、`preload.cjs`；暂停/继续 smoke test、扩写恢复 smoke test、单小节暂停继续 smoke test、`npm run build`、`git diff --check` 均通过。构建仍只有既有 chunk 体积警告，diff check 仅 LF/CRLF 提示。
- 已修复软件重启后扩写中任务显示成编排中的问题：`taskService.updateTask()` 现在会把每次任务阶段 stats 同步持久化到 workspace；`getActiveTasks()` 发现 workspace 中正文任务仍是 running/pausing 但 Main 无 active task 时，会自动改为 paused，并用 runtime 或“已生成数量 + 最低字数”推断 phase。已验证扩写阶段快照落盘和 stale running 恢复为 paused + expanding。
- 开始 Step04 最低字数控制实现：已根据 `client/doc/字数控制.md` 和用户反馈确认范围，准备先新增统一字数统计，再扩展配置/UI，最后改造 Main 侧正文生成任务，把扩写插入配图前。
- 已完成第一轮代码接入：新增 Renderer/Main 同口径字数统计工具；Step04 配置 UI 增加最低字数，任务 stats 支持 `outline-expanding/expanding`；Main 侧正文任务已插入补目录、生成新增叶子、无限扩写和配图前统一刷新配图目标。`node --check` 已通过 `contentGenerationTask.cjs`、`wordCount.cjs`、`preload.cjs`。
- 验证进展：`npm run build` 通过，仅有既有 chunk 体积警告；正文任务模块加载通过；字数统计 smoke test 返回 9，确认图片、Mermaid 代码块和裸 URL 未计入；最低字数扩写 smoke test 通过，任务最终 `success` 且字数达标；补目录清理旧叶子 smoke test 通过，旧 `1.1` section/plan 被移除，新 `1.1.1` section 生成。
- 修正并验证“继续生成”配图范围：最终配图目标只取本轮生成/扩写过的叶子，避免保留的旧章节重复插图；smoke test 确认已有 `1.1` 未重复配图，新增 `1.2` 正常配图。
- 开始执行后台任务组锁与技术方案清空策略：已确认当前文档规则，准备先改 `taskService.cjs` 的技术方案/废标项任务定义与锁检查，再把 Step02/Step03/Step04 清空规则收敛到 Main 侧。
- 已完成后台任务组锁与技术方案清空策略：`taskService.cjs` 新增任务定义、组锁冲突检查和任务元数据；技术方案/废标项检查组内不同任务并发启动会被拒绝；Step03 启动时 Main 侧清旧目录/正文；Step02/Step04 去掉 Renderer 启动前业务清空。验证通过 4 个 CJS `node --check`、技术方案组锁冲突 smoke test、`cd client; npm run build` 和 `git diff --check`，构建仅有既有 chunk 体积警告，diff check 仅有既有 LF/CRLF 提示。
- 已完成标书查重迁入任务组体系：新增 `duplicate-analysis` 外层任务和 `duplicateCheck` stateKey；`duplicateCheckService.runAnalysisTask()` 作为 taskService runner，内部元数据/目录/正文/图片子流程并发保持不变；前端改为 `tasks.startDuplicateAnalysis()` + `tasks.onTaskEvent()`；旧 `duplicate-check:start-metadata-analysis` IPC 兼容转发到 taskService。验证通过相关 CJS 语法检查、模块加载、任务注册 smoke test、`npm run build` 和 `git diff --check`。
- 开始 DOC/WPS 本地转换后端自动识别：已确认现有链路只在 `withLegacyWordDocxFile()` 中找 LibreOffice；本轮会保留后续 DOCX Markdown 提取，只新增 LibreOffice/WPS/Word 候选转换和统一提示。
- 已完成 DOC/WPS 本地转换后端自动识别：`withLegacyWordDocxFile()` 现在按候选后端实际转换并校验 DOCX；Windows 通过 PowerShell COM 支持 WPS/Word；缺失提示已改为 LibreOffice/WPS Office/Microsoft Word 任一即可。验证通过 `node --check`、转换模块动态 import、`npm run build`、`git diff --check`；构建仍只有既有 chunk 体积警告，diff check 只有 LF/CRLF 提示。
- 开始废标项检查流式检查与单项重试改造：已先按用户要求把流式 JSON 请求使用方法和 JSON 修复边界写入 `client/开发说明.md`；本轮不新增后端到页面的流式返回，只改 Main 到 AI 服务商的请求模式。
- 已完成废标项检查流式检查与单项重试改造：Main 侧三类检查主请求改用 `streamChat`，JSON 解析失败复用原非流式修复链路；页面错误态新增只重试当前检查的按钮；验证通过 CJS `node --check`、`npm run build` 和 `git diff --check`，仅有既有 LF/CRLF 与 chunk 体积警告。
- 已修复废标项检查流式进度导致的前端扰动：Main 侧不再把流式 chunk 接收字数写入 workspace，只保留阶段状态和最终结果；Renderer 后台任务事件同步时不再覆盖当前用户查看的 Step/Tab，避免切到错别字检查后被任务事件切回废标项检查。验证通过相关 CJS `node --check`、`npm run build` 和 `git diff --check`。
- 已修复小米模型逻辑谬误 JSON 非法转义问题：`aiService.cjs` 在原始候选解析失败后会尝试修复 JSON 字符串内部的非法反斜杠转义（如 `1\.`），并补强 JSON 修复 prompt；旧小米日志内容解析 smoke test 返回 3 条 findings，`node --check`、`npm run build`、`git diff --check` 通过。
- 开始实现废标项检查 Step03 三类并发检查：用户要求废标项检查、错别字检查、逻辑谬误检查并发执行；错别字结果用 `错别字 -> 正确的字` 折叠列表展示并支持复制真实原文；逻辑谬误结果展示标题、原文/位置、原因和建议。
- 已完成三类检查代码接入待验证：新增错别字/逻辑谬误类型、工作区缓存字段、Prompt 和 service；Step03 会按配置并发启动废标项、错别字、逻辑谬误任务；错别字结果先用投标文件原文精确定位并重截取原文片段，无法定位的候选会被过滤。
- 验证完成：`cd client; npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 Git LF/CRLF 提示。
- 开始 Analytics 远程公告通道实现：用户确认使用 Cloudflare KV；目标是 Worker/Dashboard/Client 全链路实现 Markdown 公告，客户端与 30 分钟版本检查共用轮询，公告关闭后同 ID 不再显示。
- 文件型计划 catchup 首次使用示例路径失败，实际脚本位于 `~/.config/opencode/.../session-catchup.py`，已重跑成功并记录到计划。
- 已完成 Analytics Worker 和 Dashboard 公告管理改造：Worker 新增公开 `/notice`、管理员 `/api/notice` GET/POST/DELETE；Dashboard 新增公告标题、启用状态、Markdown 内容、读取/发布/停用交互。
- 已完成客户端远程公告接入：`UpdateNotifier` 与版本检查共用 30 分钟定时器，公告使用独立 Dialog 和 Markdown 渲染，关闭后以 `remote_notice_dismissed_id` 记录同 ID 不再显示。
- 已新增 `analytics/scripts/setup-notice-kv.mjs` 和 `analytics/worker` 的 `setup:notice-kv` 脚本，文档补充 KV 创建、公告接口、Dashboard 使用和排查说明。
- 验证进展：`node --check analytics/worker/src/index.js` 和 `node --check analytics/scripts/setup-notice-kv.mjs` 已通过；Dashboard 内嵌脚本首次检查失败是检查命令正则转义问题，准备换字符串索引方式重跑。
- 第一次 `npm run build` 发现 `remoteNotice.ts` 中 `notice.enabled !== false` 在类型收窄后恒为 true，已改为过滤后直接归一 `enabled: true`。
- 复查公告停用流程时发现 `DELETE /api/notice` 需要 CORS 预检支持，已将 Worker `Access-Control-Allow-Methods` 补充 `DELETE`，并重跑 Worker 语法检查通过。
- 远程公告通道验证完成：`node --check analytics/worker/src/index.js`、`node --check analytics/scripts/setup-notice-kv.mjs`、Dashboard 内嵌脚本 `new Function` 检查、`cd client; npm run build`、本轮变更文件 `git diff --check` 均通过；构建仍只有既有 chunk 体积警告，diff check 仍只有 LF/CRLF 提示。
- 用户本地执行 `npm run setup:notice-kv` 失败，原因是本地 Wrangler 没有 `CLOUDFLARE_API_TOKEN` 且脚本以非交互方式调用 Wrangler。已改造为部署前自动幂等执行：优先复用 `NOTICE_STORE_ID`/已配置 id/账号中已有 namespace，不存在才创建；`deploy-if-changed.mjs` 会在 `analytics/worker` 部署前调用该脚本。
- 开始活跃留存与配置使用统计改造：已进入文件型计划，范围限定为客户端配置使用上报、Worker 汇总查询和 Dashboard 展示，不做任务漏斗/错误/耗时统计。
- 已完成客户端埋点接入：`user_config.json` 新增 `analytics_created_at`；`analytics.ts` 支持 `config_usage`；应用启动、设置保存、生图测试、Step02/Step03/Step04 启动会按白名单上报配置枚举值。
- 已完成 Worker 和 Dashboard 改造：Worker 支持 `config_usage`，新增 `/api/retention`、`/api/config-usage`，`summary` 增加活跃/新老客户端；Dashboard 增加活跃指标卡、留存概览、配置使用分布和最近事件分页。
- 验证通过：`node --check analytics/worker/src/index.js`、`node --check client/electron/services/configStore.cjs`、Dashboard 内嵌脚本 `new Function` 语法检查、`cd client; npm run build`、本次改动文件 `git diff --check`。构建仍只有既有 chunk 体积警告，diff check 仍只有 LF/CRLF 提示。
- 已修复代码评审提出的旧匿名客户端 ID 迁移问题：`analytics.ts` 会读取旧 `localStorage.analytics_client_id`，优先用旧 ID 覆盖并保存到 `user_config.json`；当前埋点也直接使用旧 ID。验证通过 `cd client; npm run build` 和 `git diff --check -- client/src/shared/analytics/analytics.ts`。
- 已修复代码评审提出的 `/api/latest` 分页总数采样口径问题：分页 total 改用 `COUNT()`，与 `LIMIT/OFFSET` 明细行数一致，不再用 `SUM(_sample_interval)` 估算事件数。验证通过 `node --check analytics/worker/src/index.js` 和 `git diff --check -- analytics/worker/src/index.js`。
- 已修复线上 `/api/summary`、`/api/retention` 返回 `query failed` 的高风险 SQL：移除 `toDateOrNull/dateDiff/COUNT(DISTINCT IF(...))` 组合，summary 改为多个简单去重查询，retention 改为查询 app_open 明细后在 Worker JS 中计算；查询失败时增加 `console.error`，并在 `analytics/README.md` 补充 `wrangler tail` 查看日志方式。验证通过 `node --check analytics/worker/src/index.js` 和 `git diff --check`。
- 已初始化文件型计划，用于跟踪导入招标文件页面重做任务。
- 已查看客户端导入页、现有文件解析服务、配置存储和工具目录概览，确认需要重做 UI 并重写解析服务分流。
- 已细读 doc2markdown-node、MinerU Agent、MinerU 精准 API demo 的关键流程，下一步迁入/复用解析逻辑。
- 已完成客户端解析链路改造：Electron 文件服务按配置分流本地解析、MinerU-Agent、MinerU 精准 API；导入页改为配置标题 + Markdown 渲染器。
- 已通过 `node -e "require('./electron/services/fileService.cjs'); console.log('file service ok')"`、`node -e "import('./electron/services/doc2markdown/convert.mjs').then(() => console.log('converter ok'))"`、本地 Markdown 转换 smoke test、`npm run build`、`npm audit`。
- 开始技术方案缓存迁移：目标是从 Renderer `localStorage` 改为 Electron Main 侧 `userData` 文件存储，并同步开发说明。
- 已完成技术方案缓存迁移：新增 `workspaceStore.cjs`、`workspaceIpc.cjs`、preload `window.yibiao.workspace`，技术方案 Hook 改为异步读写 Main 侧缓存；`npm run build` 通过。
- 已完成 Step02 招标文件解析：新增解析模式切换、并发流式解析、进度与结果展示，项目概述和技术评分要求成功且进度 100% 后才允许进入目录生成；`npm run build` 通过。
- 已重做 Step02 用户体验：模式选择改为明确的按钮式 Segmented Control，结果展示改为左侧任务列表 + 右侧单项阅读器，不再把所有解析结果铺满页面；`npm run build` 通过。
- 已完成 Step03 目录生成迁移：将旧版后端目录生成 Prompt 与自由/评分项对齐工作流迁入 client service，新增目录生成页面、过程日志、目录树、详情编辑、添加/删除目录项；`npm run build` 通过。
- 已完成 Step02/Step03 后台任务化：新增 Main 侧 `taskService`、`bidAnalysisTask`、`outlineGenerationTask` 和 `tasks:*` IPC/preload，招标文件解析和目录生成切页面不中断，任务状态与结果持续写入 `technical_plan.json`；`npm run build` 和任务模块加载验证通过。
- 已严格对齐后端 `/api/outline/generate-stream` 的目录生成容错机制：client `aiService` 新增 `collectJsonResponse`，目录生成每一步改为 schema 标准化 + validator + JSON 修复 + 最多 3 轮重试；`outlineGenerationTask.cjs` prompt、validator 和工作流已按 backend `OutlineService` 迁移；模块加载、假 AI 流程和 `npm run build` 验证通过。
- 开始 Step04 正文生成与 Word 导出：已确认后端正文生成接口、导出 Word payload、旧前端叶子节点生成逻辑和 client 当前任务/导出占位结构。
- 已新增 Main 侧正文生成任务、任务 IPC/preload 入口、技术方案正文状态类型、Step04 页面主体和 Word 导出服务；首次 CJS 模块验证发现 `??`/`||` 混用语法错误，已改为中间变量修复。
- Step04 正文生成与 Word 导出已完成集成：模块加载验证、Word buffer 生成、假 AI 正文任务流程和 `npm run build` 均通过；构建仍有既有 chunk 体积警告。
- 已核对并修复 Step04 代码评审问题：目录变更时清空正文生成缓存和 outline 节点旧 content；正文 Markdown 渲染移除 `rehypeRaw`，避免模型输出 HTML 被渲染成 DOM；任务模块加载和 `npm run build` 通过。
- 已给正文生成结果增加开头重复章节标题过滤：在 Main 侧流式结果写入工作区前清理独立标题行，覆盖编号标题、Markdown 标题、加粗标题和中文序号标题；针对性用例、假 AI 任务和 `npm run build` 通过。
- 开始 toolbar 拖动与页面内部滚动优化：已进入文件型计划，目标是让底部悬浮工具条可通过手柄拖动，并消除页面全局滚动条。
- 已完成 toolbar 拖动与页面内部滚动优化：`FloatingToolbar` 增加拖动手柄和边界约束；全局布局改为 `100vh` 内部滚动；设置页拆成内部滚动层和悬浮工具条层；移除 toolbar 底部预留空间；`client/开发说明.md` 已补充规则；`npm run build` 和 `git diff --check` 通过。
- 开始 GitHub Release 自动打包与更新检查：目标是 `v*` tag 触发 Windows/macOS 构建，自动生成 Release notes，并在打包客户端启动时检查 GitHub Release 更新。
- 已完成 GitHub Release 自动打包与更新检查：安装 `electron-builder` / `electron-updater`；补齐 `client/package.json` 打包配置；新增 `.github/workflows/release.yml`；新增 `updateService.cjs` 并接入主进程；更新开发说明；`npm run build`、`npm audit`、`updateService` 模块加载、Windows unpacked 和 NSIS 打包验证通过。
- 已修复首次远程发布验证问题：`v2.0.1` Actions 成功但 Release 无产物，是因为正式 Release 与 electron-builder 默认 draft 发布类型冲突；workflow 已改为构建后用 `gh release upload --clobber` 显式上传，同时 Release notes 改为基于 `git log` 生成，并支持手动输入已有 tag 重新发布。
- 已修复 Actions `Build renderer` 的 `TS2688: Cannot find type definition file for 'plist'`：新增 `@types/plist` devDependency，并在 workflow 中补装该类型包以兼容手动重跑旧 tag；`npm run build` 和 `npm audit` 通过。
- 已确认用户此前点击的是旧 run 的 `Re-run all jobs`，不会使用 main 上修复后的 workflow；已通过 `gh workflow run release.yml --ref main -f tag_name=v2.0.1` 触发最新 workflow，`v2.0.1` Release 已成功上传 13 个构建资产并更新提交列表说明。
- 已排查 Windows 安装包“无响应”：下载文件完整且可解包，本地启动后安装器进程有响应窗口；同时已将后续构建产物命名修正为 `Yibiao-版本-平台-架构.ext`，本地 NSIS 构建验证通过。
- 已修复打包后图标仍为 Electron 默认图标：恢复 Windows exe 图标资源编辑；macOS workflow 在打包前从 `assets/icon_256.png` 生成 `assets/icon.icns`；`package.json` 格式、`npm run build` 和 `git diff --check` 通过。
- 已统一 Step02/Step03 左侧进度块为 Step04 的 `content-outline-stats` 风格：Step02 任务列表、Step03 生成日志保持独立滚动；清理旧进度卡样式；`npm run build` 和 `git diff --check` 通过。
- 已将 Step04 Word 导出从手写 XML/浅层 Markdown 正则改为 Markdown AST 到 `docx` 对象模型：支持标题、加粗、斜体、删除线、链接、列表、表格、引用、代码块和图片导出；模块 smoke test、表格/图片 zip 检查、`npm run build`、`npm audit` 和 `git diff --check` 通过。
- 已完成 Step04 正文智能表格与可选配图：设置页新增生图模型状态显示和测试结果持久化；正文生成先做 AI 编排决策，再按决策生成 Markdown 表格和可选图片；生图结果保存到 `workspace/generated-images/` 并以 `yibiao-asset://generated-images/...` 插入正文；预览协议和 Word 导出读取均已支持；模块加载、无生图/有生图 smoke test、`npm run build`、`git diff --check` 通过。
- 已完成 Step04 正文首批体验修正：生成正文落盘前规范 `<br>`，前端正文页启用 raw `<br>` 渲染，Word 导出将 `<br>` 写成真实换行；图例去掉“AI 生成示意”；图片和图例居中；图片支持点击全屏查看；开发者模式下显示配图计划/尝试/成功/失败/跳过统计；`npm run build`、正文任务 smoke test、Word `<br>` 导出 smoke test、`git diff --check` 通过。
- 已完成 Step04 正文第二批优化收尾：mermaid.ink `pako:` 编码改为压缩 JSON 状态；正文任务插入的 Mermaid URL 返回 200 image/png；Word 导出 Mermaid 代码块可嵌入 `word/media/*.png`，且不保留 Mermaid 源代码；mermaid.ink 失败时 Word 导出写入可读占位不崩溃；模块加载、正文任务 smoke test、Word 导出 smoke test、失败路径 smoke test、`npm run build` 和 `git diff --check` 均通过。`npm run build` 仍有既有 chunk 体积警告，`git diff --check` 仍有 LF/CRLF 提示。
- 已完成 Step04 正文第三批优化：安装 `mermaid` 依赖；正文生成中的 Mermaid 改为保存代码块；正文页用 Mermaid 动态导入进行前端本地渲染；Word 导出新增 `export:word-progress` 事件、preload 订阅、Renderer 进度弹窗和核对提示；导出服务返回图片失败 warnings 并写控制台日志，失败时 Word 中保留可读占位。模块加载、正文任务 Mermaid 代码块 smoke test、Word Mermaid 图片导出 smoke test、失败路径 smoke test、`npm run build`、`git diff --check` 均通过。构建新增 Mermaid 动态分包，仍有 chunk 体积警告；`git diff --check` 仍有 LF/CRLF 提示。
- 已修复 Step04 评审问题：正文编排阶段单章节失败会降级为纯正文生成，不再阻断全文任务；Word 导出识别 WebP 并在 Electron 运行时转 PNG；Word 导出补充常见 HTML 节点转换和不支持标签 warning。模块加载、编排失败降级 smoke test、HTML 表格/列表/换行导出 smoke test、WebP Node 失败路径、`npm run build` 和 `git diff --check` 通过。普通 Node 环境无 `nativeImage`，WebP 真正转 PNG 需在 Electron Main 运行时手动复验。
- 已优化 Step04 进度展示：正文任务 stats 增加 `content.phase`、编排总数/完成数和生成总数/完成数；前端在编排阶段优先显示绿色“编排统计”进度条，目录节点从“待生成”改为“编排中”；编排完成后自动切回原有正文生成进度。模块加载、正文任务 stats smoke test、`npm run build` 和 `git diff --check` 通过。
- 已完成 Step04 前端性能优化（不改流式 chunk 节流）：合并正文任务开始/完成/失败处的重复状态事件；`ContentEditPage` 预计算目录节点状态、叶子数和字数，避免渲染目录时反复递归统计；正文 Markdown 渲染拆为 `memo` 组件，只有正文内容变化才重新解析；`TechnicalPlanHome` 使用最新 `event.task` 并把 UI 任务日志裁剪为最近 80 条。模块加载、正文任务事件 smoke test、`npm run build` 和 `git diff --check` 通过。
- 已修复 Step04 全文重新生成行为：点击“重新生成正文”并确认开始后，Renderer 先清空全文正文、章节状态、任务进度并写入工作区缓存；Main 侧收到全文 `regenerate` 时也清空 outline content 和 sections 后再计算初始进度，避免旧内容导致进度仍是 100%。全文重新生成清空 smoke test、`npm run build` 和 `git diff --check` 通过。
- 已完成 Step04 Mermaid 配图渲染失败自修复：正文任务在追加 Mermaid 代码块前先做前端兼容规则和 mermaid.ink 渲染校验；失败后调用文本模型按错误信息最多修复 3 轮；修复通过写入修复后的 Mermaid，连续失败则取消该 Mermaid 配图、保留正文并记录失败统计。模块加载、修复成功 smoke test、连续失败取消 smoke test、`npm run build` 和 `git diff --check` 通过。
- 已完成 Step04 配图阶段重构：编排阶段允许 AI 生图和 Mermaid 双候选；正文生成阶段只保存纯正文；新增 `illustrating` 配图阶段和前端配图进度；配图阶段先按 AI 上限选择 AI 目标，未入选 AI 但有 Mermaid 候选的章节降级为 Mermaid；AI 生图并发 2、Mermaid 校验/修复并发 5，AI 生图失败不自动降级 Mermaid。配图阶段 smoke test、模块加载、`npm run build` 和 `git diff --check` 通过。
- 已修复 Step04 Word 导出表格与编号问题：`parseMarkdown()` 前对 Markdown 表格做导出层归一化，支持标题后紧跟表格和表格行被压成一行的情况；Markdown/HTML 有序列表改为每个列表块独立 numbering reference，避免 Word 跨块连续编号。模块加载、导出 smoke test、`npm run build` 和 `git diff --check` 通过；`git diff --check` 仍只有 LF/CRLF 提示。
- 已完成 Step04 Word 导出压缩表格二次修复：针对截图中的“表头正常、分隔行后拼接数据行”形态，导出前按表头列数拆回 GFM 表格行；截图同形态 smoke test 生成 1 个 Word 表格和 3 行表格行，且不再残留 `:---` 文本。`exportService` 模块加载、`npm run build`、`git diff --check` 通过；构建仍有 Mermaid 相关 chunk 体积警告，`git diff --check` 仍只有 LF/CRLF 提示。
- 已完成 Step04 单章重新生成流程调整：新增 `contentGenerationPlans` 持久化最终编排/配图决策；全文生成后保存每个小节 `ai`/`mermaid`/`none`；单章重新生成优先复用历史编排并跳过编排模型，缺失时只编排目标小节一次，然后重新生成正文并按编排结果重新配图。单章复用与缺失两条 smoke test、正文任务模块加载、`npm run build`、`git diff --check` 通过；`git diff --check` 仍只有 LF/CRLF 提示。
- 已修复 Step04 Word 导出 HTML 容器 P2：`div/section/article` 包含表格、列表、引用、图片等块级子节点时递归导出为 Word 原生结构；纯内联容器仍保持单段落输出；`p` 中出现块级子节点也拆块处理。HTML wrapper smoke test 通过：包裹表格生成 2 个 Word 表格，包裹列表保留 2 个列表项；`exportService` 模块加载、`npm run build`、`git diff --check` 通过，仍只有 LF/CRLF 提示。
- 已修复 Step04 Word 导出列表项内表格问题：Markdown 表格归一化现在会保留空白前缀缩进，并让压缩表格拆出的行继承表头缩进，避免列表内 GFM 表格被破坏。列表项内表格 smoke test 通过：生成 1 个 Word 表格、外围列表保留 2 个列表项，且不残留 `| 备件类别` 或 `:---` 文本；`exportService` 模块加载、`npm run build`、`git diff --check` 通过，仍只有 LF/CRLF 提示。
- 开始知识库完整分析流程重构：已根据用户确认记录完整方案、关键取舍和提示词缓存策略；下一步梳理现有知识库服务、IPC、类型和页面。
- 已梳理现有知识库 Main 服务和 IPC：当前上传后立即 AI 整理并生成 `items.json`，前端没有继续分析入口；需要改为先生成候选条目和 block，再由用户输入批次大小启动匹配。
- 已完成知识库完整流程重构：上传后准备 Markdown、block、筛除日志和两轮候选条目；新增 `startMatching/readAnalysis` IPC/preload/type；前端新增分析调试页和批次输入；匹配阶段按固定全文前缀 + 变量条目批次调用 AI，随后补漏最多两轮并由程序回填正文。
- 验证通过：`node --check electron/services/knowledgeBaseService.cjs`、`node --check electron/ipc/knowledgeBaseIpc.cjs`、`node --check electron/preload.cjs`、知识库 block/filter/prompt smoke test、两次 `npm run build`。`git diff --check` 仅发现非本次修改的 `client/doc/知识库设计.md` EOF 空行和 LF/CRLF 提示。
- 已按反馈优化知识库提示词缓存结构：移除知识库主流程所有 `system` prompt，改为多条 `user` 消息；全文 block 单独作为第一条 user message，任务要求和变量条目放后续 user message。已显式兼容第二轮补充条目返回 `{"items":[]}`，会继续合并首轮条目并进入待匹配。`node --check`、prompt smoke test、`npm run build` 通过。
- 已为知识库流程增加开发者模式详细 JSONL 日志：写入 `userData/logs/knowledge-base/<documentId>.jsonl`，记录文档状态更新、复制/转换、block 筛选统计、每次 AI 调用开始/结束、prompt 消息长度、条目/匹配/补漏数量、保存路径和异常堆栈；分析调试页会展示日志路径。`node --check`、prompt smoke test、`npm run build` 通过。
- 开始 Step03 目录生成弹窗 UI 改造：目标是移除页面原生成方式切换，点击生成目录后在弹窗内选择生成方式和多选参考知识库文档，本轮不改目录生成后台逻辑。
- 已完成 Step03 目录生成弹窗 UI 改造：`OutlineEditPage` 中生成按钮改为打开配置弹窗；弹窗内选择自由生成/按评分项对齐并显示解释；按文件夹列出知识库文档并支持多选完成状态文档；页面顶部移除原生成方式切换。`npm run build` 通过，仍只有既有 chunk 体积警告；`git diff --check` 只有既有 LF/CRLF 提示。
- 已按反馈重做 Step03 弹窗内“参考知识库”交互：改为紧凑搜索框 + 左侧折叠文件夹树 + 右侧已选文档清单；默认只展开第一个有可用文档的文件夹，搜索时自动展开命中结果；默认只展示已完成文档，支持文件夹全选/取消和已选文档移除/清空。`npm run build` 通过，仍只有既有 chunk 体积警告。
- 已完成 Step03 目录生成应用知识库：目录生成 payload 传入参考知识库文档 ID；Main 侧任务服务注入知识库服务；知识库只读返回 `document_id::item_id/title/resume`；目录生成按当前一级目录关键词筛选最多 15 条知识条目，只在二三级目录 prompt 中注入；目录节点只保留合法 `knowledge_item_ids`。已验证对齐模式非法 ID 过滤、自由模式一级目录不使用知识库/二三级使用知识库、CJS 语法检查、`npm run build` 和 `git diff --check`。
- 继续 Step03 知识库目录 Patch 增强：当前 `outlineGenerationTask.cjs` 仍存在旧的章节级知识条目筛选、二三级 prompt 注入和自由模式知识库强制 fallback，需要改为先生成完整目录再全局 Patch。
- 已完成 Step03 知识库目录 Patch 增强：主目录生成不再接收/注入知识库条目，选中文档只在完整目录审核通过后读取轻量条目并调用一次全局 Patch；Patch 只允许 bindings/additions，过滤非法目录/知识 ID，新增节点由程序编号，并全局去重 `knowledge_item_ids`。验证通过：CJS 语法检查、临时 smoke test、`npm run build`、`git diff --check`。
- 已修复 Step03 知识库 Patch 全部过滤问题：Patch prompt 改为真实 ID 示例 + 三类白名单（可绑定目录、可新增父级、可用知识 ID）；Patch 校验改为严格抛错并触发 `collectJsonResponse` 修复，覆盖占位 ID、短 ID、一级绑定、三级 parent、重复知识 ID 等；开发者模式任务日志新增白名单规模、校验失败原因、原始尝试摘要和校验通过统计。修复 smoke test、CJS 语法检查、`npm run build` 和 `git diff --check` 通过。
- 开始 Step03 知识库 additions-only 重构：已确认 `outlineGenerationTask.cjs` 仍保留旧 `bindings/additions + knowledge_item_ids` Patch、严格知识 ID 校验和应用层绑定落盘逻辑；下一步替换为只补缺失三级目录。
- 已完成 Step03 知识库 additions-only 重构：知识库增强 prompt 不再暴露知识库 ID，只输出 `additions[parent_id,title,description]`；normalizer 支持数组/items/directories 归一、删除多余字段、三级 parent 自动上提、description 用 title 补齐和 parent+title 去重；应用层只把新增三级目录追加到现有二级目录并用空知识 ID 集合归一，确保不落 `knowledge_item_ids`。验证通过：临时 smoke test、5 个 CJS `node --check`、`npm run build`、`git diff --check`；构建仍只有既有 chunk 体积警告，diff check 仍只有 LF/CRLF 提示。
- 已完成 Step04 正文编排阶段关联知识库：正文编排 JSON 新增 `knowledge.item_ids`；编排 prompt 在章节动态信息前加入固定知识库轻量清单，只含 `id/title/resume`；Main 侧读取 `reference_knowledge_document_ids` 并复用知识库轻量条目读取；前端启动正文生成时传入当前参考知识库文档 ID；本轮不改正文生成 prompt、不读取知识库正文。验证通过：`node --check electron/services/contentGenerationTask.cjs`、知识库编排归一化 smoke test、`npm run build`、`git diff --check`。`npm run build` 仍只有既有 chunk 体积警告，`git diff --check` 仍只有 LF/CRLF 提示。
- 已完成 Step04 正文生成阶段应用知识库：Main 侧按 `documentId::itemId` 建立知识库正文素材 Map；正文生成时按当前小节 `contentPlan.knowledge.item_ids` 解析对应 `content`，并在正文 prompt 中只注入 content，不传 ID、标题或简介；知识库素材消息放在项目概述之后、章节上下文之前以提升缓存命中可能。验证通过：`node --check electron/services/contentGenerationTask.cjs`、正文 prompt content-only smoke test、`npm run build`、`git diff --check`；构建仍只有既有 chunk 体积警告，diff check 仍只有 LF/CRLF 提示。
- 开始知识库查看链路性能埋点：目标是在开发者模式下记录 `openDocument()` 点击、IPC 读取、返回数据规模、状态更新、条目列表渲染、DOM 提交、Long Task 和下一帧可见，以区分慢点来自读取链路、列表渲染还是单条原文渲染。
- 已完成知识库查看链路性能埋点：新增 `document-items` trace，并让 `document-markdown` trace 从点击开始贯穿 IPC 读取和渲染可见；条目集合会统计总 content 字符数、最大条目、HTML/表格/图片/URL 分布，条目列表也接入 Profiler、DOM 指标、Long Task 和下一帧可见。第一次构建发现 `metrics.chars` 类型推断问题，显式声明为 `Record<string, number>` 后 `cd client; npm run build` 通过，仍只有既有 chunk 体积警告。
- 已将知识库“查看原文”改为弹窗：条目列表不再被原文视图替换，关闭弹窗后保留原滚动位置；弹窗复用现有原文 Markdown 渲染、开发者模式 item-source trace 和一帧延迟渲染逻辑，并新增专用遮罩/卡片/内部滚动样式。验证通过：`cd client; npm run build`，仍只有既有 chunk 体积警告。
- 开始并完成标书查重元数据模块首版：新增 Main 侧 `duplicateCheckService` 和 `duplicate-check:start-metadata-analysis` IPC/preload；Step02 自动启动元数据分析；正文提取与元数据提取并发，内部按文件线性处理；正文提取使用 `preserveImages: true` 并按文件保存 Markdown；元数据页展示两条进度、横向滚动对比表和重复项标红。验证通过：CJS `node --check`、模块加载和 `cd client; npm run build`，构建仍只有既有 chunk 体积警告。
- 已优化标书查重元数据模块：Step02 右上角新增“重新查重”，通过 `force: true` 强制重跑当前文件批次；时间类元数据改为同一天即橙色高亮，不再要求完全一致。验证通过：`node --check electron\services\duplicateCheckService.cjs`、`node --check electron\preload.cjs`、`cd client; npm run build`。
- 已完成标书查重 WPS/DOC/PDF 元数据增强：新增 `cfb` 依赖；`doc2markdown/convert.mjs` 导出 `withLegacyWordDocxFile()`；`.doc/.wps` 读取 OLE `SummaryInformation`、`DocumentSummaryInformation`、自定义属性和 WPS/Kingsoft 痕迹，并尝试转 `.docx` 补充 `docProps`；PDF 展开全部 Info/XMP、fingerprints、permissions 和原始 `/Author` 等记录；动态前缀字段参与横向比较。验证通过：`node --check electron\services\duplicateCheckService.cjs`、转换模块动态 import、查重服务模块加载、`npm run build`、`git diff --check`；`npm audit` 仍报既有 `mermaid` moderate 漏洞，未自动修复。
- 开始标书查重目录分析首版：已确认用户要求纯程序提取目录并比对；招标文件只做句子白名单，投标文件目录项若直接来自招标文件则不计重复；下一步扩展 Main 状态和前端目录 Tab。
- 已完成标书查重目录分析首版：Main 侧基于已提取 Markdown 生成招标句子白名单，按显式目录页/Markdown 标题/语义标题提取投标文件多级目录，命中招标文件句子的目录项不计重复；新增强重复/疑似相似组和文件两两相似度。前端目录 Tab 展示概览、相似度矩阵、文件目录树、重复组和“来自招标文件”灰色标签。验证通过：`node --check electron\services\duplicateCheckService.cjs`、`node --check electron\preload.cjs`、`node --check electron\ipc\duplicateCheckIpc.cjs`、查重服务模块加载、`npm run build`；`git diff --check` 仅本轮文件 LF/CRLF 提示，另有既有 `client/doc/标书查重.md:54 trailing whitespace` 未处理。
- 开始标书查重正文和图片比对：目标是正文按句子用程序聚合重复，招标文件句子作为排除白名单；图片按 hash 找完全相同图片；两个分析在正文 Markdown 提取完成后并发运行，前端用文件编号条和分页列表展示。
- 已完成标书查重正文和图片比对：新增 `contentAnalysis` 和 `imageAnalysis` 工作区状态；正文提取完成后并发运行目录、正文和图片分析。正文比对移除图片后拆句，用招标句子 Set 排除引用内容，再按规范化句子 Map 聚合跨投标文件重复；图片比对解析 Markdown/HTML 图片，读取 `yibiao-asset`/data/file 图片字节并按 SHA256 聚合。前端正文/图片 Tab 已实现投标文件 A/B/C 编号条、重复句子分页和重复图片分页缩略图。验证通过：`node --check electron\services\duplicateCheckService.cjs`、`node --check electron\preload.cjs`、`node --check electron\ipc\duplicateCheckIpc.cjs`、查重服务模块加载、`npm run build`；全量 `git diff --check` 仍有既有 `client/doc/标书查重.md:54 trailing whitespace`，本轮相关文件仅 LF/CRLF 提示。
- 已修复标书查重正文分句的表格拼接问题：正文比对前先提取结构化文本块，HTML 表格按单元格解析，Markdown 管道表按行列解析；移除 `isLikelyMergedTableSentence()` 特例过滤；正文清洗不再删除编号前缀，保留原始标点。真实缓存验证 `无偏离 + 编号 + 下一单元格正文` 异常句为 0，模拟重复分析中表格拼接异常为 0。验证通过：`node --check electron\services\duplicateCheckService.cjs`、`node --check electron\preload.cjs`、`node --check electron\ipc\duplicateCheckIpc.cjs`、查重服务模块加载、真实缓存/Markdown 表格 smoke test、`npm run build`、`git diff --check -- client/electron/services/duplicateCheckService.cjs`。
- 已修复标书查重正文比对忽略句首序号：`normalizeContentSentence()` 现在仅剥离句首结构性序号，展示句仍保留原文；招标引用排除和投标文件重复聚合都会把 `3.特别要求：...` 与 `特别要求：...` 视为同句。真实缓存验证目标句命中招标白名单 5 次且不再进入重复句；`GB/T 29768-2013`、`交货期：30天`、`质保期：3年`、`第2包` 均不被误删。验证通过：CJS 语法检查、preload/IPC 检查、查重服务模块加载、`npm run build`、`git diff --check -- client/electron/services/duplicateCheckService.cjs`。
- 已完成标书查重正文序号归一化二次修复：正文分句改为先生成 `normalized`，再用 `normalized` 判断是否有信息量，避免短标题因句首序号变长而进入重复池；句首结构序号补齐 Markdown 转义 `1\.`、全角数字、括号/圈号后额外分隔符和章节号。真实缓存模拟验证：截图短标题重复项为 0，normalized 句首序号残留为 0，“特别要求”招标引用仍未进入重复结果。验证通过：`node --check electron\services\duplicateCheckService.cjs`、`node --check electron\preload.cjs`、`node --check electron\ipc\duplicateCheckIpc.cjs`、私有函数用例、真实缓存模拟、`git diff --check -- client/electron/services/duplicateCheckService.cjs`、`npm run build`；构建仍只有既有 chunk 体积警告。
- 开始 AI 模型使用埋点与 Analytics 展示改造：用户要求文本/生图模型都统计服务商、Base URL、模型和 prompt/completion/total tokens；所有埋点异步吞错，不能影响主流程；模型使用不再按模型名 lower 聚合，按 total_tokens 降序展示真实状态。
- 已完成代码改造待验证：客户端 `aiService.cjs` 改为在响应/失败后异步吞错上报 provider/base_url/model/token usage；流式请求尝试 `stream_options.include_usage` 并对不支持场景重试；Worker `/track` 写入 ai_request 新字段和 token doubles；`/api/config-usage` 模型使用按 provider/base_url/model 查询并按 total_tokens 降序；Dashboard 模型使用表格展示新增列；README 已更新采集口径。
- 验证完成：`node --check client/electron/services/aiService.cjs`、`cd client; npm run build`、`node --check analytics/worker/src/routes/track.js`、`node --check analytics/worker/src/routes/configUsage.js`、`node --check analytics/worker/src/constants.js`、`node --check analytics/worker/src/index.js`、`node --check analytics/dashboard/public/src/pages/configUsage.js`、`node --check analytics/dashboard/public/src/main.js` 均通过；客户端构建仍只有既有 chunk 体积警告。
- 按用户反馈调整 Base URL 策略：不兼容旧客户端模型统计；文本模型只有自定义服务商允许编辑 Base URL，非自定义服务商和全部生图服务商强制使用预置 Base URL；Main 侧移除 `trimBaseUrl()` 的 OpenAI 默认兜底，Base URL 为空时明确报错。验证通过：`node --check electron/services/aiService.cjs`、`node --check electron/services/configStore.cjs`、`cd client; npm run build`。
- 开始新增生图自定义 OpenAI-like 模式：已确认当前金龙/火山共用 OpenAI compatible `/images/generations` 路径，自定义 provider 需要扩展类型、配置归一化、设置页 Base URL 可编辑和 Main 侧 provider 分支。
- 已完成生图自定义 OpenAI-like 模式：新增 `custom` 生图 provider，设置页支持自定义 Base URL/API Key/模型名称并可尝试 `/models` 获取列表；预置服务商 Base URL 仍锁定；Main 侧测试和正文配图把 `custom` 纳入 OpenAI compatible `/images/generations` 分支，并支持 `response_format` 不兼容时重试、测试预览显示 URL 或 base64 图片。验证通过：`node --check electron/services/aiService.cjs`、`node --check electron/services/configStore.cjs`、`cd client; npm run build`。
- 已给生图模型测试增加 5 分钟超时：OpenAI-like（金龙/火山/自定义）测试和 Google AI Studio 测试均复用 `AI_REQUEST_TIMEOUT_MS = 300000`，超时时提示“生图模型测试超时，请检查 Base URL、API Key 或模型名称”；OpenAI-like 的 `response_format` 不兼容重试也在同一个超时窗口内。验证通过：`node --check electron/services/aiService.cjs`、`cd client; npm run build`。
- 已修复 Analytics GitHub 仓库统计接口：`/api/github-repo-stats` 不再吞掉错误返回 `code:0, repo:null`；新增可选 `GITHUB_API_TOKEN`、GitHub HTML fallback、KV 手动 TTL 缓存和 stale cache 兜底；更新 `WORKER_CODE_VERSION=github-stats-resilient-v1` 与 README。验证通过：`node --check` Worker 相关文件、真实 handler 调用返回 `github-api` 数据、模拟 GitHub API 403 时 HTML fallback 返回数据、模拟全失败时 stale cache 返回数据、`git diff --check` 本轮 Analytics 文件。
- 按 review 继续修复：`parseRepoStatsFromHtml()` 现在要求 stars/forks/open issues 全部解析成功才返回，避免部分 counter 缺失时缓存 0；Dashboard `imageProviders` 增加 `custom: 自定义生图服务`。验证通过：GitHub stats route 与 Dashboard configUsage 语法检查、完整 HTML fallback、部分 HTML 缺失返回 502 且不缓存、部分 HTML 缺失时返回 stale cache、`git diff --check`。
- 按 review 修复模型使用表 provider 标签：新增 `textModelProviders` 标签表，`renderModelUsageGroups()` 根据分组 key 选择文本或生图标签，避免文本 `custom` 显示成“自定义生图服务”，并补中文展示小米/DeepSeek/龙猫。验证通过：`node --check analytics/dashboard/public/src/pages/configUsage.js`、`git diff --check -- analytics/dashboard/public/src/pages/configUsage.js`。
## Rejection Check Step03 Session
- 开始实现废标项检查 Step03：已确认现有页面、类型、Prompt 和 AI 调用边界；本轮会新增结果状态、三轮纯 user prompt、AI 检查服务、可展开/删除结果列表和样式，并运行客户端构建验证。
- 已完成代码接入：新增 Step03 风险项类型和工作区字段；三轮 AI 检查使用纯 user messages 与 `aiClient.chat()`；页面支持开始/重新检查、运行态、持久化、单项展开、自动折叠和删除；样式已覆盖桌面和移动端。
- 验证完成：`cd client && npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 Git LF/CRLF 提示。
- 按评审修复 Step03 健壮性：废标项 Step02 流式解析不再因 10 秒无 chunk 自动标成功；缓存中的 `running + content` 恢复为 error 并要求重新解析；Step03 检查要求 Step02 状态为 success；第三轮最终 JSON 改为 `aiClient.requestJson()`，复用 Main 侧 JSON 提取、修复和重试链路。
- 评审修复验证完成：`cd client && npm run build` 通过，仅有既有 chunk 体积警告；`git diff --check` 通过，仅有 Git LF/CRLF 提示。
- 已修复 Step04 继续生成重复配图问题：最终配图目标改为本次任务实际生成/补目录生成/扩写过的成功叶子，历史成功但本次未触达的小节不重新配图；`minimumWords=0` 通过正常字数判断自然跳过补目录/扩写；扩写 prompt 会移除旧图片/Mermaid 上下文；已有图片或 Mermaid 的目标小节会跳过配图。验证通过 CJS 语法检查、继续生成不重复配图 smoke test、首次全文配图 smoke test、扩写顺序 smoke test、`npm run build` 和 `git diff --check`（仅 LF/CRLF 警告）。
- 已修复 Step04 补字数无限循环风险：扩写批次现在会返回是否完成一整轮候选覆盖，`ensureMinimumWords()` 在每轮开始记录总字数，完整一轮后如果总字数没有增长就写日志并抛错结束任务，不设置固定次数上限。验证通过 CJS 语法检查、无增长保护 smoke test、扩写顺序 smoke test、`npm run build` 和 `git diff --check`（仅 LF/CRLF 警告）。
- 已修复 Step04 扩写非法 operation 被吞成 insert 的问题：`normalizeContentExpansionPatch()` 现在保留原始 operation，`validateContentExpansionPatch()` 会拒绝非 `insert/replace` 并触发 JSON 修复链路；新增正文扩写专用修复 prompt，明确禁止 `delete/rewrite_full/rewrite/append/update`。验证通过 CJS 语法检查、非法 operation smoke test、`npm run build` 和 `git diff --check`（仅 LF/CRLF 警告）。
- 已完成标书查重与废标项检查 SQLite v2 改造：`sqliteDatabase.cjs` 升到 schemaVersion 2，新增 `duplicateCheckStore` / `rejectionCheckStore`、功能专用 IPC/preload/types；删除旧 `workspaceStore.cjs` / `workspaceIpc.cjs`；两个页面改用 `window.yibiao.duplicateCheck` / `window.yibiao.rejectionCheck`，废标项检查任务不再从 Renderer payload 接收招标/投标大文本。补充修复了标书查重目录项跨文件同 ID 写入冲突，并按 `file_id` 恢复目录分组归属。验证通过 CJS 语法检查、Electron SQLite v2 Store 冒烟、目录项同 ID 回归 smoke、`npm run build`；`npm audit` 仍为既有 3 个漏洞。
- 按方案复查后完成补漏：标书查重重新选择文件时会删除旧 Markdown 和 `duplicate-check-content-*` 图片资产，清空时删除整个 `workspace/duplicate-check/` 后重建目录；标书查重正文提取后会把 Markdown SHA256 写入 `duplicate_check_files.content_hash`；废标项任务移除 `payload.tenderContent` / `payload.bidContent` / `payload.invalidBidAndRejectionItems` fallback；删除未引用的 Renderer 侧 `rejectionCheckService.ts`；移除不再使用且会向 Renderer 返回废标项 Markdown 大文本的 `file.importRejectionCheckDocument` bridge。
- 已完成技术方案 SQLite 复查补漏：`tasks:event` 对技术方案改为 `technicalPlanPatch` + 必要的 `contentSection/outlineData/contentRuntime`，不再广播完整 `technicalPlan`；`TechnicalPlanHome` 改为按 patch 合并任务事件；删除未引用的 `analysisWorkflow.ts`，并移除 `bidAnalysisWorkflow.ts` 中 Renderer 直连 AI 的 `fileContent` 请求函数，开发者测试页改为直接使用通用 `aiClient.chat()` 样例。验证通过 `node --check electron\services\taskService.cjs electron\services\contentGenerationTask.cjs electron\preload.cjs`、`npm run build`；`git diff --check` 仍只有 LF/CRLF 提示。
- 已按要求保留开发者测试页并清理其他废弃代码：移除 Renderer 暴露的旧 `file.importDocument` / `file:import-document` / 类型声明，保留 Main 内部 `fileService.importDocument()` 供技术方案 Store 使用；删除 `technicalPlanStore.saveTechnicalPlan()` 旧整包保存方法；删除未引用的旧 localStorage 草稿/工作区存储、旧文档分析 prompt builder 和相关类型/工具。验证通过相关 CJS `node --check`、`tsc --noEmit`、`npm run build`、`git diff --check`（仅 LF/CRLF 提示）。
- 已修复代码评审指出的恢复/持久化问题：`rejectionCheckStore.saveUiState()` 只保存调用方实际传入的 UI 字段，避免 `undefined` 被归一化为默认 step/tab；`recoverInterruptedDuplicateCheckTask()` 恢复 stale running 后会向订阅页面 emit 最新 `duplicateCheck` 快照，避免页面本地仍停留 running。验证通过 `node --check electron\services\rejectionCheckStore.cjs electron\services\taskService.cjs` 和 `npm run build`。
- 开始知识库 SQLite v3 文档设计：本轮只更新文档、SQL 说明和开发说明；已确认用户要求知识库历史数据不能丢，升级后进入知识库时检测旧 `index.json` 并弹窗确认迁移，迁移成功并校验后删除旧索引/结果 JSON，下次不再触发弹窗。
- 已完成知识库 SQLite v3 文档设计更新：新增 `client/doc/sqlite改造方案_知识库.md`；`sql/workspace_schema.sql` 目标版本升为 v3 并补充 `knowledge_*` 表；`client/开发说明.md` 补充知识库迁移 API、Store 边界、数据保留和弹窗文案；既有 SQLite 文档和 `知识库设计.md` 已加新方案引用。验证通过文档级 `git diff --check`（仅 LF/CRLF 提示）和 Markdown 行尾空白搜索。
- 已完成知识库 SQLite v3 运行代码接入：`sqliteDatabase.cjs` 升到 schemaVersion 3 并新增 `knowledge_*` runtime migration；新增 `knowledgeBaseStore.cjs` 接管文件夹、文档、block、候选条目、最终条目、舍弃记录、报告和旧 JSON 迁移；`knowledgeBaseService.cjs` 改为委托 Store 持久化；IPC/preload/type/页面接入 `getMigrationStatus()` / `migrateLegacy()`，进入知识库检测旧 `index.json` 后提示用户确认迁移。修复了 Electron 冒烟发现的 `markdown_hash` 变量名运行时错误，并补强迁移错误状态和文件夹校验。验证通过 CJS `node --check`、Electron 运行时知识库 v3 迁移 smoke、`npm run build` 和 `git diff --check`（仅 LF/CRLF 提示）。
- 已按知识库 SQLite v3 方案复查补齐三项缺口：迁移事务内新增关键结果数校验（block、筛除 block、候选条目、最终条目、来源关系、舍弃记录、报告），校验失败会回滚且不清理旧 JSON；`knowledgeBaseService.list()` / `getMigrationStatus()` 会把无 active 任务的旧处理中状态恢复为 error；`KnowledgeBasePage` 在迁移中禁用上传、新建、重命名、删除、查看和匹配入口。验证通过新增 Electron 回归 smoke、原迁移 smoke、相关 CJS `node --check`、`npm run build` 和 `git diff --check`。
- 已完成 SQLite 改造后的明确废弃代码清理收尾：删除无引用的 Renderer 旧服务/占位 Prompt/未实现 JSON 修复占位后，继续删除 `client/src/shared/utils/errors.ts` 中仅自引用的 `ClientNotImplementedError` / `getErrorMessage()` 旧占位工具；残留搜索确认相关废弃文件、导出和占位文案无命中，剩余 `buildChapterContentMessages` / `repairJsonResponse` 命中均为 Electron Main 真实实现。验证通过 `cd client; npm run build` 和 `git diff --check`，仅有既有 chunk 体积警告与 LF/CRLF 提示。
- 已确认评审指出的知识库迁移 stale running 首屏问题成立，并按用户确认改为只迁移旧版 `status = success` 文档：`migrateLegacy()` 迁移前统计已完成/跳过数量，非完成或未知状态文档不写入 SQLite，返回跳过数量；Service 迁移后重新执行恢复和 `list()`，避免返回过期运行态；页面确认框明确提示未完成或处理中的文档会被丢弃。验证通过 CJS 语法检查、既有知识库迁移 smoke、回归 smoke、新增 skip smoke、`npm run build`。
- 已将知识库迁移确认从系统 `window.confirm` 替换为项目内 Radix Dialog：页面检测到旧索引后打开统一风格弹窗，排版为标题、旧版不再支持继续处理提示、迁移规则警告和三列统计；文案明确建议未完成文档需回退旧版本解析为“已完成”后再更新。补充移动端单列样式，更新开发说明和知识库迁移方案。验证通过 CJS 语法检查和 `npm run build`，构建仅有既有 chunk 体积警告。
- 已按用户要求精简 `client/开发说明.md`：保留技术栈、架构边界、目录职责、Main/IPC/Store、数据存储、后台任务、UI 复用、AI/Prompt、埋点、发布和验证标准；删除 preload API 全量清单、过细功能流水账和重复实现说明。验证通过 `git diff --check -- client/开发说明.md`，仅有 LF/CRLF 提示。
- 已完成 SQLite 重构后埋点排查并按用户取舍优化：不为一次性知识库迁移弹窗/迁移动作新增埋点；确认 Main 侧 `ai_request` 链路仍由 `aiService.chat()` / `generateImage()` 统一上报；修复技术方案页子步骤 `page_view` 在 SQLite 状态异步恢复前误报默认 `technical-plan/document-analysis` 的问题。验证通过 `cd client; npm run build` 和 `git diff --check`，仅有既有 chunk 体积警告与 LF/CRLF 提示。
- 开始全文配图标题统一编排：用户确认由图片编排 Agent 为每张图生成最终标题，三类生成阶段直接使用并注入该标题；计划升级为 v3，程序校验最终标题唯一，不新增相似度算法、SQLite、IPC 或 UI 链路。
- 已完成全文配图标题统一编排：Agent 输出新增必填最终图注 `title`，v3 计划校验格式和标准化唯一性；HTML、Mermaid、AI 提示词统一注入标题，Mermaid 只生成 code，正文 alt/图注只使用计划标题；按用户要求删除全部旧图片计划兼容、自动重编排和标题回退。相关 CJS 语法、计划/三类生成/HTML Agent smoke、客户端构建和 diff 检查均通过。
- 开始新手用户使用手册任务：已读取仓库规则、`client/开发说明.md` 和 Windows 应用控制说明；下一步核对代码中的菜单与操作流程，再采集已安装软件真实截图。
- 已打开已安装的“易标投标工具箱”，沿现有结果完成真实界面核对和截图采集；未点击任何重新生成、测试、自检或外部请求按钮。截图已保存到 `使用说明/images/`，下一步编写并校验 Markdown 手册。
- 已新增 `使用说明/用户使用手册.md`，按“配置”和“使用”两大部分编写，包含 15 张真实截图及截图下方操作标注；内容覆盖文本模型、生图模型、文件解析、智能体配置、技术方案五步、已有方案扩写、文档知识库、标书查重和废标项检查。
- 用户手册任务完成：15 个图片链接无缺失、15 个 JPEG 签名有效、无行尾空白或错误扩展名引用；已抽查关键截图清晰可读，并将软件恢复到原技术方案 Step05 后正常关闭。
- 开始用户手册二次调整：将重新采集 15 张无损 PNG，并把“配置/使用”拆为两个目录、各三级章节拆为独立 Markdown 文件，根目录新增 README 总索引。
- 已验证并开始使用原始物理像素 PNG 截图方案：完成首页、设置页签、文本模型和生图模型 4 张新截图，单张分辨率约 2902×1750。
- 已继续完成文件解析、智能体配置、Step05 正文结果和 Step04 全局事实 4 张无损 PNG；截图过程中只做页面导航，未触发测试、自检、生成或导出。
- 已完成技术方案 Step03、Step02、Step01 三张无损 PNG；技术方案五步截图现已全部替换为高分辨率版本。
- 已完成文档知识库、查重文件选择、查重结果和废标项结果 4 张无损 PNG；15 张手册截图已全部重新采集完成。
- 已完成手册拆分：新增根 `使用说明/README.md`，新增 `配置/` 4 个章节文件与 `使用/` 6 个章节文件，删除原单文件手册；初检 11 个 Markdown、15 个图片链接、37 个文档链接均无缺失。
- 已确认 15 张新 PNG 均为 2902×1750 且可正常读取，随后在限定的 `使用说明/images/` 内删除 15 张旧 JPEG，仅保留新截图。
- 二次调整完成：11 个 Markdown 文件、15 个图片链接和 37 个文档链接全部有效，无行尾空白；15 张 PNG 全部为 2902×1750，旧单文件手册和旧 JPEG 已移除；软件恢复 Step05 后正常关闭。
- 开始第三次调整：将删除根 README 与全部文档导航链接，并使用图像编辑能力为截图添加编号、箭头和简短中文重点提示。
- 已删除 `使用说明/README.md` 和 10 个章节文件中的返回/上一篇/下一篇链接；已完成代表性截图的标注样式试制，确定使用红橙色编号标签、白字、箭头和目标高亮框。
- 已完成 14 张实际使用截图的高清标注版，并将全部 Markdown 图片链接切换到 `images/标注/`；对目录编辑页箭头落点进行了单独微调。
- 第三次调整验证完成：根目录无文件，10 个章节无总目录或前后篇导航，14 个图片引用全部有效；标注图均为 2902×1750，抽样对照未出现新增透明区域，代表性页面目视清晰。
- 开始实现个人 Skill `yibiao-user-manual`：已读取 `skill-creator` 与 `planning-with-files` 规范，恢复现有规划记录，并锁定发行版路径询问、无数据阻塞和限定范围更新三项交互规则。
- 首次初始化因 `short_description` 仅 23 字符被官方脚本拒绝；当前仅产生未完成 `SKILL.md` 模板，将清理后使用合规描述重新初始化。
- 已清理首次初始化产生的单一模板并重新运行官方初始化脚本；`SKILL.md`、`agents/openai.yaml`、`scripts/` 和 `references/` 骨架创建成功。
- 检查骨架发现 `agents/openai.yaml` 的中文参数因 Windows 编码写入乱码；已记录，后续与 Skill 正文一起用 UTF-8 修正。
- 已新增三个可复用 PowerShell 脚本：发行版窗口物理像素截图、JSON 坐标驱动的确定性重点标注、支持限定范围与完整只读检查的手册验证。
- 首次批量写入 Skill 说明时，损坏的 `agents/openai.yaml` 非法 UTF-8 字节使补丁整体未生效；已改为先清理该单一文件，再分批创建 UTF-8 内容。
- 已完成 `SKILL.md`、UTF-8 `agents/openai.yaml`、项目约定和标注格式说明；三项用户新增规则已写入主流程，当前进入脚本运行验证阶段。
- 已通过 Windows 应用控制能力启动并检查现有发行版，确认应用 ID 和窗口标题可用；尚未点击任何业务功能，下一步最大化后执行临时截图测试。
- 首次联合验证因检查命令使用 PowerShell 保留变量 `$Error` 失败；Skill 文件未受影响，将改名变量并拆分重新验证。
- 三个脚本首次解析暴露 PowerShell 5.1 的 UTF-8 无 BOM 兼容问题；将把脚本源码调整为纯 ASCII 后重新执行语法和运行测试。
- 三个脚本已完成 ASCII 兼容调整，非 ASCII 扫描为 0，PowerShell 5.1 语法解析全部通过。
- 首次官方 Skill 校验受 Python GBK 默认编码影响，未能读取 UTF-8 中文正文；将以 `PYTHONUTF8=1` 重新执行。
- 官方 Skill 结构校验已通过；手册校验脚本的结果汇总在 PowerShell 5.1 泛型列表展开处失败，已定位到第 189 行并准备显式数组转换。
- 当前手册完整校验已通过：配置 4 篇、使用 6 篇、14 个标注截图引用、0 个问题；首次窗口截图测试命令因测试输出管道语法错误未执行，将修正测试命令后继续。
- 窗口截图脚本实际运行发现单个候选进程被自动展开为标量，已定位为 `.Count` 兼容问题，将强制数组包装后重测。
- 窗口截图脚本已成功生成 2560×1368 PNG；标注测试命令重复出现测试输出管道语法错误，脚本尚未执行，将使用统一的结果变量写法继续。
- 临时截图和标注图已生成并目视检查，但截图内容被前台 Codex 窗口遮挡，标注图又出现大块透明黑区；两项均判定未通过，将更换目标窗口捕获方式并修复全像素合成。
- 截图脚本已改用 `PrintWindow` 并成功捕获 2560×1368 真实易标界面；标注脚本保持相同尺寸、无新增透明样本，Pillow 与高质量预览均确认图像完整。脚本实现阶段完成。
- 关闭测试发行版时应用控制因检测到用户输入暂停；刷新后句柄截图与应用标识不一致，已停止继续发送 UI 输入，后续仅在确认进程身份后做安全收尾。
- 限定范围隔离验证通过：范围内阻塞问题 0、范围外问题 1，完整检查正确以退出码 1 失败；缺失窗口场景也正确阻塞。元数据断言仍有一项失败，正在核对实际字段。
- 元数据断言已改用 ASCII Unicode 转义并通过；三个独立前向测试全部通过，覆盖限定范围、发行版路径未知和业务页面无数据三种关键行为。
- `yibiao-user-manual` 实现完成：官方 Skill 校验、UTF-8、3 个脚本语法、当前手册 10 篇/14 图、限定范围、缺失路径、无数据和真实窗口截图/标注测试全部通过；临时文件已清理，测试发行版已关闭。
