Skip to content

fix(perceives): PDF→Markdown 1:1 还原 R10 — Agentic AI Survey 13 维新失真治理(D13-D25) - #692

Merged
ThreeFish-AI merged 9 commits into
feature/1.x.xfrom
ThreeFish-AI/pdf-markdown-fidelity-restore
May 28, 2026
Merged

fix(perceives): PDF→Markdown 1:1 还原 R10 — Agentic AI Survey 13 维新失真治理(D13-D25)#692
ThreeFish-AI merged 9 commits into
feature/1.x.xfrom
ThreeFish-AI/pdf-markdown-fidelity-restore

Conversation

@ThreeFish-AI

@ThreeFish-AI ThreeFish-AI commented May 27, 2026

Copy link
Copy Markdown
Owner

背景

ISSUE-094 PDF→Markdown 还原工程 第十轮迭代。本轮以 Agentic AI Survey 37 页 Springer Nature 期刊 作为 unseen sample 端到端测试 negentropy-perceives 的 parse_pdf_to_markdown 管线(11 stages:preprocessing → quick_scan → layout_analysis → text_extraction → table_extraction → formula_extraction → image_extraction → code_detection → assembly → asset_bundling);逐页对照 PDF 原文档与 Markdown 渲染(Knowledge Base 的 Harness Engineering corpus),按 12 维质量矩阵深度扫描,累计定位并修复 13 个此前 sample 未触发的根因维度

主要影响:学术 PDF 在 Markdown 渲染时残留大量「不可见破坏」—— 软连字符 / 零宽空格 / UTF-8 双编码 mojibake / 期刊运行头 / 括号空格 / 句子型 heading 误判 / list-item label+body 折叠等。这些残留破坏文本拷贝、全文检索、URL 可点击性、TOC 大纲、视觉一致性。

修复维度(R10 新增 D13-D25 共 13 维)

维度 失真 修复点 sample 实例
D13 软连字符 U+00AD 渗漏 MarkdownFormatter._apply_typography_fixes­[ \\t]*(?=[a-z]) 合并 + 兜底 strip 138 → 0
D14 反向 word -word(图注路径) (?<=[a-zA-Z]) -(?=[a-z]) 强制合并 11 → 0
D15 期刊运行头 / 页脚泄漏 FitzTextExtractor._is_header_footer 补 Springer / 双数字 / Surname et al. 4 类模式 58 → 0
D16 列表项 lead-in 句被误升 heading _detect_heading 编号路径 + 非编号路径补「作者代词 + 多词正文」过滤 3 → 0(h2 15→12, h4 13→12)
D17 零宽空格 U+200B(URL 注入) 全局 text.replace("​", ""),保留 U+200D ZWJ 1304 → 0
D18 UTF-8 / CP1252 双编码 mojibake(em / en dash / 引号 / 省略号) 固定 6 模式映射 â€" → — 1 → 0
D19 两侧空格 word - word(表格 cell 内) (?<=[a-zA-Z]{2}) - (?=[a-z]{2}) 强制合并 80 → 0
D20 Table caption 紧邻重复 _deduplicate_approximate_paragraphs 起首插入 caption 精确去重 5 → 0
D21 复合 hyphen 链 wrap 误吞(Reasoning-acting- interacting (?<![a-zA-Z]-) 守护 + (?<=[a-z])-\\s+(?=[a-z]{2}) 收尾 actinginteracting 1 → 0
D22 Latin-1 重音字符 mojibake(íí D13 之前 10 类 Latin-1 mojibake 映射 RodrÃguez 1 → 0
D23 闭括号前空格((2025 ) (\\S) \\)\\1) 112 → 0
D24 开括号后空格(( 2008),D23 镜像) \\( (\\S)(\\1 3 → 0
D25 list-item label + 句子型 body 误升 heading _detect_heading 编号路径补 [a-z]+\\s+[A-Z][\\w-]+, 信号 + length>50 + no colon 守护 h2 12 → 10(含意外修复一处误升的作者机构 IKERBASQUE

改动文件

  • apps/negentropy-perceives/src/negentropy/perceives/markdown/formatter.py —— 9 条新增排版归一化规则 + 1 处 caption 去重补强
  • apps/negentropy-perceives/src/negentropy/perceives/pipeline/stages/pdf/text_extraction.py —— _is_header_footer + _detect_heading 增 8 条结构识别规则(含 D25)
  • apps/negentropy-perceives/tests/unit/test_formatter_hyphenation.py —— 新增 11 条断字 / 复合链测试
  • apps/negentropy-perceives/tests/unit/test_formatter_unicode_artifacts.py —— 新建文件,17 条 ZWSP / mojibake / 括号空格测试
  • apps/negentropy-perceives/tests/unit/test_formatter_dedupe_table_caption.py —— 新建文件,3 条 caption 去重测试
  • apps/negentropy-perceives/tests/unit/test_text_extraction_structure.py —— 新建文件,27 条运行头 / heading 分级测试(含 D25 5 条)

9 commits(按维度顺序)

  • 1689bd43 R1 D13/D14
  • 60143ae0 R2+R3 D15/D16
  • af1559ed R4 D17/D18
  • 70ebc549 R5 D19/D20
  • 2474f80a R6 D21
  • 17a1c647 R7 D22/D23
  • a7fd5980 R8 D24
  • dcb76932 R9 D25

测试 & 实机验证

  • Unit 全量回归 1625 passed 0 regression(含本轮新增 58 测试,5 条为 D25)
  • 签名跨轮稳定:图 9 / table 87 行 / 13 表头 / inline_math 0 / block_math 0 / code_block 0 维度不变;md_chars 116508 → 113319(-2.7%,全部为噪声清理);h2/h4 误判修正(h2: 15→10 / h4: 13→12)
  • Chrome 实机双 tab 对照(用户常用 Chrome 主 profile):PDF 原文 vs Documents 渲染逐页扫描,封面 / 摘要 / TOC / 章节 / Table 1 / Figures 2-8 / 4.1 list / References 全维度通过
  • 重抽取链路验证:通过 backend POST /knowledge/base/{corpus_id}/documents/{document_id}/refresh_markdown 触发 9 轮端到端重新解析,DB markdown_extract_status 轮询 + GCS asset 上传双确认

已知限制 / 后续候选(非阻塞)

  • D26 候选:4.1 节列表的第 2、3 项 (2. The governance divide ...3. Temporal paradigm shift ...) 仍被吸入紧跟段落正文中(不影响 heading 大纲,但语义结构未完整恢复)。这需要 assembly 层的「numbered prefix mid-paragraph splitting」改动,跨度较大,留待后续单独工作项。

Test plan

  • Unit tests apps/negentropy-perceives/tests/unit/ 全量绿(1625 passed)
  • 量化签名(heading 数 / 图数 / 表行数 / 公式数 / hyphen residue 等)跨 r0 → r9 diff 全部为 0 新增问题
  • Chrome 实机双 tab 视觉对照(首页 / TOC 页 / 含图页 / 含表页 / 含 4.1 list 页 / 末页)
  • 13 维质量矩阵逐维核对清单
  • reviewer: 用其他 unseen 学术 PDF(如 NeurIPS / IEEE 期刊)抽样验证以确认 R10 治理无回归

相关

  • 13 维质量矩阵 + R10 经验沉淀已同步至 pdf-to-markdown-12d-quality-matrix memory
  • 端到端验证范式见 pdf-to-markdown-e2e-verification memory

🤖 Generated with Claude Code

学术 PDF 在 PyMuPDF 文本抽取时会保留排版断字处的软连字符 U+00AD,``" ".join(spans)`` 后形成 ``advance­ ment``(不可见字符 + 空格 + 续接小写词),覆盖 Agentic AI Survey 全文 138 处;image caption / 表格标题抽取路径还会把 U+00AD 归一化为 ASCII 连字符但忽略断字合并,形成反向模式 ``retrofit -ting`` / ``or -chestration`` 11 处。两类残留破坏文本拷贝、全文检索与可读性。

在 ``MarkdownFormatter._apply_typography_fixes`` 既有 ``word- word`` 规则下补入两条互斥的对称规则:① ``­[ \t]*(?=[a-z])`` 清除 U+00AD 及后续空白;② ``(?<=[a-zA-Z]) -(?=[a-z])`` 清除反向 ``word -word`` 模式(同时排除复合词 ``X-Y`` 与 em-dash 风格 ``A - B``);最后兜底 ``replace("­", "")`` 防御任何残留。新增 6 条单测覆盖软连字符 / 反向模式 / em-dash / 复合词 / 大写边界,全部从红到绿;formatter + pdf 全量单测 113 passed 0 regression。

实机回归(doc 616e60d5 Agentic AI Survey 37 页):U+00AD 138 → 0,反向断字 11 → 0,``advancement / framework / orchestration / retrofitting / fundamentally`` 等 130+ 词全部正确合并,签名结构性计数(h1/h2/h3/h4/图/表/公式)无变化。
Springer Nature 等学术期刊的页脚 ``11 Page 2 of 37`` / 反向 ``Page 3 of 37 11`` /
双数字运行页码 ``1 3`` / 作者运行头 ``M. Abou Ali et al.`` 等模式在 PyMuPDF 抽取时
bbox 可能因双栏布局被记到正文区,又因文本长度 < 20 字符无法触发 ``_is_header_footer``
位置启发式的下界,导致每页 2-4 行运行头泄漏为正文(Agentic AI Survey 37 页累计 58
处短段落污染);同时 ``1. A novel dual-paradigm taxonomy We introduce and employ ...``
``Our analysis of the complete corpus reveals three significant patterns:`` 等
"列表项 lead-in 句"被 ``_detect_heading`` 误升级为 ``##`` / ``####`` heading,
破坏文档大纲与 TOC 结构。

修复:在 ``_is_header_footer`` 增 4 类位置无关的期刊运行头识别(Springer ``N Page M of K``
正反向、双数字 ``\d \d``、``Initial. Surname et al.``、``Surname and Surname et al.``);
在 ``_detect_heading`` 编号路径补 3 类句子结构识别(作者代词 ``We/I/Our + 小写动词``、
不定式 ``To <verb>, , and ...``、长正文 ≥ 2 逗号子句),并在非编号路径补对称的
代词 + 多词正文过滤(保留 ``Our Method`` 这类合法短标题)。新增单测 22 条覆盖运行头 /
heading 句子识别 / 合法短标题 / 合法 numbered headings,formatter + pdf + text_extraction
146 passed 0 regression。

实机回归(doc 616e60d5 Agentic AI Survey 37 页 R2 + R3 两轮合并):md 116241 → 115367
(-874 chars,主要为页脚 / 运行头清理);h2 15 → 12 / h4 13 → 12(误升 heading 修复);
"Our analysis..." lead-in 句正确还原为段落;签名结构性计数其它维度稳定。
…D17/D18)

Springer Nature 等期刊在引用 URL 每字符之间注入 U+200B 作为软换行 hint(Agentic
AI Survey References 累计 1304 处),渲染时不可见但破坏文本拷贝 / 全文检索 /
URL 可点击性;PyMuPDF 某些抽取路径会把 em-dash ``—`` (U+2014, UTF-8 ``E2 80 94``)
按 CP1252 解码为 ``â € "`` 三字符再以 UTF-8 重新编码,最终显示为 ``â€"`` 三字符
mojibake(同类问题覆盖 en-dash / 单 / 双引号 / 省略号 6 种符号)。

在 ``MarkdownFormatter._apply_typography_fixes`` 既有 U+00AD 兜底后补两条 Unicode
归一化规则:① 全局 ``replace("​", "")`` 清除零宽空格(保留 U+200D ZWJ 不动以
不破坏 emoji 连写);② 6 模式 mojibake 映射表(em / en dash、单 / 双引号、省略号)
原地替换为正字符。不引入 ftfy 直接依赖(当前 ftfy 仅为 docling 传递依赖,避免
硬绑定)。新增单测 8 条覆盖 URL / 正文 ZWSP / ZWJ 保留 / 6 种 mojibake / 合法符号
保留,formatter + pdf + text_extraction 154 passed 0 regression。

实机回归(doc 616e60d5 R4):md 115367 → 114060(-1307,主要因 1304 ZWSP 剥离);
ZWSP 1304 → 0;mojibake ``â€"``: 1 → 0,``—`` 还原为正常 em-dash;引用 URL 形如
``https://doi.org/10.1145/3593013.3594033`` 干净可点击;签名结构性计数无变化。
PyMuPDF 表格 cell 抽取路径在每行 cell text 间用单空格连接,导致 cell 内跨行断字
``per-\nformance`` 在表格抽取后形成 ``per - formance``(两侧均空格)形态;
Agentic AI Survey 37 页 References / Table cells 累计 80 处,覆盖 ``Scalabil - ity``
``gov - ernance`` ``sym - bolic`` ``Mo - zolevskyi`` 等正文 / 表格 / 专有名词模式。
同时 PyMuPDF 把 ``Table N ...`` caption 抽为正文段、table_extraction 又把同样
caption 内嵌为表头,二者经 assembly 写入 markdown 后形成「caption / caption / table」
三段结构,但 caption 通常少于 15 词被既有 ``_deduplicate_approximate_paragraphs``
长度守卫绕过,覆盖 Table 1/2/3/5/8 共 5 处。

在 ``_apply_typography_fixes`` 既有两条断字规则后补第三条 ``(?<=[a-zA-Z]{2}) - (?=[a-z]{2})``
两侧均空格合并规则;两侧均要求 2+ 字母(避免误吞数学 ``a - b`` 单字母),右侧
要求 ASCII 小写起首(避免误吞 em-dash 风格 ``Section A - Section B``)。
在 ``_deduplicate_approximate_paragraphs`` 主 Jaccard 去重前插入 caption 行
(``Table|Figure|Fig.|Tab.|Algorithm|Algo.`` + 数字)的相邻精确去重,仅当
``kept[-1].strip() == para.strip()`` 时跳过新段,不影响跨段非相邻合法重复
(如 ``Table 5 (continued)`` 出现在不同位置 / 表格之间)。新增单测 7 条覆盖
表格内 / 专有名词 / em-dash / 数学单字母边界 / caption 精确相邻 / 不同 caption 保留 /
非相邻重复保留,formatter + pdf + text_extraction 161 passed 0 regression。

实机回归(doc 616e60d5 R5):md 114060 → 113448(-612);两侧空格 ``word - word``
80 → 0;Table caption 紧邻重复 5 → 0;签名结构性计数其它维度稳定。
PyMuPDF 在复合链 ``Reasoning-acting-\ninteracting taxonomy`` 处行折叠后产物
``Reasoning-acting- interacting``,会被既有 ``([a-z])- ([a-z])`` 合并规则
误命中 ``g- i``,错误地把后半并入前段得到 ``actinginteracting`` 视觉破坏 ——
学术 React 类框架的「reasoning-acting-interacting」三段命名被砸成单词。

为既有合并规则补 ``(?<![a-zA-Z]-)`` 复合链守护:前置 2 字符若已是 ``<letter>-``
(即当前位置已在 hyphen 链中),跳过合并;再补一条 ``(?<=[a-z])-\s+(?=[a-z]{2})``
wrap 收尾规则收紧守护后残留的 ``acting- interacting`` 多余空格,恢复
``Reasoning-acting-interacting`` 三段语义。新规则与 ``LLM-based``(大写边界)/
``30-50``(数字)/ ``a - b``(单字母 / 两侧空格)/ ``state-of-the-art``(无空格
复合)全部互斥。新增单测 2 条覆盖复合链 wrap 与多次断字混合,formatter 70 passed
0 regression。

实机回归(doc 616e60d5 R6):md 113448 → 113449(基本持平 / 单合并字符差);
``actinginteracting`` 1 → 0;``Reasoning-acting-interacting`` 0 → 1;
合法 hyphen 链 ``state-of-the-art`` ``belief-desire-intention``
``perceive-plan-act-reflect`` 等 23 条三段及以上复合保留稳定。
…/D23)

PDF 抽取中 Latin-1 重音字符 ``í / é / á / ó / ú / ñ / ü / ö / ä / ç`` 的 UTF-8
(如 ``í`` = ``\\xc3\\xad``)被 CP1252 解为 ``Ã + U+00AD`` 再以 UTF-8 重新编码
为 4 字节序列;与 D18 的 em-dash 类(3 字节)不同 —— D22 的尾字节是 ``\\xad``
即 U+00AD soft hyphen,必须在 D13 ``­[ \\t]*(?=[a-z])`` 合并规则**之前**完成
还原,否则 ``Ã + ­ + guez`` 的 U+00AD 被先剥离后只剩孤立 ``Ã``(Rodríguez 退化
为 RodrÃguez)。同时学术 PDF 中 ``(2025\\n)`` 经 PyMuPDF 折叠后形成 ``(2025 )``
等 ``)`` 前空格,Agentic AI Survey 表格 / References / 正文累计 112 处。

在 ``_apply_typography_fixes`` 起首(D22)插入 10 类 Latin-1 重音字符 mojibake
映射表,置于 D13 U+00AD 处理之前;在 D18 em-dash 映射后插入 D23 ``(\\S) \\)``
→ ``\\1)`` 单空格归一规则(前置非空白保护,避免破坏空括号 ``(  )`` 的合法
噪声 —— 极少见)。新增单测 7 条覆盖 í/é/ñ Latin-1 mojibake / Mojibake 不影响
合法 em-dash / 年份 / 词语前闭括号空格 / 已正确括号保留 / 引号内括号保留,
formatter + pdf + text_extraction 170 passed 0 regression。

实机回归(doc 616e60d5 R7):md 113448 → 113328(-120 chars,主要为 112×1
char 的闭括号空格 + 1 字节 Mojibake 还原);``(2025 )`` 112 → 0;任意 ``\\S )``
0;``RodrÃguez`` 1 → 0,``Rodríguez`` 正确显示;非 ASCII 重音字符
``í=1, á=3, ó=4`` 真实出现。
D23 仅治理了 ``(2025 )`` 闭括号前空格,但 PDF 中 ``Harden (\\n2008)`` 折叠后还会
形成 ``Harden ( 2008)`` 开括号后空格(D23 镜像)。Agentic AI Survey 累计 3 处
(Kaelbling 1998 / Laird 2022 / Thomas-Harden 2008 引用)。在 D23 紧后插入
``\\( (\\S)`` → ``(\\1`` 单空格归一,前置非空白保护与 D23 同理。新增单测 2 条
覆盖年份开括号空格与正常括号保留。

实机回归(doc 616e60d5 R8):md 113328 → 113325(-3 chars);``( YYYY``
3 → 0;至此所有 8 类典型 unicode / 排版残留维度(D13/D14/D17/D18/D19/D20/
D22/D23/D24 共 9 维)累计归零,结构性签名稳定。
PR #692 已知非阻塞限制:Agentic AI Survey 第 16 页 4.1 节 lead-in 句
``Our analysis ... reveals three significant patterns:`` 后的 3 项编号列表,
第 1 项 ``1. Paradigm specialization by domain High-stakes, regulated domains
like Healthcare`` 被 PyMuPDF 折叠到同一文本块,又因 ``^\\d+\\.`` 前缀 + 较大
max_font_size 被 ``_detect_heading`` 升级为 ``## ``,破坏文档大纲。R10 已有
12 条编号 heading 过滤规则均未命中(长度 81 < 100;body 无作者代词;非不定式;
仅 1 个 ``, ``)。

新增 D25 规则识别该 case 特征指纹 ``[a-z]+\\s+[A-Z][\\w-]+,`` —— 小写词 + 空格 +
Capital 起首词(可含 hyphen)+ 逗号;学术 heading 内 Capital 词后接逗号几乎不出现
(合法 heading 的 Capital 复合词 ``Reinforcement Learning Models`` 后无逗号),
该组合是 PyMuPDF 折叠 ``\\d+. **Label** Body sentence,...`` 的高置信信号。
守护:长度 > 50 + 不含 ``:``(合法 heading subtitle 分隔符放行)。

新增单测 5 条:① 目标 case 红→绿;② 合法 Capital 复合词 ``Deep Learning Models for
Reinforcement Learning Applications`` 保留;③ 含 colon subtitle ``Findings:
a paradigm-aware analysis`` 保留;④ 短编号 heading(length < 50)保留;
⑤ 含 hyphen 但无逗号的 ``Cross-functional analysis`` 保留。formatter + pdf +
text_extraction 177 passed,全量 unit 1625 passed 0 regression。

实机回归(doc 616e60d5 R9):md 113325 → 113319(-6 chars);
``## 1. Paradigm specialization`` h2 1 → 0;意外收益修复另一处误升 ``## 4 IKERBASQUE,
Basque Foundation for Science, Bilbao, Spain`` 作者机构行(同样命中 lowercase+Capital
+comma 信号,本身就是误升的页脚 affiliation,降为段落后 IKERBASQUE 信息完整保留)。
h2 12 → 10,h3/h4/h1/图/表/公式签名其它维度稳定。
@ThreeFish-AI ThreeFish-AI changed the title fix(perceives): PDF→Markdown 1:1 还原 R10 — Agentic AI Survey 12 维新失真治理(D13-D24) fix(perceives): PDF→Markdown 1:1 还原 R10 — Agentic AI Survey 13 维新失真治理(D13-D25) May 28, 2026
依据 Review 反馈对 R10 系列做三处守护精化,降低对正文与合法 heading 的副作用:

- D19 两侧空格断字合并:引入 ``_EM_DASH_RHS_CONNECTORS`` 与
  ``_EM_DASH_RHS_LATIN_ABBR`` 守护词表,右侧若是 ``or`` / ``and`` /
  ``which`` / ``i.e.`` 等 em-dash 连接词则保留 ` - ` 原貌,避免误吞
  ``data - or what was left - was deleted`` 这类正文 em-dash。
- D21 复合链 wrap 收尾:``\s+`` 收窄为 ``[ \t]+``,防止 ``\n\n`` 被吞掉
  从而跨段落合并、破坏 markdown 段落结构。
- D16 heading 句子型过滤:拆分 ``\b(We|I|Our)\s+[a-z]`` —— ``We`` /
  ``Our`` 走通用守护,单字母 ``I`` 仅当后接 ``propose`` / ``introduce`` /
  ``argue`` 等学术叙述动词时才过滤,避免误伤 ``Phase I improvements`` /
  ``Type I errors`` 等含罗马数字 I 的合法 heading。

新增 12 个回归用例覆盖:em-dash 连接词 / 拉丁缩写 / 代词保留、wrap 不跨段、
罗马数字 I heading 保留、学术第一人称叙述过滤。全部 82 个相关用例通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI
ThreeFish-AI merged commit 3e60142 into feature/1.x.x May 28, 2026
10 checks passed
@ThreeFish-AI
ThreeFish-AI deleted the ThreeFish-AI/pdf-markdown-fidelity-restore branch May 28, 2026 05:59
ThreeFish-AI added a commit that referenced this pull request Sep 6, 2026
* build(deps): travel-agent-ui 升级 next 16.2.12 并补齐 workspace 隔离声明,修复 9 项 alert;

- next / eslint-config-next 16.2.6 → 16.2.12,核销 Dependabot #574-582:
  SSRF(GHSA-89xv-2m56-2m9x / GHSA-p9j2-gv94-2wf4)、中间件绕过(GHSA-6gpp-xcg3-4w24)、
  Server Actions DoS(GHSA-m99w-x7hq-7vfj)等 9 条;修复门槛为 16.2.11,取 16.2 线
  最新补丁 16.2.12 以多带一版累积修复,不跨 minor 避免无关框架行为变更
- 补齐 `packages: []` 的 pnpm-workspace.yaml——本工程已从根 workspace 解耦但缺失隔离
  声明,是 ISSUE-175 所列同款入口中全仓最后一个敞口。本次恰好改动其 manifest,正是
  事故链第一环(改嵌套 manifest → 顺手 install → 根 lockfile 静默被覆写),故一并钉死
- 本工程无 lockfile、不被任何 workflow 构建,改 manifest 即生效:本批未执行任何
  pnpm install/add/update,根 pnpm-lock.yaml sha1 校验前后一致(06e898b1,13098 行)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* build(deps): 根 workspace 三 importer 升级 next 16.2.12 + faker 10,修复 28 项 alert;

- next / eslint-config-next 16.2.6 → 16.2.12(negentropy-ui / negentropy-wiki /
  cognizes-ui):核销 #583-591 / #592-600 / #565-573 共 27 条,覆盖 SSRF、中间件绕过、
  Server Actions DoS、缓存混淆、Image Optimization DoS 等;修复门槛 16.2.11,取 16.2 线
  最新补丁多带一版累积修复
- @faker-js/faker ^9.0.0 → ^10.5.0(实解 10.6.0),核销 #687GHSA-qxc2-j82w-r537,
  helpers.fake 可被利用为任意代码执行,<=10.4.0 全线受影响故 9.9.0 亦在范围内)。
  跨大版本但唯一调用点 tests/ui/helpers/factory.ts 仅用 string.uuid / person.fullName /
  helpers.arrayElement / date.* / number.int / lorem.*,与 v10 移除清单零交集
- lockfile 完整性核对(ISSUE-175 教训):overrides 块 17 条全在、importers 5 个不变、
  next 两条 @babel/core peer 变体链(7.29.7 / 8.0.1)均保留、`@babel/core` override
  上界 `>=7.29.6 <8.0.0` 未放宽;净减 70 行系 @babel/core 获得 (supports-color) peer
  后缀导致的键合并,非依赖丢失;`pnpm install --frozen-lockfile` 通过

验证:cognizes-ui lint 0 error + tsc --noEmit 通过 + test:coverage 28 passed(含
faker 三个消费测试)+ build 通过;negentropy-ui lint(--max-warnings=0)+ typecheck +
build 通过;negentropy-wiki lint 0 error + build(含 pagefind 索引)通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* build(deps): cognizes 九包定向升级消 47 项 alert,新增四条传递依赖地板;

- 直接依赖抬地板:pypdf 6.13.3→6.17.0(10 条 DoS/无限循环/内存耗尽)、
  pillow 12.2.0→12.3.0(13 条堆越界写/解压炸弹/命令注入)
- gpu 组抬地板:transformers 5.8.1→5.16.1(CVE-2026-9856 save_pretrained 路径穿越)、
  torch 2.12.0→2.14.0(CVE-2025-3000 torch.jit.script 内存破坏)。无上界阻断:
  sentence-transformers 5.5.0 仅要求 transformers<6.0.0 且不约束 torch
- constraint 抬升 cryptography 49.0.0→50.0.1(GHSA-g6cj-pr64-35w5 Bleichenbacher oracle)
- constraint 新增四条传递依赖地板:gitpython 3.1.50→3.1.61(18 条 git option/配置注入
  RCE 与任意文件读写;travel-agent-demo → streamlit 传递,本仓零 `import git`)、
  pyasn1 0.6.3→0.6.4(3 条 BER/CER/DER 解码器 DoS)、httplib2 0.31.2→0.32.0
  (解压炸弹 DoS)、setuptools 81.0.0→84.0.0(CVE-2026-59890 MANIFEST.in 绕过)
- 定向升级(--upgrade-package ×9)而非全量 --upgrade:lock 仅动 435 行且 docs 组
  零位移(mkdocs/pymdown 变更 0 行),保持可 review 与可归因

验证:ruff check/format 通过(207 文件);pytest tests/unittests/ 225 passed 2 skipped、
覆盖率 30.98% 过 20% 门;uv build + import cognizes 通过;六包运行时版本实测达标。
integration 套件 13 failed/110 passed —— 已用 git stash 在同一环境对拍确认与本次改动
无关(干净树同为 13 failed/110 passed,根因是 TracingManager.span 属性缺失与
tests/integration/mind 下 test_e2e.py 同名 basename 收集冲突,均为既存问题)。

已知验证边界:transformers/torch 的一手调用在 engine/perception/reranker.py,该模块
无单测。已尽力覆盖到 API 契约层——模块本身导入通过,且逐项验证 rerank() 实际调用的
AutoTokenizer/AutoModelForSequenceClassification.from_pretrained、tokenizer 四个 kwargs
(padding/truncation/max_length/return_tensors)、SequenceClassifierOutput.logits 路径与
torch.no_grad/sigmoid 在 5.16.1 下均存在;未验证真实模型推理(需下载 bge-reranker-base)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* build(deps): 删除 cognizes 死配置 docs 依赖组,从根消除 3 项 alert;

- 移除 [dependency-groups] docs(mkdocs / mkdocs-material / mkdocstrings),核销
  #692(mkdocs-material DOM XSS)与 #618/#663(pymdown-extensions 路径穿越 + ReDoS)
- 判定为死配置的三项证据:① 全仓零 mkdocs.yml;② CI 从不安装该组
  (setup-python-uv 仅 `uv sync --group dev`),亦无任何 workflow/脚本引用;
  ③ src/ + tests/ + scripts/ 零 mkdocs 引用。项目文档站实为 negentropy-wiki(Docusaurus)
- 相较升版本,删组从根消除这两个包及其 12 个传递依赖,同类告警不再复发
- lock 为纯删除(-215 行、0 插入),移除项全部属 mkdocs 依赖闭包,无其它包位移

验证:uv sync --frozen --group dev 通过;import cognizes 通过;
pytest tests/unittests/ 225 passed 2 skipped——与删组前逐项一致,佐证该组无运行时作用。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* build(deps): negentropy 四包定向升级消 8 项 alert,补 setuptools 传递依赖地板;

- override 抬升 aiohttp 3.14.1→3.14.3:新增修复 GHSA-cq5v-8q36-5273(C 响应解析器
  堆越界读)与 GHSA-mfx4-hv73-q22v / GHSA-mq44-7p77-q5h7(WebSocket 请求走私/未协商
  压缩帧),核销 #641/#643/#645。override 机制不变:microsandbox==0.1.8 锁死 <3.11.0
  仍需强制覆盖,只抬地板版本
- constraint 抬升 cryptography 49.0.0→50.0.1:GHSA-g6cj-pr64-35w5(PKCS#7
  EnvelopedData 解密暴露 Bleichenbacher oracle,high),核销 #648。全仓零一手 import
  (authlib/google-auth/joserfc/presidio/pyjwt/pyopenssl 传递),且 perceives 已在
  50.0.1 上验证过同构依赖者集合
- constraint 抬升 pyasn1 0.6.3→0.6.4:BER/CER/DER 解码器 3 条 DoS
  (GHSA-m4p7-r5rc-7g4j / GHSA-hm4w-wwcw-mr6r / GHSA-8ppf-4f7h-5ppj),核销 #559/#560/#626
- constraint 新增 setuptools>=83.0.0(82.0.1→84.0.0):CVE-2026-59890(MANIFEST.in
  排除规则被 Unicode 归一化绕过),核销 #558。此前无任何声明,经 spacy/thinc 传递
- 定向升级:lock 仅动 6 行;pyopenssl 26.3.0→26.4.0 随 cryptography 联动

验证:alembic 单 head(0099);pytest tests/unit_tests/ 2941 passed、覆盖率 57.04%
过 50% 门;四包 import smoke 版本达标。integration 套件本地 116 failed/115 passed/
90 errors——已对拍干净树基线逐项一致(共享 negentropy_test 累积脏数据所致的既存
环境问题,见记忆 test-db-accumulates;CI 每次起新容器不受影响),与本次改动无关。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* build(deps): negentropy mcp 1.26.0→1.29.1,修复 3 项 http-transport alert;

- mcp 地板 >=1.6.0 → >=1.28.1,<2.0.0:核销 #501/#503/#505CVE-2026-52869/52870/
  59950,MCP SDK http-transport 攻击面)。上界 <2.0.0:2.x 拆出 mcp-types/truststore
  属未验证 major 迁移(uv 默认解 2.1.1,已退回 1.x 线);alert 门槛 1.28.1,perceives
  实跑 1.28.1,本批实解 1.29.1(1.x 线最新)。idna 3.16→3.19 随 mcp 子树联动
- 一手调用面 3 处(interface/mcp_client.py 三种传输、knowledge/mcp_server.py 的
  FastMCP/StreamableHTTPSessionManager/TransportSecuritySettings、engine/sandbox/mcp.py),
  依赖要求逐条核对全部满足,与 aiohttp 完全解耦(mcp 走 httpx)

三层验证(对齐 ISSUE-092 的 CVE-2026-4372 验收范式):
① 符号 + 真实构造——stdio 私有 API 7 符号(mcp_client.py 8 处引用)全在;
FastMCP 四 kwargs(stateless_http/json_response/streamable_http_path/transport_security)
真实构造出 Starlette app;get_kb_mcp() 与 sandbox 构造路径不 mock 直接过
② 定向单测 22 用例(test_mcp_client 5 + test_mcp_client_resources 4 +
test_kb_mcp_server 13)全过;全量单测 2941 passed、覆盖率 57.04% 过门(与升级前逐项一致)
③ 真实 MCP 往返(合入前置)——httpx.ASGITransport 直打 create_kb_mcp_asgi_app():
tools/list 返回 200 且含 kb_search 工具清单;错误 bearer 401 拒绝。覆盖单测完全
mock 掉的 StreamableHTTPSessionManager.run() + stateless 路径(1.28+ 改动最多处)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(perceives): 纠偏 transformers/torch/setuptools 锁定根因,裁剪 6 条失效 ignore 并升级 datasets;

- transformers 锁定根因纠偏(pyproject [tool.uv] 注释):旧述「marker-pdf 1.10.2 /
  surya-ocr 0.17.1 在 5.x 崩(transformers.onnx)」已不成立——marker-pdf 2.0.0 /
  surya-ocr 0.22.1 均已适配 transformers>=5.12.1。真实阻断是二者同时要求 pillow<11,
  与本项目 pillow>=12.3.0(修 8 条图像解析 CVE)直接冲突;perceives 直接解析不可信
  PDF/图片故 Pillow 攻击面可达,而 transformers 零直接 import、仅加载第一方 artifact
  故不可达——升级属负收益交换。mineru 3.0.9 的 transformers<5.0.0 仅 vlm/pipeline
  extra 生效,不构成约束
- 解锁条件迁移:从「等 marker/surya 适配 transformers 5.x」改为「等二者放开
  pillow<11 上界」——跟踪对象不同,否则后来者会困惑「已适配为何仍锁」
- torch CVE-2025-3000 纠偏:upstream fix 2.13.0 已发布(原注释「暂无 fix」过时),
  改述为「有 fix 但受 marker/surya/docling-ibm-models/torchvision 四方联动约束」
- setuptools pin 注释纠偏:原述「undetected-chromedriver 依赖 pkg_resources」已证伪
  ——实测 82.0.1 与 83.0.0 皆无 pkg_resources(上游早于 82 移除,复核 ISSUE-092
  隔离结论)。维持 82.0.1:不为不可达 build-time 低危变更 build 后端版本
- 裁剪 6 条失效 ignore:fastmcp(CVE-2025-64340/CVE-2026-27124)与 litellm
  (CVE-2026-35029/35030、GHSA-69x8-hrgq-fjj8CVE-2026-42271)注释停留在 3.1.1/1.80.0,
  实锁已 3.2.4/1.85.0。实跑 pip-audit 确认两包零命中后删除,非凭版本号推断
- datasets 4.8.5→5.0.1:本次裁剪后暴露的新 advisory CVE-2026-66007(PYSEC-2026-3716,
  folder-based dataset builder 路径穿越任意文件读)。mlx-vlm 仅要求 >=2.19.1 无上界,
  故直接升级而非新增 ignore 债

验证:ignore 数组经 bash -n 语法校验(56 条);以 CI 原样命令复跑 pip-audit
退出 0——「No known vulnerabilities found, 10 ignored」;CI 参数复跑测试
(-n auto -m "not slow")2130 passed,docling/mineru/marker 三引擎 worker 均真实
启动;mlx-vlm 在 datasets 5.0.1 下 import 通过。3 个 test_config 失败已对拍干净树
基线一致(本地 .env 使 concurrent_requests=32≠默认 16,CI 无该文件),与本次无关。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(issue): ISSUE-092 增补 perceives 4 条 dismiss 依据与 transformers 解锁条件迁移;

- 记录 104 条 alert 人工核销的收口:100 条经升级消除,perceives 4 条走 dismiss
- transformers 锁定根因纠偏:marker-pdf 2.0.0 / surya-ocr 0.22.1 已适配
  transformers>=5.12.1(旧「transformers.onnx 崩溃」不再成立),真实阻断是二者
  要求 pillow<11 与本项目 pillow>=12.3.0 冲突;附攻击面可达性对比论证
  (Pillow 可达 vs transformers 不可达)说明升级为负收益交换
- 解锁条件从「等适配 transformers 5.x」迁移为「等放开 pillow<11 上界」,
  避免后来者按旧条件追踪而困惑
- torch CVE-2025-3000 状态迁移留档:upstream fix 2.13.0 已发布,原「暂无 fix」
  记录作废;此例印证本 Issue 既有防范条款「四元注释便于季度 review 识别可移除项」
- 记录本次 ignore 清单 review 结果(62→56 条)与 datasets 升级替代新增 ignore 的处理
- 沉淀三条方法论:「上游已适配≠可升级」须核对全部约束维度、安全债决策应比较
  攻击面可达性而非 CVSS 分数、ignore 注释的「阻断原因」腐化快于 CVE 本身

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(travel-agent-ui): 补 allowBuilds 修复隔离 workspace 下 pnpm install 退出 1;

上一提交把本工程钉成独立 pnpm workspace 根以阻断根 lockfile 覆写,但漏声明
allowBuilds——原生构建许可原本继承自根 workspace,隔离后不再传递。

实测(pnpm 12.2.1,本目录完整 pnpm install):Error: ERR_PNPM_IGNORED_BUILDS,
被拦 @scarf/scarf / esbuild / sharp / unrs-resolver,退出码 1,且 pnpm 会往
pnpm-workspace.yaml 回写 "set this to true or false" 占位;根 pnpm-workspace.yaml
所载的 `cd … && pnpm install && pnpm dev` 因此卡在第一步。

注:作者侧大概率以 --lockfile-only 验证,该模式不执行构建脚本故退出 0,恰好掩盖此失败。

- 补齐四条许可,取值与根 workspace 一致(@scarf/scarf 保持 false,同为隐私考虑)
- 未纳入根侧 msw:本工程不依赖,遵循最小声明
- 注释指向修正:原「运行方式见同目录 README.md」——该 README 为 create-next-app
  原始样板,无 install 步骤亦未提隔离 workspace,改为就地写明安装运行命令

验证:修复后 pnpm install 退出 0、IGNORED_BUILDS 零命中;根 pnpm-lock.yaml 逐字节未变,
隔离目标保持有效;YAML 解析通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(perceives): 同步 pip-audit ignore 注释至纠偏后口径并订正 ISSUE-092 计数;

本分支已论证 transformers 锁定 <5.0.0 的真实阻断是 marker-pdf 2.0.0 / surya 0.22.1
要求 pillow<11,而非旧记的「marker-pdf / docling 兼容交集」;setuptools 保持 82.0.1
的理由亦已由「undetected-chromedriver 依赖 pkg_resources」改写为「已证伪」。但 CI
ignore 清单中的四处注释仍停留在旧口径,与 pyproject、issue.md 相互矛盾。

CVE-2026-9856 条已承载完整根因,其余三处改为指针式引用,避免同一结论多处维护:

- PYSEC-2025-211..218 / CVE-2026-4372 / PYSEC-2026-2290:删除「docling 兼容交集」
  归因,统一指向 CVE-2026-9856 条;CVE-2026-4372 的「待交集支持 5.3.0+ 后升级」
  同步改为「待 marker-pdf / surya 放开 pillow<11 上界」
- PYSEC-2026-3447:交叉引用由「见 pyproject,undetected-chromedriver 相关」改为
  「见 pyproject setuptools 注释与 ISSUE-092 2026-09-06 增补」——照旧文跳转只会
  读到相反结论
- ISSUE-092:「ignore 条目 62→56」订正为 34→28。negentropy-perceives-ci.yml 是
  全仓唯一 --ignore-vuln 来源,实测本分支前 34 条、后 28 条(差值 6 正确,绝对值错位)

纯注释与文档变更,ignore 条目与 pip-audit 行为零改动。验证:YAML 解析通过;
--ignore-vuln 实测 28 条,与订正后的 issue.md 记载一致;注释行宽与既有块保持齐平。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant