Files
X-Financial/document/work-log/2026-06-24.md
caoxiaozhu f9553a6a1a docs: 清理过期计划文档并补全 work-log 与开发/用户文档
- 删除已落地的 improvement-roadmap、superpowers 计划与 ui-mockups 参考稿,删除早期 work-log(2026-05-06~08)
- 新增 2026-05-23 起的 work-log 与 attachment-association-background-job、reimbursement-draft-action-branching 等开发文档及用户文档
- docker-compose(.full).yml 微调服务配置
2026-06-24 10:42:57 +08:00

139 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-06-24 工作日志
## 当日工作内容
- 09:41我开始为 X-Financial 补一个专门写修改日志的项目级 Skill目标是让后续每次 bugfix、新功能、重构或配置/文档修改之后,都能留下有时间、有操作、有判断的增量记录。
- 修改:新增 `agent-change-log` Skill约定触发场景、每日日志位置、三段式结构、TODO 勾选规则和拟人化记录方式。
- 修改:新增 Skill 展示元数据,方便后续通过 `$agent-change-log` 识别和调用。
- 修改:准备把 `AGENTS.md` 接上强触发规则,避免后续代理只记得“写代码”而忘了“写修改记录”。
- 操作:沿用既有 `document/work-log/YYYY-MM-DD.md` 日志目录,不另起一套新路径,避免历史记录分裂。
- 验证09:42 已补做结构检查,见下一条记录。
- 影响:后续修改会从“最终总结”升级为“过程可追踪”,当天工作内容、遗留问题和 TODO 会随着每轮修改持续增长。
- 09:42我按刚写好的 `agent-change-log` 规则做了第一次自检,并把验证结果回填到当天日志里。
- 操作:运行 `git diff --check` 检查本轮涉及文件的空白问题。
- 操作:用 `rg` 检查 Skill frontmatter、`AGENTS.md` 触发规则,以及日志中的 `当日工作内容``遗留问题``TODO` 三个固定标题。
- 验证:`git diff --check` 无输出,说明补丁没有空白错误;`rg` 能命中 `agent-change-log`、日志路径和三段式标题。
- 影响:这个日志 Skill 已经有了可执行的触发条件、固定记录位置和第一次样例记录,后续修改可以直接照这个格式增量追加。
- 09:43我继续检查了新 Skill 的版本管理可见性,确认它已经落在本机项目目录,但默认会被 `.gitignore` 忽略。
- 操作:运行 `git check-ignore -v` 检查 `.codex/skills/agent-change-log/SKILL.md``agents/openai.yaml` 的忽略来源。
- 验证:命中 `.gitignore:10:.codex/`,说明普通 `git status` 不会显示这个新 Skill`ls` 已确认两个文件真实存在。
- 影响:本机后续可以使用这个 Skill但如果要把它随仓库交付需要后续显式调整忽略规则或强制加入版本管理。
- 09:44我收紧了 `.gitignore` 规则,让新建的 `agent-change-log` Skill 能进入普通版本管理视野,同时继续保护 `.codex` 下其他本地状态。
- 修改:把 `.codex/` 改成 `.codex/*`,再只放行 `.codex/skills/agent-change-log/**`
- 操作:保留 `.codex` 其他内容默认忽略,避免把本地运行缓存、临时状态或其他未审查 Skill 一起暴露出来。
- 验证:`git status --short` 已能看到 `agent-change-log` 的两个新增文件;`git diff --check` 仍然无输出。
- 影响:后续提交这个 Skill 时不需要强制添加,普通 `git status` 就能看到相关文件。
- 10:01我按你的补充要求把“先拉取/检查 Git分析其他智能体提交”纳入 `agent-change-log` 的硬流程。
- Git 提交检查:已运行 `git fetch --all --prune``HEAD..origin/main` 未发现 upstream 新提交。当前本地 `main` 显示 ahead 1后续在 10:02 单独补充分析本地 ahead 提交。
- 修改:更新 `agent-change-log`,新增 `Required Git Check`,要求写日志前执行 `git fetch --all --prune``git status -sb`、上游分支识别和 `git log HEAD..@{u}`
- 修改:更新 Skill 展示提示,把 upstream commit check 也列入触发场景。
- 修改:更新 `AGENTS.md`,明确每次日志更新前先做 Git 拉取检查;工作区干净且只落后上游时可 `git pull --ff-only`,脏工作区或可能冲突时只 fetch 并记录风险。
- 操作:没有在当前脏工作区执行自动 merge/rebase避免把其他大量未提交改动和远端提交混在一起。
- 验证:`rg` 已命中 `Required Git Check``git fetch --all --prune``HEAD..@{u}``git pull --ff-only``git diff --check` 无输出。
- 影响:后续日志会同时记录“我改了什么”和“其他智能体已经提交了什么”,不会只盯着本地 diff。
- 10:02我把本地 ahead 提交也纳入日志 Skill因为当前仓库已经出现 `origin/main..HEAD` 的本地提交。
- Git 提交检查:`origin/main..HEAD` 发现 `9321260 chore(skills): add git checkpoint commit loop`,提交时间为 2026-06-24 09:47:05内容包括新增 `git-checkpoint-commit` Skill、展示元数据、`checkpoint_commit.py` 脚本,并调整 `.gitignore`
- 修改:更新 `agent-change-log`,要求同时检查 `HEAD..@{u}``@{u}..HEAD`,分别识别 upstream 新提交和本地 ahead 新提交。
- 修改:更新 `AGENTS.md`,把本地 ahead 提交也纳入“其他智能体提交摘要”的记录范围。
- 操作:用 `git show --stat``git show --name-only` 查看 `9321260` 的文件清单与提交信息,没有改写该提交。
- 验证:`rg` 已命中 `@{u}..HEAD``本地 ahead``9321260``git diff --check` 无输出。
- 影响:后续即使其他智能体只做了本地 commit、还没 push也会被日志 Skill 捕捉并分析。
- 10:21自动记录 `9321260` 提交后的工作日志。auto-log:9321260
- Git 提交检查fetch 失败error: cannot open '.git/FETCH_HEAD': Operation not permittedupstream `origin/main`upstream 新提交:未发现;本地 ahead 提交9321260 (HEAD -> main) chore(skills): add git checkpoint commit loop。
- 修改:最近提交为 `9321260 chore(skills): add git checkpoint commit loop`
- 操作manual 验证自动日志脚本 触发 `tools/agent-change-log/update_change_log.py`,自动读取 Git 状态并写入当天日志。
- 验证:自动脚本只记录提交和 Git 状态,不替代业务测试;业务验证仍以本次任务实际运行结果为准。
- 影响:提交后即使执行代理忘记手动写日志,也会留下最低限度的时间、提交和分支状态记录。
- 10:21我排查了“修改 bug 或新增功能后不会自动写日志”的根因,并补上可执行自动化入口。
- Git 提交检查:当前权限下 `git fetch --all --prune` 会失败,错误是 `.git/FETCH_HEAD` 不允许写入;`origin/main..HEAD` 仍显示本地 ahead 提交 `9321260`
- 修改:新增 `tools/agent-change-log/update_change_log.py`,用于自动生成并追加当天工作日志,包含 Git 双向提交检查、最近提交摘要、重复提交去重和 fetch 失败遗留问题记录。
- 修改:新增 `.githooks/post-commit`,提交后调用日志脚本,作为真正的自动触发点。
- 修改:新增 `tools/agent-change-log/install_post_commit_hook.sh``README.md`,说明如何把版本化 hook 安装到本地 `.git/hooks/post-commit`
- 修改:更新 `AGENTS.md`,明确 Skill/AGENTS 只是规则,自动触发必须安装 post-commit hook如果当前环境无法写 `.git`,必须如实记录限制。
- 操作:尝试执行 `tools/agent-change-log/install_post_commit_hook.sh`,当前沙箱返回 `mkdir: .git/hooks: Operation not permitted`,所以本轮不能实际安装本地 hook。
- 验证:`update_change_log.py --dry-run --no-fetch` 能输出日志条目;默认 dry-run 能捕获 fetch 权限错误并输出遗留问题;真实运行脚本已成功追加 10:21 的 `auto-log:9321260` 记录。
- 影响:现在仓库里已经有可执行自动日志链路;等环境允许写 `.git` 后,安装 hook 即可实现“提交后自动写日志”。未提交的普通文件变更仍无法由 Git 自动判断,需要代理在任务结束前主动调用日志 Skill。
- 10:24我修正了 PDF 票据 OCR 的转图链路,避免“预览图丢中文但仍继续 OCR”的假成功。
- Git 提交检查:`git fetch --all --prune` 失败,错误是 `.git/FETCH_HEAD: Operation not permitted``git status -sb` 显示当前 `main...origin/main [ahead 1]``HEAD..@{u}` 未输出 upstream 新提交;`@{u}..HEAD` 显示本地 ahead 提交 `9321260 chore(skills): add git checkpoint commit loop`
- 修改:`document_preview.py` 把 PDF 渲染器标识升级为 `pdf-raster-cjk-safe-v3`,新增 `render_pdf_pages()`,按 `pdftoppm -> mutool -> gs -> pdftocairo` 尝试生成 PNG遇到 `Missing language pack``Unknown font tag``No font in show` 这类会丢中文的输出时,不再接受该 PNG。
- 修改:`ocr.py` 删除“PDF 文本层可用就直接构建识别结果”的分支PDF 现在必须先转图片,再进入 Paddle OCR worker文本层仅作为后续纠错/兜底材料,不再绕过图片 OCR。
- 修改:`docker-compose.yml``docker-compose.full.yml``bootstrap_paddleocr_mobile.sh``bootstrap_paddleocr_gpu.sh` 增加 `mupdf-tools`,让容器里有 `mutool` 作为中文安全转图 fallback。
- 修改:`test_ocr_service.py` 增加回归测试,覆盖运行时依赖包含 `mupdf-tools`、Poppler 字体映射失败时尝试下一个渲染器、坏转图不再调用 OCR worker、以及 PDF 文本层可用时仍必须调用 OCR worker。
- 操作:执行 `python3 -m py_compile``git diff --check``rg` 残留检查;尝试按项目规范执行容器内定向 pytest。
- 验证:`py_compile``git diff --check`、残留搜索均通过;容器 pytest 未能执行,原因是当前 Codex 进程访问 Docker socket 被拒绝:`permission denied while trying to connect to the docker API at unix:///Users/caoxiaozhu/.docker/run/docker.sock`
- 影响:后续 PDF 票据如果第一轮转图丢中文,会自动切换渲染器;如果所有渲染器都不可用,会明确失败并提示转图问题,而不是把缺中文的坏图送进 OCR。
- 10:28我确认 10:06 上传的票据夹记录当前仍是 PDF 预览,并修正 OCR 文本层纠错会清空 PNG 预览的问题。
- Git 提交检查:`git fetch --all --prune` 失败,错误是 `.git/FETCH_HEAD: Operation not permitted`;当前 `main...origin/main [ahead 1]``HEAD..@{u}` 未输出 upstream 新提交;`@{u}..HEAD` 仍显示本地 ahead 提交 `9321260 chore(skills): add git checkpoint commit loop`
- 发现:`server/storage/receipt_folder/caoxiaozhu_xf.com/f0dd9b4a-f7b7-4784-ade7-4e31b71f0b12/meta.json``preview_kind=pdf``preview_media_type=application/pdf`,前端 `ReceiptFolderView.vue` 因此走 `<iframe>` 而不是 `<img>`
- 根因:`OcrService._finalize_document()` 里旧逻辑在 PDF 文本层参与纠错且 OCR 文本占位符比例较高时,会主动把 `preview_kind``preview_data_url` 清空;票据夹保存时拿不到 `data:image/png`,只能回退到原 PDF 预览。
- 修改:删除这段清空 PNG 预览的旧保护逻辑;转图阶段已经负责识别坏 PNG文本层纠错不再影响预览资产类型。
- 操作:执行 `python3 -m py_compile server/src/app/services/ocr.py server/tests/test_ocr_service.py``git diff --check``rg` 残留检查。
- 验证:语法检查、空白检查和残留搜索均通过;容器 pytest 仍因 Docker socket 权限无法执行。
- 影响:后续 PDF OCR 结果即使使用文本层修正字段,也会保留 OCR 转图得到的 PNG 预览,票据夹应写入 `preview_kind=image``preview_media_type=image/png`
- 10:32我继续排查“重新上传仍是 PDF 识别”的原因,确认最新 10:29 上传命中了旧 OCR 结果,并修正 OCR 内存缓存失效条件。
- Git 提交检查:`git fetch --all --prune` 失败,错误是 `.git/FETCH_HEAD: Operation not permitted`;当前 `main...origin/main [ahead 1]``HEAD..@{u}` 未输出 upstream 新提交;`@{u}..HEAD` 仍显示本地 ahead 提交 `9321260 chore(skills): add git checkpoint commit loop`
- 发现:最新两条票据夹记录 `e9e3c0be-...``9ecee0d8-...` 上传时间为 10:29但仍是 `preview_kind=pdf``ocr_line_count=0``ocr_text` 仍是只有英文和数字的旧坏结果。
- 根因:`OcrService._build_cache_key()` 只使用 OCR 语言、设备、模型和文件 digest没有包含 PDF 转图/识别管线版本;同一 PDF 重新上传时可能复用旧的内存缓存,导致新转图逻辑没有机会执行。
- 修改:新增 `OCR_RESULT_CACHE_PIPELINE_VERSION`,把当前 PDF 渲染器标识 `DocumentPreviewAssets.PDF_RENDERER_ID``no-pdf-direct` 策略写入 OCR cache key。
- 修改:`test_ocr_service.py` 增加 `test_ocr_cache_key_includes_pdf_render_pipeline_version`,防止以后改转图管线但继续吃旧缓存。
- 操作:执行 `python3 -m py_compile server/src/app/services/ocr.py server/tests/test_ocr_service.py``git diff --check``rg` 检查;尝试执行容器内定向 pytest。
- 验证:本地语法检查、空白检查和残留搜索通过;容器 pytest 仍因 Docker socket 权限被拒绝,未能执行。
- 影响:后端加载新代码后,同一 PDF 会因为 cache key 变化重新进入 PDF 转 PNG + Paddle OCR 流程,而不是复用旧的 PDF fallback/坏识别结果。
- 10:40我修正了 AI 工作台附件预览弹窗在左侧侧边栏存在时视觉不居中的问题。
- Git 提交检查:`git fetch --all --prune` 失败,错误是 `.git/FETCH_HEAD: Operation not permitted`;当前 `main...origin/main [ahead 1]`;基于本地 ref`HEAD..@{u}` 未输出 upstream 新提交;`@{u}..HEAD` 仍显示本地 ahead 提交 `9321260 chore(skills): add git checkpoint commit loop`
- 修改:`workbench-ai-file-preview-dialog.css` 将预览遮罩改成“侧边栏占位列 + 主内容列”的网格布局,弹窗固定落在第二列并居中;同时保留折叠侧栏变量和 900px 以下移动端单列布局。
- 修改:`workbench-ai-composer-components.test.mjs` 增加回归断言,锁定附件预览必须按主内容区域居中,而不是按整个 viewport 居中。
- 操作:检查本地 `5173` 可达,返回 `HTTP/1.1 200 OK`;检查项目没有现成 Playwright/Puppeteer 依赖,未新增依赖。
- 验证:`node --test web/tests/workbench-ai-composer-components.test.mjs` 通过 8/8`npm --prefix web run build` 构建通过;`git diff --check` 无输出。
- 影响:用户点击附件打开预览时,弹窗会避开左侧 AI 工作台侧边栏,在右侧主工作区内居中展示,截图里的“偏左/不居中”观感会收敛。
- 10:41我补修了票据夹 PDF 保存阶段的预览持久化,避免 OCR 后仍把源 PDF 当成附件预览展示。
- Git 提交检查:`git fetch --all --prune` 失败,错误是 `error: cannot open '.git/FETCH_HEAD': Operation not permitted`;当前 `main...origin/main [ahead 1]`;基于本地 ref`HEAD..@{u}` 未输出 upstream 新提交;`@{u}..HEAD` 显示本地 ahead 提交 `9321260 chore(skills): add git checkpoint commit loop`
- 修改:`receipt_folder.py``document.preview_data_url` 缺失且源文件是 `application/pdf` 时,保存阶段立即调用 `DocumentPreviewAssets.render_pdf_first_page()` 生成 `preview.png`,并把 `preview_kind``preview_media_type``preview_rendered_with` 写成图片预览元数据;只有渲染异常时才回退到源 PDF 预览。
- 修改:`test_receipt_folder_service.py` 新增 `test_receipt_folder_pdf_save_eagerly_renders_image_preview`,覆盖 PDF OCR 结果没有内嵌预览图时,票据夹仍应主动生成图片预览的场景。
- 操作:读取当前票据夹存储里的两条 PDF meta确认旧记录存在 `preview_kind=pdf``preview_media_type=application/pdf` 且没有 `preview.png`,这与前端显示 PDF 预览的问题一致。
- 验证:`python3 -m py_compile server/src/app/services/receipt_folder.py server/tests/test_receipt_folder_service.py` 通过;宿主机缺少 pytest 和后端依赖,容器 pytest 又因 Docker socket 权限被拒绝,暂未完成项目要求的容器定向测试。
- 影响:后续新上传或重新 OCR 保存的 PDF 票据会优先拥有 PNG 图片预览,前端票据夹预览应走 `<img>` 体验;既有已经写成 PDF fallback 的旧 meta 还需要单独刷新。
## 遗留问题
- 09:41当前 Skill 是新建在项目级 `.codex/skills` 目录里,本轮可以通过文件检查验证结构,但是否被未来会话自动加载还依赖 Codex 对项目 Skill 的刷新机制。建议后续新开会话或下一次任务时确认 Skill 列表是否出现 `agent-change-log`
- 09:43`.codex/` 曾被 `.gitignore` 整体忽略,新建的 `agent-change-log` 默认不会进入普通提交范围09:44 已改成只放行该 Skill。建议后续如果还新增其他项目 Skill也按同样方式逐个显式放行别一次性开放整个 `.codex`
- 10:01当前工作区已有大量未提交改动且本地 `main` ahead 1。建议后续如果真的发现 upstream 新提交,先用 fetch 和 `HEAD..@{u}` 写日志;只有在工作区干净、可快进时再执行 `git pull --ff-only`,避免把其他智能体提交和本地半成品混到一起。
- 10:02本地 ahead 提交也可能来自其他智能体,不能只看 upstream behind。建议后续日志固定同时记录 `HEAD..@{u}``@{u}..HEAD` 两个方向。
- 10:21自动日志触发时发现 fetch 未成功失败error: cannot open '.git/FETCH_HEAD': Operation not permitted。建议后续在有 Git 写权限和网络权限的环境里重新执行拉取检查。
- 10:21当前环境不能写 `.git/hooks`,所以 post-commit hook 模板已经入库,但尚未安装到本 checkout。建议在有 `.git` 写权限的环境执行 `tools/agent-change-log/install_post_commit_hook.sh`
- 10:24本轮未能在容器内执行 pytest也未能实际确认容器是否已安装 `mupdf-tools`。建议在 Docker 权限恢复后重建/重启 `x-financial-main`,执行定向 OCR 测试,并在 5173 用真实 PDF 票据确认预览图和 OCR 字段都保留中文。
- 10:2810:06 那条既有票据记录已经写成 PDF fallback代码修复不会自动改写旧 meta。建议重新上传一次同一 PDF或在容器权限恢复后触发票据重识别/重建预览,确认新记录变为 PNG 预览。
- 10:32最新 10:29 上传仍然写成 PDF说明运行中的后端可能还没加载最新代码或本轮上传发生在缓存版本修复之前。建议重启后端/重建容器后再重新上传,确认 OCR cache key 已包含 `pdf-image-ocr:`
- 10:40本轮可以确认 5173 服务可达、结构测试和生产构建通过,但当前环境没有可调用的浏览器自动化插件,项目也没有现成 Playwright/Puppeteer 依赖,所以未生成真实页面截图。建议在具备浏览器自动化的环境回放一次附件预览,确认主内容区居中效果。
- 10:41票据夹 PDF 保存阶段已补主动生成图片预览,但当前沙箱不能访问 Docker socket无法运行容器内 pytest也无法刷新已有 PDF 票据的旧 meta。建议 Docker 权限恢复后先跑定向测试,再对旧记录触发 `resolve_preview` 或重识别来补 `preview.png`
## TODO
- [x] ~~检查 `agent-change-log` 的 frontmatter、触发描述和日志模板是否完整。~~(完成于 09:42证据`rg` 命中 frontmatter、日志路径和三段式标题`git diff --check` 无输出)
- [x] ~~将 `AGENTS.md` 接入“每次修改后调用日志 Skill”的项目级规则。~~(完成于 09:42证据`AGENTS.md` 已新增 `变更日志 Skill 规范`
- [x] ~~如果需要把 `agent-change-log` 随仓库提交,确认是调整 `.gitignore` 放行还是用强制添加方式纳入版本管理。~~(完成于 09:44证据`.gitignore` 已只放行 `.codex/skills/agent-change-log/**`
- [x] ~~把 Git 拉取检查和其他智能体 upstream 提交分析纳入 `agent-change-log`。~~(完成于 10:01证据Skill 已新增 `Required Git Check``AGENTS.md` 已要求日志前运行 `git fetch --all --prune``git log HEAD..@{u}`
- [x] ~~把本地 ahead 提交也纳入 `agent-change-log` 的提交分析范围。~~(完成于 10:02证据Skill 和 `AGENTS.md` 已新增 `git log @{u}..HEAD`,并记录 `9321260` 本地 ahead 提交)
- [x] ~~补上提交后自动写日志的可执行脚本和 hook 模板。~~(完成于 10:21证据`update_change_log.py` dry-run 与真实写入成功,`.githooks/post-commit` 已新增)
- [ ] 在有 `.git` 写权限的环境执行 `tools/agent-change-log/install_post_commit_hook.sh`让提交后自动写日志真正启用。来源10:21 当前沙箱安装失败)
- [ ] 在后续每次 bugfix、新功能、重构或配置/文档修改后,调用 `agent-change-log` 并增量更新当天日志。来源09:41 用户要求)
- [ ] 重建/重启 `x-financial-main`,确认容器内存在 `mutool`,并执行 OCR 定向 pytest。来源10:24 PDF 中文转图链路修复)
- [ ] 在 5173 真页重新上传/预览火车票 PDF确认预览 PNG 不再丢中文OCR 字段不再出现“乘车人/站点”等中文缺失或错位。来源10:24 PDF 中文转图链路修复)
- [ ] 重新上传 10:06 同款 PDF 或触发该票据重识别,确认新的 `meta.json` 写入 `preview_kind=image``preview_media_type=image/png`来源10:28 PNG 预览保留修复)
- [ ] 后端加载缓存版本修复后,重新上传同一 PDF确认不会再命中旧 OCR 缓存,`ocr_line_count` 和 PNG 预览都来自新转图流程。来源10:32 OCR cache key 修复)
- [ ] 在有浏览器自动化能力的环境回放 AI 工作台附件预览弹窗截图确认弹窗按侧边栏右侧主内容区居中。来源10:40 附件预览弹窗布局修复)
- [ ] Docker 权限恢复后运行票据夹 PDF 预览定向测试,并刷新已有 `preview_kind=pdf` 的旧票据 meta。来源10:41 PDF 保存阶段主动生成图片预览修复)