- 删除已落地的 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 微调服务配置
22 KiB
2026-06-24 工作日志
当日工作内容
-
09:41:我开始为 X-Financial 补一个专门写修改日志的项目级 Skill,目标是让后续每次 bugfix、新功能、重构或配置/文档修改之后,都能留下有时间、有操作、有判断的增量记录。
- 修改:新增
agent-change-logSkill,约定触发场景、每日日志位置、三段式结构、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-logSkill 能进入普通版本管理视野,同时继续保护.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。
- Git 提交检查:已运行
-
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-commitSkill、展示元数据、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 捕捉并分析。
- Git 提交检查:
-
10:21:自动记录
9321260提交后的工作日志。(auto-log:9321260)- Git 提交检查:fetch 失败:error: cannot open '.git/FETCH_HEAD': Operation not permitted;upstream
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 状态,不替代业务测试;业务验证仍以本次任务实际运行结果为准。
- 影响:提交后即使执行代理忘记手动写日志,也会留下最低限度的时间、提交和分支状态记录。
- Git 提交检查:fetch 失败:error: cannot open '.git/FETCH_HEAD': Operation not permitted;upstream
-
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。
- Git 提交检查:当前权限下
-
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。
- Git 提交检查:
-
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。
- Git 提交检查:
-
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/坏识别结果。
- Git 提交检查:
-
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 工作台侧边栏,在右侧主工作区内居中展示,截图里的“偏左/不居中”观感会收敛。
- Git 提交检查:
-
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 还需要单独刷新。
- Git 提交检查:
遗留问题
- 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:当前工作区已有大量未提交改动,且本地
mainahead 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:28:10: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
检查(完成于 09:42,证据:agent-change-log的 frontmatter、触发描述和日志模板是否完整。rg命中 frontmatter、日志路径和三段式标题;git diff --check无输出)将(完成于 09:42,证据:AGENTS.md接入“每次修改后调用日志 Skill”的项目级规则。AGENTS.md已新增变更日志 Skill 规范)如果需要把(完成于 09:44,证据:agent-change-log随仓库提交,确认是调整.gitignore放行还是用强制添加方式纳入版本管理。.gitignore已只放行.codex/skills/agent-change-log/**)把 Git 拉取检查和其他智能体 upstream 提交分析纳入(完成于 10:01,证据:Skill 已新增agent-change-log。Required Git Check,AGENTS.md已要求日志前运行git fetch --all --prune和git log HEAD..@{u})把本地 ahead 提交也纳入(完成于 10:02,证据:Skill 和agent-change-log的提交分析范围。AGENTS.md已新增git log @{u}..HEAD,并记录9321260本地 ahead 提交)补上提交后自动写日志的可执行脚本和 hook 模板。(完成于 10:21,证据:update_change_log.pydry-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 保存阶段主动生成图片预览修复)