arXiv 源码与正文生命周期审计¶
审计日期:2026-10-24。审计基线:6125280f0;初次审计提交:80352d3e0。
下文场景表和问题证据保留审计时状态;修复结果见本节,当前契约见
论文入库 与 聊天上下文。
修复结果(2026-10-24)¶
- 复用
ParseBody作正文准备入口,先准备有效 arXiv TeX,再处理已有 Markdown / PDF; 本地识别与合并、Connector 稳定路径 finalizer、Zotero 迁移、打开 / 全库 reconcile 均接通。 标识符 / Bib/RIS / CLI 下载复用同一源码准备;远程 staging 与 Connector 镜像也复用它。 - 补资源分别检查原始源码和可读正文。旧 OCR、旧 catalog 标签不能掩盖缺源码;UI 使用 Host 的有效 TeX / 缺源码标志,PDF-only 不反复提示,源码失败保留独立下载提示。
agentero-source.json记录明确无 TeX 与可重试失败;自动请求有 15 分钟退避,手动下载 可立即重试。临时源码失败不静默启动云端 OCR,源码被同步策略排除时不自动补拉。- 先落主 PDF,再用原生文字版本戳固定 e-print 请求;保留用户显式版本 URL。显式版本与 PDF 文字戳冲突时报告错误。未指定版本且文字戳读不出时按最新版下载(无版本链接即当时最新版)。
- gzip / tar 在暂存目录完整解包和校验;短 HTML、空 TeX、损坏 tar 不发布为可用源码。 发布保护已有不同内容的源码与 sidecar,失败撤销新增文件。主 PDF 不再取工程内图 PDF。
- 源码发布与正文提交共用按论文路径的锁;PDF 许可等待后重判,落盘前再验 TeX、PDF 标识 和取消状态。晚到的有效源码使旧 OCR 结果失效,不覆盖原始源码或旧 Markdown。
- 抽取编译侧 literal TeX helper 供读取共用;聊天全文、章节与搜索优先主 TeX 和按位置展开 的依赖,保留公式。catalog 正文投影使用既有事务字段更新,清除产物时同步修正来源。
- 广场 scratch 同样源码优先,
SOURCE.txt为供 Agent 只读的展开副本;没有 TeX 才解析 PDF。
本次保留的产品边界:PDF 版面分析独立;force 仍表示重建派生正文,不强制越过有效源码;
切换默认正文引擎不自动重跑全库;LaTeX 源码翻译仍属未实现的独立功能。复杂 TeX 宏不执行,
已有用户源码与上游冲突需要用户处理。未指定版本时按最新版补源码;显式版本与 PDF 戳冲突仍报错。
验证包括 core / Host 回归测试、前端资产判定测试、工作区 Clippy 与类型检查;桌面使用
pnpm tauri dev 和独立配置 / Vault 验证:两篇都保留旧 OCR Markdown,缺源码的一篇显示
下载提示,有效 TeX 的一篇正常打开且 catalog 来源修正为 latex。未对真实 Vault 执行修复,
未调用真实云端 OCR;远程网络 / arXiv 真实下载未作端到端回放。
结论与用户意图¶
确实存在 arXiv 论文可以获得 LaTeX,却先进入 PDF 正文解析 / 云端 OCR 的路径。
正常的标识符入库会并发下载 PDF 和 e-print,并等待两者结束;若磁盘已检测到
.tex/.ltx,计划与正文执行器都会跳过 ParseBody。问题集中在其它入口、临时下载失败、
并发补全和后续读取,不能概括成“所有 arXiv 都在 OCR”。
按科研阅读意图,合理的默认行为应为:
- 已知 arXiv 身份时,优先取得、验证并保留对应版本的原始源码。
- 源码下载中、临时失败、明确无 TeX、用户选择不下载,是不同状态。
- 可用源码应被 paper-reader 和聊天上下文共同消费;不要求源码能在本机编译。
- 无可用源码时再选正文提取方式;原生 PDF 文字提取与逐页 VLM OCR 应区分。
- 阅读 PDF 仍可需要图表、坐标、跳转和翻译所依赖的版面分析。
- 临时回退生成的 Markdown 不应让源码补全永久停止,也不应优先覆盖晚到的有效源码。
三条容易混淆的管线¶
| 管线 | 产物与用途 | 当前与 TeX 的关系 |
|---|---|---|
RecognizeMetadata |
识别标题 / DOI / arXiv ID,改名或合并 | liteparse probe 明确关闭 OCR;它本身不是全文 OCR |
ParseBody |
PDF → PAPER.md,更新 body_source/body_quality |
has_tex=true 时直接返回,force=true 也一样 |
LayoutAnalyze |
PDF → source/layout.json / layout-index.json,供图表、引用定位、上下文等使用 |
有 PDF 就可以调度,与是否存在 TeX 无关 |
parserBackend 与 layout.backend 是两项独立设置:
- 正文使用
agentero/openaiCompatible时渲染 PDF 并逐页发给 VLM,不先判断原生文字是否足够。 - 正文使用
local时优先本地文字,允许 best-effort OCR;body_source=ocr是复杂度预检 的needs_ocr标签,不能单凭此字段证明 OCR 确实执行且成功。 - 版面使用
local时是本地模型与 PDF 文字层处理;使用 MinerU / Paddle 时会调用远程 PDF 解析服务,即使源码已在磁盘,也可能发生远程 OCR / 提取。该任务有独立用途。
入口:core paper/analyze/parse/mod.rs::parse_paper_body_inner、
run_liteparse_markdown_direct、run_liteparse_probe_direct;Host
paper/analyze/body_engines/openai_vlm.rs::parse;前端 lib/pdf/layout/run-analysis.ts。
下文 core 指 crates/agentero-core/src/features/,Host 指 src-tauri/src/features/,
integration 指 src-tauri/src/integration/,前端路径相对 src/。
各入口与异常场景¶
| 情况 | 当前行为 | 判断 |
|---|---|---|
| 魔棒 / 广场入库,PDF 和 TeX 均成功 | tokio::join! 等待两个下载;tex=true 不计划正文解析;仍可分析 PDF 版面 |
正常 |
| 本地已有正常 TeX,再打开 / 全库补正文 | needs_paper_md=false,正文执行器也跳过 |
正常;不代表所有读取端能消费 TeX |
只有空 source/,没有 .tex/.ltx |
仍视为无 TeX,允许正文解析 | 目录本身不能证明源码存在 |
| e-print 实际为 PDF-only | 原始 %PDF 响应写到论文根目录,tex=false,允许 PDF 正文解析 |
合理回退;不应无限重试 TeX |
| 源码下载 429 / 网络失败 / 解包失败,PDF 成功 | 错误放入 messages,没有持久化的源码失败类别;通常继续计划 ParseBody |
临时失败与明确无源码混同 |
| 整体资源下载超过 180 秒 | 返回资源错误,已落盘文件保留;commit 的返回资产 flags 可能全 false | 后续打开 / reconcile 又按磁盘判定,缺少统一恢复状态 |
| 本地拖入 PDF,后台识别出 arXiv ID | 更新 metadata / 改名后直接检查 needs_paper_md,没有先下载 TeX |
明确的源码优先断点 |
| 自动收录裸 PDF | 后台识别后走同一 runner | 继承本地 PDF 入口问题 |
| Connector 浏览器成功上传 PDF | 初次 commit 使用 Deferred;成功上传后打开 / reconcile,不主动补拉 TeX | 明确的源码优先断点 |
| Connector 浏览器 PDF 失败,走 Host resolver | ensure_paper_assets_with_cookies 会尝试 PDF + arXiv TeX |
反而比浏览器上传成功时更完整 |
| Zotero 迁移,已有 arXiv ID 和本地 PDF | 迁移完成直接 spawn 正文解析,没有源码下载步骤 | 可能直接进入 OCR |
| Bib/RIS 导入,映射结果含 arXiv ID | AssetsPolicy::SyncDownload 尝试 TeX |
成功时正常;失败时同其它回退路径 |
| DOI / URL 元数据未返回 arXiv ID | 下载器只按 arxiv_id 字段决定拉 TeX,不从论文属于预印本自动推断源码 |
身份识别不足时走 PDF;不能承诺所有 DOI 都能找到 arXiv |
| 打开论文 / 启动 Vault,PDF 已到而 TeX 仍在下载 | reconcile 不等待 DownloadAssets,允许抢跑正文解析 |
存在竞态 |
OCR 已生成 PAPER.md,TeX 仍缺失 |
UI 和批量补资源把可读正文当作足够;不再选中该论文补源码 | 会长期停留在回退结果 |
| 手动单篇补资源 | 若实际执行下载命令,仍会按磁盘缺失尝试 TeX | 可以修复部分旧数据;自动筛选与图标可能不再提示 |
| 下载 TeX 成功,旧 OCR Markdown 仍存在 | 不清理旧 Markdown;显式下载命令更新 body_source=latex |
paper-reader 与聊天上下文可能读取不同正文 |
| 用户清除 / 强制重建正文 | 清除 PAPER.md 后批量入队,但遇到任意 TeX 仍跳过 |
无法表达“这次明确改用 PDF 解析” |
广场 @ 全文临时副本 |
scratch 只下载 PDF,直接调用 parse_body_with_engine,不下载源码、不查 Vault TeX |
独立的 arXiv → OCR 路径 |
| 云同步排除 source,但保留 metadata / PDF | 本机无 TeX;reconcile 根据本机文件计划正文解析,metadata 不能表达 source 被排除 | 应遵守同步意图并明确回退策略 |
| 远程 Vault / CLI | 另有远程 staging/上传入口;CLI 只报告 preparation 而不执行桌面任务 | 本次只核对实现,未做配对设备 / CLI 全流程回放 |
对应入口:core/paper/import/{mod.rs,paper_import/mod.rs,sources/zotero/io.rs};
Host/paper/import/job_runners.rs;Host/paper/zotero/db.rs;
integration/connector/import.rs::{import_connector_item_with_cookies,session_has_attachment_resolvers,save_attachment_from_resolver};
core/paper/discovery/scratch.rs::materialize_scratch。
已确认的问题及优先级¶
P1:识别出 arXiv 身份后,没有统一的源码准备步骤¶
recognize_metadata_runner 在应用识别结果后,仅按最终路径的 PaperCaps 安排正文、引用和版面。
没有把新获得的 arxiv_id 接入资源下载。Connector 有 PDF 时 resolver 直接早退,Zotero 迁移
直接 spawn 正文解析。三个入口产生的都是同一篇论文,但源码策略不同。
建议:在稳定路径 / 识别完成之后,汇入同一个论文准备入口;已知 arXiv 时先决策源码。 保留 Connector 先完成上传和目标目录移动的时序,不将网络下载塞回扩展的短超时请求中。
P1:可读正文被错误地用作“源码资产已完整”¶
PaperCaps::needs_asset_download(body_source) 不接收 arXiv 身份。只要有 PDF,且有 PAPER.md
或非空 body_source,就返回 false。前端 paperAssetDownloadReasons 重复这套规则。
结果:源码失败 → OCR 产出 Markdown → 补资源入口消失 / 批量跳过;再次用魔棒导入也可能在
batch 预检时以 already_in_library 跳过,无法作为修复手段。
建议把“已有可读正文”和“仍应补齐原始源码”拆开;网络临时失败可重试,明确 PDF-only 可停止,
同步排除或用户不下载应被保留。旧 body_source 不能代替实际文件检查。
P1:下载与解析没有依赖约束,晚到的源码不会阻止 OCR 落盘¶
job_reconcile_paper 只延后活跃的 RecognizeMetadata;全库 reconcile 按磁盘直接入队。
enqueue_core 创建普通任务时 depends_on 为空。正文执行器只在开头检查一次 TeX,等待解析
许可后、发起云端请求前和写盘前都没有重判。
可发生:打开 / reconcile → 此刻只有 PDF → OCR 启动 → TeX 下载完成 → OCR 仍写入 PAPER.md
及 body_source=vlm。即使 TeX 落盘已把能力缓存失效,也不会影响在途任务。
建议:正文依赖源码准备状态;等待许可后重新决策;落盘时校验输入版本 / 当前优选来源。 已发出的远程请求不一定能撤销,但旧结果不能成为新的优选正文。
P1:TeX 的“存在”与“有效可读”没有区分¶
probe_paper_caps 见到任意 .tex/.ltx 就置位,不检查大小、内容、主文档或依赖。
unpack_arxiv_eprint 将小于 512 bytes 的任意响应视为单文件 TeX;较长内容中只要样本含
反斜杠,也可能被当作 TeX。没有在解压后的 payload 再进行 PDF 类型判定。
另一个方向是半解压:tar 顺序直接写到正式 source/,后续条目错误不会撤销已写的主 .tex。
下次 need_tex = !before.has_tex 为 false,不再下载;正文也继续跳过。tar 的原始错误被丢弃,
最终还可能变成泛化的格式错误。
建议:下载 / 解包先进入暂存目录;识别实际格式,拒绝 HTML / 错误页;验证主源码及可读文本,
然后提交源码文件与状态。可复用已有 TeX root / include 分析能力;缺本机宏包或编译失败不能
直接判定“源码不可读”。现有 source/ 同时放引用、版面 sidecar,不能直接整体替换或删除。
P1:正文消费端不统一,LaTeX 优先只在部分工作流成立¶
lib/paper/reader.ts::buildPaperReaderUserPrompt 和 Vault 模板要求优先读 TeX。
但 core/context/service.rs::full_text 是 PAPER.md → layout regions → unavailable;
section_text、search_paper 也没有 TeX 正文分支。
结果:有源码但没有 Markdown / layout 时,聊天全文工具报告不可用;两者都有时,旧 OCR Markdown 优先。Agent 可能通过其它文件工具自行读到 TeX,因此这里的结论限于上下文工具路径。
建议统一正文来源选择,给上下文工具提供主 TeX、依赖文件和来源信息;支持安全的按需读取, 不要只靠 prompt 约定,也不必为所有 TeX 强制跑本机编译或重新 OCR。
P2:元数据与原始资产 / 派生产物的关系无法自愈¶
- 初次
paper_commit下载成功并返回tex=true,但没有写body_source=latex;显式download_paper_assets_with_progress才做该更新。同样的文件产生不同 catalog 状态。 - 显式下载只要检测到任意 TeX,就记录
body_quality=high,没有正文质量验证。 - 补到 TeX 后旧
PAPER.md仍在;外部增删源码主要触发能力缓存失效,不更新正文来源字段。 - 清除正文解析结果删除
PAPER.md,不清空body_source/body_quality;批量补资源可能继续 相信已经不存在的正文。正文 reconcile 会重建其中一部分,但不能恢复可信的来源状态。 - ParseBody runner 将“因为 TeX 跳过”和真正解析完成都标为 Succeeded,跳过原因与云端回退 messages 没有完整投影到任务结果,用户很难理解发生了什么。
建议:原始资产可用性、当前选择的正文、派生结果的来源 / 输入指纹分开维护;删除或替换产物时 同步失效对应投影。优先复用现有 catalog 原子字段更新能力,避免新增全行覆盖写。
P2:版本信息丢失,后补源码可能与本地 PDF 不对应¶
extract_arxiv_id / strip_arxiv_version、enrich_remote_urls 和源码下载都按 bare ID
构造 URL。用户粘贴 v1 不会固定下载 v1;本地已有旧版 PDF 时,稍后源码补全会访问无版本
URL,可能拿到新版。need_pdf=false 又保留原 PDF,缺少两者一致性验证。
arXiv 的不同版本属于永久科研记录;无版本的摘要链接显示最新版本,见 官方版本说明。
建议去重继续用 bare ID,同时保存用户请求 / 实际取得的版本;PDF、TeX、引用和解析产物记录 共同的版本或内容指纹。后补发现不一致时显式处理,不能默认为同一内容。
P2:主 PDF 与工程内 PDF 仍有混用边界¶
PaperCaps 在没有根 PDF 时递归寻找任意 PDF,source/ 中的图、附录 PDF 也算;根级多 PDF
则由文件名排序选首个。该能力同时决定是否需要下载主 PDF。部分解包只留下图 PDF 时,可能
错误抑制主 PDF 下载或将图片当正文输入。
版面任务已有仅使用根目录 {id}.pdf 的保护,应保留;正文 / 下载的主文件判定也应与之明确
对齐,并为用户实际选择的旧文件名留兼容路径。
其它尚未闭合的能力¶
- 广场 scratch 不下载源码、不复用 Vault 中的现有源文档;它绕过论文级 TeX guard 直接调用
引擎。不能只修改
parse_paper_body_inner就宣称所有 arXiv 入口都已修复。 lib/workspace/actions-latex-translation.ts仍是提示“未实现”的 stub;源码下载并不等于 已有 LaTeX 双栏翻译能力。这与本机.tex编辑 / 编译是不同工作流。- 切换正文引擎不会自动使已有
PAPER.md失效;现有文件优先短路。应定义用户是只修改后续 默认值,还是要求重建选中论文,不能暗中对全库重跑 OCR。
推荐生命周期与实施顺序¶
导入 / 上传 / 识别 / 同步 / 打开论文
→ 确定稳定路径、论文身份与版本
→ 探测资产 + 读取源码获取状态和用户策略
→ arXiv 源码未知 / 可重试:准备源码;下载中:等待或显式使用临时回退
→ 有效 TeX:作为正文来源,供 Reader 和 Context 共用
→ 明确无源码 / 用户选择 PDF:按当前正文策略提取文字或 OCR
→ 落盘前校验当前输入与优选来源
→ 按实际产物更新来源、质量、指纹,刷新消费者
PDF 版面分析独立按功能需要运行,保留坐标与图表能力
不需要先建设通用工作流框架。建议从现有 PreparationPlan / PaperCaps 演进:
- 先修路由与补全:一个共享的源码决策入口,接入 local-PDF / Connector / Zotero; 区分未知、下载中、可用、明确无 TeX、临时失败、用户排除;已生成 Markdown 不阻止原始源码补全。
- 再修在途与落盘:绑定源码准备依赖,重检 / 指纹保护,暂存解包和有效性校验; 显示源码失败原因,避免无解释地自动切入逐页 OCR。
- 统一正文消费与修复旧库:Reader / Context 用同一来源选择;对照盘上文件修正 catalog, 标记旧 OCR 为回退产物,不删除用户 NOTES 或直接覆盖既有源码;涉及版本不明时单独处理。
- 补版本与次级入口:保留 arXiv 版本,覆盖 scratch、同步排除、远程 Vault,明确手动 PDF 重解析与引擎切换的语义。
修复时至少覆盖:成功 TeX、PDF-only、临时 429、源文件晚到、空 / 假 TeX、半解压、已有 OCR 后补源码、旧 PDF + 新源码、Context 全文、Connector 上传成功与 fallback、本地识别、Zotero。
本次验证与边界¶
cargo test -p agentero-core features::paper::capabilities::tests -- --nocapture:11 项通过。cargo test -p agentero-core features::paper::import::preparation::tests -- --nocapture:2 项通过。- 临时加入隔离探针,调用真实公开入口 / 同模块解包函数,运行
cargo test -p agentero-core audit_probe -- --nocapture: 6 项复现通过:Markdown / 旧 body_source 隐藏缺源码;空 TeX 阻断 force;TeX 晚到仍提交 OCR;Context 忽略 TeX 并选旧 Markdown;短 HTML 被保存为 TeX;损坏 tar 留下部分 TeX。 - 晚到源码探针使用 mock 引擎在 guard 后写入 TeX,未调用付费服务。探针断言的是当前问题 行为,验证后已移除,未作为“正确行为”测试保留。
- 未读取或修改真实 Vault,未对用户观察到的某一篇论文归因;未执行真实 arXiv 下载、 云端 OCR、桌面 UI、远程 Vault 或同步端到端回放。
- 源码归档的常见 gzip / tar 形式核对了 arXiv 官方解包说明。