Claim 的 references 用 kind:id,服务端通过 /api/papers/lookup 精确解析

Claim 增加一个 references 字段:它引用的文献 works,存成带命名空间、 无版本的 kind:id 字符串——arxiv:2208.06941, openalex:W4406693713, doi:10.22331/q-2023-03-20-955。这些 IDs 同时出现在 Claim 的 claims.json 和 qatlas-lean 在 Claim 抽取期间消费/产出的 gitea issue 正文中,这会锁定格式 (一旦 issues 携带它们,难以回退的成本就是重写 agony/qatlas-lean 的 issue 历史)。

解析(kind:id → title / authors / year)是服务端且精确的:新增 GET /api/papers/lookup?ids=arxiv:…,openalex:…,doi:… 批量端点,从本地 OpenAlex corpus(ADR 0006)回答,并为每个 ref 返回 {ref, title, authors, year, hosted, resolved}。 自由文本 fuzzy 文献检索是刻意独立、延后的能力。

为什么是带命名空间的 kind:id,且无版本

  • 自描述前缀 → 解析器直接分发到正确后端(openalex:/doi:/arxiv:), 而不是从形状推断;它在人读 issue 正文时也可读。它匹配 qatlas-lean 的文献工作流 和 QA 的只读 papers/corpus 接口面所共享的 lookup 模式。

  • 无版本:一个引用(Reference)引用的是一个 work,不是一个快照,所以是 arxiv:2208.06941(没有 vN)——这刻意不同于归档论文(paper-of-record);QA 用代理键 papers.paper_id(ADR 0009)识别归档论文,而 PDF 版本按资产存在 paper_assets.arxiv_version,不放在 paper id 自身里。

  • 一个引用(Reference)(这里的文献指针)不同于 lean reference lemma (语料内 Lean 复用候选 entry——reference_lemmas),也不同于 proof citation (证明说明文字里的 citation,带 citation_string)。术语表记录了这个区别。

为什么是服务端 lookup,而不是客户端 public API 解析

ADR 0006 把完整 OpenAlex corpus 保存在本地,目的正是让“每个 referenced_works id 都能本地解析——引用遍历永不 fallback 到 public API”。让客户端对 public API 解析 references,正是 0006 要消除的冗余。因此:

  • Lookup 是一种 host-core Paper/corpus 能力(它补上了现有 papers/getCitedRefs stub, hostapi/core.go:89 的精神),不是 claim-domain 端点——所以不违反 ADR 0003。 它按 ID 读取 OpenAlex corpus;它对 Claims 一无所知。

  • 读取它与 QA/lean 边界一致:qatlas-lean 可以运行 Claim 抽取和文献/引用增补, 但这些工作流只是从 QA 读取 paper bytes 和 corpus metadata;它们不会让 QA 起草或持久化 Claims、proofs 或 Theorems。QA 提供只读 paper/corpus 基底; lean own claim/proof/theorem 工作流。

  • 优雅降级(镜像 ADR 0006):当 corpus 不可达时,qatlas client 可以在该会话中 fallback 到 public OpenAlex API。

证明器如何访问 QA:优先 CLI/HTTP(+ MCP),保留只读 DB

证明器(qatlas-lean)通过两种被认可的只读模式读取 QA 的 Paper catalog + OpenAlex corpus, 按优先级排序。lean 永不写 QA 存储——QA own paper md / catalog / corpus,lean own claims/proofs/theorems;QA 永不起草或维护 lean 的内容(反之亦然)。

  1. CLI / HTTP — 首选,默认。 qatlas client(qatlas paper …)以及 REST 接口面 (GET /api/papers/lookup, /api/papers/{id}/markdown, /stats, /needs-mineru),使用 papers:read PAT。lean 不持有 QA DB credentials,因此 QA 可以在稳定 HTTP 合约 之后自由演进物理 schema。一个新的 QA MCP server 把同一个读取接口面包装成 自描述工具(MCP tool schema 就是 文档),让 qatlas-lean 的 Claim 抽取与 文献/引用工作流不用直接 DB access 也能消费 QA 的 paper/corpus data。

  2. Read-only SQL — 保留,次级。 QA PostgreSQL 上的直接只读 role (papers + paper_assets + openalex_works——ADR 0009 重构后的 catalog,以及 ADR 0010 的 corpus,后者删除了 work_referenced edge table),只在某个 query 需要 HTTP 无法高效表达的 join/scan 时使用。这不再是 “deferred”:它是保留并文档化的能力—— 但它是 fallback,不是默认,因为它把 lean 耦合到 QA 的物理 schema。

为什么是 /api/papers/lookup(文献总入口),不是 /api/works 或 /api/openalex

  • 这个端点是现有 /api/papers/{path...} catch-all 下的仅 path 特例, 与 /api/papers/stats 和 /api/papers/needs-mineru 并列;/api/papers/{id}/markdown 以及其余按 id 取资产的接口面不受影响。

  • lookup 覆盖更广义的文献(OpenAlex corpus 里大多是 QA 不 host 的 works),并用 hosted 标记每个命中。一个 QA 尚未 host 的 corpus 命中之后可以触发后台 PDF 下载 + MinerU 转换,并成为 hosted Paper——因此用单个 /api/papers/ 总入口同时覆盖 “查找文献” + “获取 hosted Paper 的资产” 是一致的。

  • 术语表仍然把 Paper catalog 和 OpenAlex corpus 作为不同的 数据存储 (ADR 0006);/api/papers/ URL 只是文献 总入口。works / openalex 作为 资源名词被否决:works 读起来像实体而不是操作,openalex 会把 vendor name 焊进 URL。

unresolved Reference 为什么带 warning 提交,而不是阻塞

引用(References)是为 Claim 增补信息;它们不是正确性门控。OpenAlex 覆盖缺口(全新 preprint、 无 DOI 的书、打错的 id)不应阻止提交一个其它方面良好的 Claim。contrib WebUI 对 unresolved Reference 显示 warning;人来删除 / 编辑 / 保留它。保留下来的 unresolved Reference 以原始 kind:id 和 "resolved": false 存储。

备选方案

  • Bare ID(推断 kind) / full URI — 否决(见“为什么是带命名空间的 kind:id”)。

  • 客户端 public-API 解析 — 否决:与 ADR 0006 的本地 corpus 冗余;还会把我们已经持有的数据的负载分摊到每个用户的 OpenAlex key 上。

  • 新增 /api/works 或 /api/openalex resource — 否决,改用 /api/papers/ 文献总入口

    • hosted flag。

  • 直到每个 Reference 都解析成功才允许 Confirm — 否决:面对 corpus 覆盖缺口太脆弱。

影响

  • GET /api/papers/lookup 作为 /api/papers/{path...} 下的仅 path 特例实施。 papers/getCitedRefs stub 的角色被澄清为以 paper 为中心的 “paper X cite 了哪些 works” query, 其结果 items 自身也可通过 lookup 解析。

  • claims.json 和 gitea issue body 增加一个 references list,元素为 kind:id(加一个 resolved flag);格式由 issue history 锁定(上线前不欠 backwards-compat,但 issue history 是实际锁)。

  • 证明器访问模型已决策(取代早期 “read view deferred”)。 证明器通过 优先 CLI/HTTP(+ 一个新的 self-documenting MCP),保留 read-only SQL role 作为次级路径 读取 QA(见“证明器如何访问 QA”)。早期 deferral 已解决:DB path 是 retained, not deferred, 但降级到 CLI/HTTP 之下。因此原交接里的 “design the prover's PG read schema this pass” 被重新收束为次级路径的只读 schema contract,而不是 bespoke prover DB view。

  • 两条访问路径都要文档化。 CLI/HTTP:qatlas paper CLI docs(docs/client/)+ REST API docs(docs/server/rest-api.md + /swagger/ 上生成的 OpenAPI/Swagger, 由 pixi run swagger 重新生成)+ 新 MCP server(self-describing tool schemas)。 Read-only SQL:发布只读 schema contract(papers / paper_assets / openalex_works 的稳定可读子集——ADR 0009/0010)+ read-only role grant。

  • 新增构建项——覆盖 papers read surface 的 QA MCP server(lookup + markdown + stats), 纯新增(QA 目前没有 MCP)。它把同一个 papers:read HTTP capability 重新暴露为 MCP tools; 它不开放任何写入路径。

  • Fuzzy free-text literature search 是已知未来能力,本迭代不构建。

  • qatlas-lean 仍然是运行 Claim 抽取和文献/引用工作流的地方;QA 只通过 CLI/HTTP、MCP,以及上述次级 read-only SQL path 暴露只读 paper/corpus 基底。