Skip to content

fix(fetch): preserve rendered document content - #919

Closed
lanyue-llk wants to merge 21 commits into
mainfrom
codex/fetch-content-audit-main
Closed

lanyue-llk wants to merge 21 commits into
mainfrom
codex/fetch-content-audit-main

Conversation

@lanyue-llk

@lanyue-llk lanyue-llk commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

网页请求成功后,原生 Markdown 导出仍可能丢失实时表单值、媒体候选、公式、复杂表格和可见正文。这组修改把实时 DOM 与计算样式的采样留在浏览器内,并让 Markdown 与保真 HTML 输出共用内容和边界规则。

当前分支已 rebase 到 main 的 d9928760ed2049befd59f5fc0b53d0d3ff74ff95,当前提交为 4f556a687c93fe0c10c445ed0f3350f87209f227。Stylo 精确锁定 1032a2947ec2f7cee1027d07084203be87e17643,该提交已包含 main 使用的 Stylo 基线。

主要修改

  • 浏览器采样表单当前值、资源候选和计算样式,避免用初始属性覆盖实时状态。
  • 共享可读标签、片段链接、媒体、表单和文本边界规则;复杂表格、公式及包含结构的预格式化内容保留必要语义。
  • 从 Stylo 的真实层叠结果取得 visibility 来源和有限动画终态,按原动画槽位组合效果。无法确定的动画状态保留为未知,不重放页面回调。

实现没有站点、题号或评分器特判。原生导出本身负责内容转换,调用者无需先取 JSON 再用外部转换器生成 Markdown。

flowchart LR
  A[实时 DOM 与表单状态] --> C[共享内容与边界规则]
  B[计算样式与可见性来源] --> C
  C --> D[原生 Markdown]
  C --> E[保真 HTML 输出]
Loading

当前验证

macOS 使用仓库固定的 Rust 1.96.1 完成格式检查、全目标全特性 Clippy,以及完整 Nextest:19,889 项通过,17 项按仓库配置跳过。

测试修复包括等待本次导航的加载事件、使用现有 Ahem 字体固定布局预期、固定 HTTP 测试响应的日期,以及迁移 canvas 测试的上下文引用。两项布局测试的全部 120 种组合另经 Chromium 实测验证;这些修复不改变生产浏览器行为。

已发布实测结果与当前代码

公开报告中的 PR919 行绑定以下一次完整运行:

  • Moli 1.1.11
  • 源码提交 721bd2e329f96c06573db6e6b257a149cf17a6fe
  • release 二进制 SHA-256 fac987f54939fab2f5db7bf54af41b25cbb3aed3230528c170b4c22ada0b98ac
  • 545 个逻辑任务,目标正文 545/545

这份 545 页测量仅对应上述历史源码和二进制,不代表当前 4f556a687 的成绩。当前分支基于 main 的 d9928760ed2049befd59f5fc0b53d0d3ff74ff95。

方法 目标正文 综合分 全文 代码 公式 表格内容 表格结构
Moli 1.1.9 原版 543/545 36.41% 41.45% 90.87% 20.29% 17.31% 12.12%
Moli 1.1.9 · PR785 修复版 545/545 36.53% 41.72% 90.80% 20.25% 17.75% 12.11%
Moli 1.1.11 · PR919 721bd2e 实测版 545/545 39.27% 40.73% 91.06% 28.20% 22.62% 13.75%

专项指标公共总体为全文 545、代码 110、公式 257、表格内容与结构各 179。

任务 8798f93a-240c-46d7-a8d1-a5fb011279fc 的人工主内容包含 91 组由页面脚本控制的可展开比赛明细。PR919 实测版没有恢复这些内容,该页代码分为 12.28%。这是真实的评测能力差距;本 PR 没有通过删除参考、解析任意 onclick 或添加任务特判来提高分数。独立 PR #1305 补充调用者明确指定交互后再导出的 CLI 组合能力,复用真实执行与标准导出路径;它不依赖本 PR,也不改变这次默认只读运行的结果。交互采集须单独固定共同操作和任务范围,不能只给 Moli 展开后替换本报告成绩。

相关报告与实现

拆分版本 #1334、#1335、#1336、#1337 分别覆盖这组修改的部分范围;本 PR 保留完整组合。

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审 683b297e1b99b5bbe27284dc8b5e657eaacf8996,结论:仍需修改。本轮主审与 3 个子审将 #919 与 #814 最后审查版本及新增围栏转换前的 1713b0452 对照,确认 6 项问题,见行级评论。

#919 不是原样搬运 #814。以下修复值得保留:font color 进入正常 Stylo presentation hint/CSS 级联,恢复了隐藏白字与 author CSS 覆盖的双向验证;tooltip 空链接、图片 alt 标题、lazy srcset 回退、特殊节点锚点、直接渐变背景与图片误删等旧反例已修正。原有 HTML-to-Markdown 测试 342 个通过;PageVm 原测试和 7 个历史反例也都通过。描述已准确区分继承的 #785,Clippy 已通过,不能沿用上一轮“Clippy 失败、描述仍是旧提交”的结论。

最重要的新问题来自最后两次“使代码可被评分器提取”的改动:

  1. 所有 pre 改成围栏,删除真实导航/下载链接。 预格式化不等同纯代码。正式认证样本仍保留 HOME GAMES/AWAY GAMES、raw 等文字,却完全丢失其 href。
  2. 任意表格含 pre 就整表拆平,丢失行列与跨行关系。 实际源码浏览页的作者/行号/源码三列以及并排行号/源码两列均被拆散。测试把 td 数量从 2 改为 0,并删除表格关系断言,恰好接受了这种退化。
  3. 逐层重新检测深处 pre,导致嵌套表格平方级扫描。 使用稳定的 DOM 查询计数而非时间测量,256 层从基线 67,599 次升为 436,468 次。

最小修正方向是保留语义表格及含真实链接的 pre 的 HTML fallback;明确的 presentation/none 布局表继续沿已有路径展开。没有必要仅为评分器不识别 raw HTML 再增加转换模式或复杂缓存。代码分的提高可以如实记录,但不能据此接受已经证实的信息损失。

另有 3 项残余边界:父容器渐变背景下的白字仍被删;DOM 只读查询甚至注释被当成展开关系;fragment 只做解码匹配,丢掉原始值本应优先命中的目标,导致跳到另一段内容。锚点这一点也补正了前轮审查覆盖不足:保持 DOM ID 原值是必要的,但还必须保留原始 fragment 的优先匹配。

复测证据

  • cargo test -p moli-html2md --offline:原有 342 个测试通过;另加的历史标题/tooltip 2 例通过。
  • 下载链接、语义表格、嵌套表格成本及 2 个历史锚点用例,同一份测试在 1713b0452 为 5/5 通过;当前为 2 通过、3 失败。两边采用独立构建目录。
  • 原始 fragment 与解码 fragment 同时存在、带百分号的 legacy name 两例均失败;期望按 HTML fragment 选择规则 确定。
  • PageVm:8 通过、3 失败,失败为祖先渐变、DOM 只读事件、注释事件。
  • 已核对 PR 所附正式认证报告 对应的本地原始输入/输出:8798f93a…、69ef0461… 确认链接丢失,54aa3595…、647dc2d4… 确认表格关系退化,并非只有合成反例。
  • 当前 CI 的 Format、Clippy 等已通过;Nextest 和 release builds 仍排队。本轮结论来自已完成的源码对照和行为复测,不以排队状态推断通过或失败。

本轮没有把声明不支持的任意 addEventListener 回调静态推断当作缺陷,也没有要求执行回调改变受测页面。需要修正的是实际采取的判定规则和已观测的信息损失。

Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/html_table.rs Outdated
Comment thread moli-html2md/src/anchors.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审最新提交 17372cccac608f7f199b0939f190eb72a30e91f6,由 3 个子 agent 分别审查渲染可见性、结构/导航和真实评测证据。结论:上轮 pre 链接、语义表格与嵌套扫描问题已修复,但当前仍有 5 项可复现问题,建议修复后再合并,详见行内评论。

测试是否到位

现有 342 项 html2md 测试通过;恢复的链接与表格结构断言有价值,不能据此认定同类问题已覆盖。独立场景验证结果:

范围 实测结果 最小补充建议
展开正文 真实冻结页 91 组详情消失;原正例被替换/反转 保留真实正例,与日志、注释、只读访问负例共同运行;检测正文存在而非仅请求成功
可见性 renderer 专项 4 绿、3 红:半透明、阴影、祖先背景遮挡缺口 背景透明度 × 遮挡,以及阴影的少量正反组合;不必穷举 CSS
结构与导航 独立 10 项 7 绿、3 红;pre/表格旧问题已绿 ID/name 冲突、非法 name、普通/fallback 路径保持相同目标语义;MathML 根目标通过但后代 mrow 目标仍丢失,作为同类覆盖缺口补测
图片 2 种 URL × 4 个上下文:无逗号 4 绿、内部逗号 4 红 URL 语法边界与普通/标题/链接/表格输出路径交叉验证
复杂度 32/64/128/256 层 DOM 查询 9,117/18,205/36,381/72,733,已恢复线性 将 DOM 查询增长断言纳入回归;现有文本复制字节计数不能防止重复遍历复发

建议用小型参数化场景矩阵保护“内容、目标身份、URL 与结构关系不丢失”这些稳定契约。红测应基于读者使用场景,修复后同一输入转绿;不要为适配当前实现而换输入或反转原验收。PR 说明的问题分类已经较清楚,但 inline handler 支持说明与当前实现不符,且真实内容损失需要纳入验收结论。

测试在隔离源码快照中执行,没有修改 PR 产品代码。新增 renderer 失败反例验证的是 strip_css=false,未把未执行的 true 模式算作已覆盖。

Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/html_table.rs Outdated
Comment thread moli-html2md/src/media.rs Outdated

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 独立审查问题:回归测试未保护原需求,也未覆盖同类场景

这是本轮第 6 项问题,独立于前面 5 项实现缺陷。当前测试通过不能证明 PR 声称的内容保留能力已验收:展开正文正例被换成 ARIA 或反转为丢弃断言,真实冻结页面 91 组详情消失仍能通过;已有用例又主要验证单一属性和单一输出路径,未保护跨场景的共同语义。

当前提交 17372cc 的独立复测已证明这些缺口实际放过了错误,而非假设性担忧:

  • 可见性:半透明背景、文字阴影、不透明背景遮挡祖先渐变,3 项失败。
  • 导航:ID 优先于 legacy name、非 a 元素 name 无效、MathML 后代目标保留,3 项失败。
  • 媒体:含内部逗号的合法 URL 在正文、标题、链接包裹、表格 4 种上下文全部失败;对应无逗号对照全部通过。
  • 性能:当前 DOM 查询已恢复线性,但正式测试的文本复制量计数无法捕获此前的重复遍历回归。

验收要求:保留原需求正例和对应反例,新增小型参数化场景矩阵;针对上述已复现缺陷,先证明同一用例在当前实现为红,再在修复后转绿。测试应验证正文存在、导航目标正确、URL 完整、结构关系保留等使用契约,不应只断言某个标记存在,也不能为迁就实现更换输入或反转期望。将真实展开页的关键正文断言和深度倍增时的 DOM 查询增长断言纳入回归即可,无需引入庞大的测试框架。

只有修复实现并补入可持续运行的回归保护,才算关闭这项问题;单独修好目前列出的几个样例还不够。

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Spider Bench A/B

✅ All benchmark browser service runs completed; results are informational.

Public HEAD: 184 / 240 rows; 38 / 48 sites produced rows; 10 unexpected empty sites.

✅ Deterministic fixture contract is clean.

Common ancestor d9928760ed20 → HEAD 4f556a687c93; benchmark order: head-first; workflow: success.

Public 48-site run · informational

Metric Base HEAD Δ
Run status success success —
Extracted rows / contract 184 / 240 184 / 240 0 (0.00%)
Contract fill 76.67% 76.67% 0.00 pp (0.00%)
Sites with rows 38 / 48 38 / 48 0 (0.00%)
Sites meeting row contract 36 / 48 36 / 48 0 (0.00%)
Unexpected empty sites 10 10 0 (0.00%)
Partial-row sites 2 2 0 (0.00%)
Site outcomes extracted: 37; HTTP error + rows: 1; empty: 7; HTTP error + empty: 1; snapshot error + empty: 2 extracted: 36; HTTP error + rows: 2; empty: 7; HTTP error + empty: 1; snapshot error + empty: 2 —
Observed duration 48.49 s 44.69 s -3.81 s (-7.85%)
Estimated CPU 50.14 s 46.07 s -4.07 s (-8.11%)
Peak PSS 275.57 MiB 285.66 MiB +10.09 MiB (+3.66%)
Peak RSS 278.83 MiB 288.47 MiB +9.64 MiB (+3.46%)
Peak threads 27 26 -1 (-3.70%)
Mismatched sites 0 0 0
Timeout with items 0 0 0
Category rows Base HEAD Δ
news 35 / 40 35 / 40 0
stocks 20 / 40 20 / 40 0
tech 35 / 40 35 / 40 0
sports 27 / 40 27 / 40 0
games 37 / 40 37 / 40 0
life 30 / 40 30 / 40 0

Public-site content, timing, and memory are noisy. This single A/B run reports evidence only; site outcome counts explain missing rows without treating them as a deterministic regression.

CPU and memory timelines

These are bounded 40-point views of the same complete process-tree samples used by the HTML report. CPU uses 100% per occupied logical core; memory lines are RSS first and PSS second when complete PSS samples are available.

Base

xychart-beta
    title "Base CPU"
    x-axis "Elapsed seconds" [1.041, 1.542, 2.542, 4.045, 5.547, 6.549, 8.052, 9.555, 11.056, 12.057, 13.558, 15.058, 16.059, 17.561, 19.063, 20.063, 21.566, 23.068, 24.57, 25.572, 27.073, 28.575, 29.575, 31.078, 32.579, 33.581, 35.082, 36.583, 37.585, 39.087, 39.588, 40.589, 42.091, 43.091, 44.593, 45.094, 46.095, 47.096]
    y-axis "CPU percent" 0 --> 500
    line [0, 21.95, 118, 135.73, 159.68, 137.73, 161.73, 113.79, 85.88, 69.89, 135.82, 137.94, 133.92, 115.93, 11.99, 19.98, 11.99, 145.84, 131.98, 159.54, 117.92, 135.93, 151.87, 131.81, 135.85, 103.81, 109.91, 19.99, 163.78, 135.83, 121.82, 10, 13.98, 27.98, 109.83, 205.66, 25.96, 139.82]
Loading
xychart-beta
    title "Base memory: RSS then PSS"
    x-axis "Elapsed seconds" [0.04, 1.041, 1.542, 2.542, 4.045, 5.547, 6.549, 8.052, 9.555, 11.056, 12.057, 13.558, 15.058, 16.059, 17.561, 19.063, 20.063, 21.566, 23.068, 24.57, 25.572, 27.073, 28.575, 29.575, 31.078, 32.579, 33.581, 35.082, 36.583, 37.585, 39.087, 39.588, 40.589, 42.091, 43.091, 44.593, 45.094, 46.095, 47.096, 48.491]
    y-axis "Memory MiB" 0 --> 500
    line [12.55, 55.59, 78.31, 116.59, 148.39, 141.77, 178.49, 178.82, 184.63, 202.47, 184.5, 179.02, 178.58, 159.35, 179.6, 148.99, 149.59, 149.49, 179.63, 170.68, 165.48, 263.45, 210.2, 165.7, 179.43, 175.67, 162.18, 161.57, 156.63, 206.73, 254, 278.83, 191.26, 173.5, 180.49, 193.39, 177.05, 157.86, 186.28, 0]
    line [9.52, 52.28, 75.01, 113.33, 145.41, 138.46, 175.59, 175.22, 181.3, 199.22, 181.12, 175.71, 175.21, 155.97, 176.22, 145.61, 146.21, 146.13, 176.25, 167.43, 162.1, 259.66, 206.82, 162.33, 176.44, 172.29, 158.8, 158.21, 153.26, 203.97, 250.62, 275.57, 187.88, 170.12, 177.22, 190.86, 171.14, 154.48, 182.94, 0]
Loading

HEAD

xychart-beta
    title "HEAD CPU"
    x-axis "Elapsed seconds" [1.538, 2.54, 4.043, 5.045, 6.548, 7.549, 9.05, 10.051, 11.553, 12.555, 14.057, 15.059, 16.561, 17.563, 19.066, 20.067, 21.569, 22.571, 24.071, 24.572, 25.072, 26.573, 27.575, 29.077, 30.078, 31.58, 32.582, 34.084, 35.085, 36.587, 37.587, 38.589, 39.089, 40.09, 41.09, 41.591, 42.592, 44.092]
    y-axis "CPU percent" 0 --> 500
    line [71.89, 107.86, 109.81, 139.75, 145.7, 168.04, 153.9, 137.8, 77.95, 69.9, 141.71, 29.98, 101.87, 123.66, 37.96, 75.81, 77.91, 123.8, 98.05, 105.95, 105.91, 137.75, 149.89, 155.79, 107.85, 107.85, 83.87, 17.95, 75.91, 133.85, 8.01, 0, 81.9, 128.01, 205.75, 39.95, 141.81, 197.62]
Loading
xychart-beta
    title "HEAD memory: RSS then PSS"
    x-axis "Elapsed seconds" [0.036, 1.538, 2.54, 4.043, 5.045, 6.548, 7.549, 9.05, 10.051, 11.553, 12.555, 14.057, 15.059, 16.561, 17.563, 19.066, 20.067, 21.569, 22.571, 24.071, 24.572, 25.072, 26.573, 27.575, 29.077, 30.078, 31.58, 32.582, 34.084, 35.085, 36.587, 37.587, 38.589, 39.089, 40.09, 41.09, 41.591, 42.592, 44.092, 44.686]
    y-axis "Memory MiB" 0 --> 500
    line [12.54, 93.23, 127.95, 138.85, 157.5, 187.32, 166.6, 193.09, 178.54, 161.13, 175.26, 190.16, 161.47, 155.53, 182.97, 146.18, 148.66, 179.65, 169.49, 225.18, 288.47, 252.2, 207.61, 159.21, 180.11, 188.18, 154.5, 153.54, 157.33, 177.55, 179.29, 166.14, 150.03, 162.24, 162.91, 163.35, 161.36, 165.5, 208.86, 0]
    line [9.49, 89.86, 123.78, 135.41, 153.91, 183.93, 163.22, 189.7, 175.48, 157.79, 171.88, 186.76, 158.07, 152.13, 179.58, 142.65, 145.26, 176.36, 166.1, 221.76, 285.66, 248.31, 204.21, 155.92, 176.69, 184.78, 151.12, 150.36, 153.93, 173.9, 175.92, 162.75, 146.63, 158.88, 159.55, 160.14, 157.96, 161.08, 205.47, 0]
Loading

Deterministic fixture · required contract

The fixture exercises 15 routes: 8 are expected to emit rows and 7 intentionally exercise empty, loading, or timeout behavior.

Metric Base HEAD Δ
Run status success success —
Extracted rows / contract 40 / 40 40 / 40 0 (0.00%)
Contract fill 100.00% 100.00% 0.00 pp (0.00%)
Sites with rows 8 / 15 8 / 15 0 (0.00%)
Sites meeting row contract 15 / 15 15 / 15 0 (0.00%)
Unexpected empty sites 0 0 0
Partial-row sites 0 0 0
Site outcomes extracted: 7; HTTP error + rows: 1; empty: 3; timeout + empty: 4 extracted: 7; HTTP error + rows: 1; empty: 3; timeout + empty: 4 —
Observed duration 19.87 s 19.88 s +0.01 s (+0.05%)
Estimated CPU 0.42 s 0.46 s +0.04 s (+8.98%)
Peak PSS 66.48 MiB 66.68 MiB +0.21 MiB (+0.31%)
Peak RSS 69.88 MiB 69.95 MiB +0.08 MiB (+0.11%)
Peak threads 18 18 0 (0.00%)
Mismatched sites 0 0 0
Timeout with items 0 0 0

Full HTML, JSON, CSV, logs, and page snapshots: workflow run and full spider-bench-results artifact.

The public-web A/B is informational. The exact HEAD fixture contract runs as a separate required CI check; timing and public-site content deltas remain non-blocking.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Sequential Navigation Soak A/B

⚠️ HEAD did not produce a complete resilience/memory observation: HEAD network_order_violations is not 0.

One browser process, one target, and one CDP session navigate CSDN → SegmentFault → Huaban → example.com repeatedly. This run issued 200 Page.navigate commands per binary.

Common ancestor d9928760ed → HEAD 4f556a687c; benchmark order: head-first; workflow: failure.

Session resilience

Metric Base HEAD
Attempted / planned 200 / 200 200 / 200
Direct observable pass 199 / 200 200 / 200
Failures / recovered 1 / 1 0 / 0
Recovery failures 0 0
Lifecycle order violations 0 0
Network order violations 0 2
Wall time 446.1 s 460.4 s

A public-page failure is reported separately from an unrecoverable session. The soak requires all navigation attempts, zero failed recovery, zero lifecycle/network ordering violations, and complete resource evidence.

Process-tree memory

Metric Base HEAD Δ
Boundary samples 200 200 0
Boundary RSS samples 200 200 0
Boundary PSS samples 200 200 0
Periodic peak RSS 266.2 MiB 265.1 MiB -1.1 MiB
Periodic peak PSS 262.3 MiB 262.9 MiB +0.6 MiB
RSS · first 10 avg 184.7 MiB 165.8 MiB -18.9 MiB
RSS · last 10 avg 182.5 MiB 188.4 MiB +5.9 MiB
RSS · last − first window -2.2 MiB +22.7 MiB +24.9 MiB
RSS · warm slope / 100 nav +6.2 MiB +6.3 MiB +0.1 MiB
PSS · first 10 avg 182.7 MiB 162.7 MiB -20.0 MiB
PSS · last 10 avg 179.0 MiB 186.5 MiB +7.4 MiB
PSS · last − first window -3.7 MiB +23.8 MiB +27.5 MiB
PSS · warm slope / 100 nav +5.2 MiB +6.7 MiB +1.4 MiB
Peak file descriptors 57 64 7
Peak threads 29 31 2

HEAD memory by 50-navigation quarter

HEAD range Avg RSS Final RSS Peak RSS Avg PSS Final PSS Peak FD
1–50 174.6 MiB 162.2 MiB 235.5 MiB 171.8 MiB 159.1 MiB 52
51–100 182.5 MiB 179.4 MiB 233.2 MiB 179.9 MiB 176.0 MiB 53
101–150 186.1 MiB 170.3 MiB 246.6 MiB 182.8 MiB 167.0 MiB 53
151–200 187.2 MiB 182.3 MiB 233.5 MiB 185.2 MiB 180.3 MiB 53

Raw reports and per-navigation boundary samples: workflow run and full sequential-navigation-soak-results artifact.

Public-site timing and memory are observational. Use the A/B deltas and trend shape as evidence, not as a deterministic performance threshold.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

CI Regression Report

Source CI run · source state at render: in_progress · artifacts: 6/6

Check Status Signal
Release regression ✅ HEAD/base failures 0/0; raw binary +0.150316%
Frontend differential ✅ 1,020/1,020 cases matched; 0 issues
Agent episodes ✅ 8/8 Moli episodes passed; 0 failures
Runtime/CDP contracts ✅ 26 contract cases; 0 failures
CDP smoke ✅ 52/52 groups passed; 621 scenarios
WebMainBench ✅ 545/545 completed; 0 unexpected failures
Release regression — ✅ HEAD/base failures 0/0; raw binary +0.150316%

Package and image size

Metric Base HEAD Delta Delta %
Raw binary 148.81 MiB 149.03 MiB +229.05 KiB +0.150316%
Stripped binary 102.46 MiB 102.66 MiB +204.00 KiB +0.194426%
gzip binary 51.06 MiB 51.15 MiB +101.33 KiB +0.193827%
Rootfs 155.71 MiB 155.94 MiB +230.00 KiB +0.144246%
gzip rootfs 59.94 MiB 60.05 MiB +115.70 KiB +0.188504%

Startup latency and PSS

Case Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta
Serve ready 27.61 ms 27.36 ms −0.25 ms 4.56 MiB 4.61 MiB +53.00 KiB
CDP first page 52.93 ms 51.60 ms −1.33 ms 4.81 MiB 4.27 MiB −553.50 KiB
CDP warm page 11.26 ms 12.72 ms +1.47 ms 50.07 MiB 49.57 MiB −514.50 KiB
CLI about:blank 17.28 ms 16.29 ms −0.99 ms 1.75 MiB 2.63 MiB +909.00 KiB
CLI local JS 20.06 ms 19.83 ms −0.22 ms 3.51 MiB 1.60 MiB −1.91 MiB

Concurrency matrix

Concurrency Base p50 HEAD p50 Delta Base PSS HEAD PSS Delta HEAD failures Unstable B/H
1 18.62 ms 18.92 ms +0.31 ms 665.00 KiB 604.00 KiB −61.00 KiB 0 0/0
5 21.80 ms 21.23 ms −0.56 ms 27.36 MiB 13.27 MiB −14.09 MiB 0 0/0
10 20.61 ms 20.77 ms +0.15 ms 13.26 MiB 13.66 MiB +412.00 KiB 0 0/0
25 22.08 ms 21.22 ms −0.86 ms 27.44 MiB 18.20 MiB −9.24 MiB 0 0/0
100 21.80 ms 22.28 ms +0.48 ms 13.65 MiB 23.04 MiB +9.39 MiB 0 0/0
Frontend differential — ✅ 1,020/1,020 cases matched; 0 issues
Match DOM mismatch Diagnostic mismatch Moli error Reference error Infrastructure error Mismatched frames Duration
1,020 0 0 0 0 0 0 7m 14.31s
Agent episodes · Moli vs Chromium — ✅ 8/8 Moli episodes passed; 0 failures
Fast contract Episodes Passed Assertions Ready p50 Episode p50
Moli 8 8 47/47 4.12 ms 27.27 ms
Chromium 8 8 47/47 257.40 ms 91.14 ms
Operation p50 Chromium Moli Delta Delta %
navigate 46.38 ms 6.21 ms −40.17 ms −86.60%
observe 1.59 ms 0.88 ms −0.71 ms −44.74%
fill 2.77 ms 3.66 ms +0.89 ms +31.98%
click 5.63 ms 4.45 ms −1.18 ms −20.98%
Idle-resource episode Peak RSS Peak PSS Average CPU Peak CPU Peak processes Sampler
Moli 65.68 MiB 62.86 MiB 0.78% 10.05% 1 ✅
Chromium 1282.20 MiB 333.37 MiB 2.05% 93.91% 13 ⚠️ PSS partial
Runtime and CDP session contracts — ✅ 26 contract cases; 0 failures
Suite Cases Failures Median case p50 Median case p95 Median peak PSS p50
Synthetic fetch 13 0 18.18 ms 19.31 ms 606.00 KiB
Long-lived CDP session 13 0 17.92 ms 18.81 ms —
CDP smoke — ✅ 52/52 groups passed; 621 scenarios

Workers: 4 · cumulative group time: 178.16 s · failed groups: 0

Slowest group Scenarios Duration Status
scrollbar-visibility 22 21.47 s ✅
target-lifecycle 24 15.84 s ✅
dom-input 27 12.19 s ✅
chromium-cdp 56 12.07 s ✅
multi-page 45 10.38 s ✅
WebMainBench · 545 pages — ✅ 545/545 completed; 0 unexpected failures
Completed Successful Expected DNS failure Unexpected failures Panics Crashes Timeouts Empty output
545/545 544 1 0 0 0 0 0

Frozen HTML · Linux · --wait done · 45 seconds per page · no retries. Content quality is evaluated separately.

Diagnostics: webmainbench-results — every page's Markdown, stderr, and exit status. Source run and artifacts

All artifact fields are parsed by the trusted default-branch renderer; missing or invalid inputs remain visible as unavailable.

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本轮对 17372cccac608f7f199b0939f190eb72a30e91f6 相对 base 80660fb6dc034f97819fac30e1fdbdd79edf49b8 的 27 个变更文件按整体需求和调用链复审,并由 4 个子 agent 分别审查渲染/状态、结构转换、媒体、需求与真实评测证据。

结论:当前 PR 应先收敛局部设计再合并。多次出现的问题确实有共同方案原因,继续按失败样例补条件不足以解决;但不应推倒整份修改。

共同根因与处理决策

根因 已复现证据 最小处理方向
内容选择混合了绘制事实、折叠正文、加载恢复、噪声猜测和摘要替换 实际坐标(0,0)正文被删;旋转动画让隐藏99混进Count 2;根visibility例外泄漏独立隐藏内容;全文被过滤后连摘要也删;disclosure后代丢失。前轮半透明背景/阴影错误仍成立 renderer保留只读adapter;分开确定隐藏、明确保留区域与不确定推断。继承按区域处理,先确定最终保留内容再去重;移除没有可靠依据的局部坐标/任意位移语义猜测
Markdown与HTML fallback是两套语义解释器 只加colspan或fragment引用就丢aria-label、tooltip、状态、SVG title;New/Old粘成NewOld;URL接受规则不同;此前锚点身份冲突属于同类 共用可读内容、边界、目标节点身份、媒体结果等少量helper/context,两路径仅负责各自转义/标记。无需新建庞大IR或重写遍历
真实运行状态与初始属性/猜测metadata没有分清 input.value/checked已变但仍导出初始值;data-original覆盖实际src;文件名含transparent/spacer导致换错图;srcset只取最后token,顺序/非法候选改变结果 状态在浏览器层采样。资源候选统一验证/选择,私有metadata仅作有明确边界的fallback;srcset按语法和descriptor解析,不继续加文件名特判
数学识别与输出语法未形成完整契约 无可见影响的span或注释使TeX payload损坏;美元包裹的纯文本链接/图片语法在普通reader中被激活,base同测试通过 对连续可读文本统一识别,明确数学输出方言,非数学内容正常转义;同时验证普通reader和math reader
性能验收只覆盖局部成本 已修复的表格DOM查询为线性,但新TeX扫描对连续反斜杠为平方级;8KiB约0.39秒,base约0.00057秒,同debug条件 扫描维护状态,避免反复重扫前缀;同时保护DOM访问和字符扫描复杂度,不能只统计文本复制
测试契约不稳定,缺少跨路径/跨状态不变量 原展开正例被替换或反转;342项绿色测试仍接受上述同类错误;真实mcubed的91组详情仍消失 测试不足继续作为独立P2。固定需求正反例与少量变形矩阵,当前同输入红、修复后绿,不能迁就实现改期望

本轮实测与覆盖

新增独立测试共32个函数,25失败、7通过;多个函数包含正反对照,这不是25个独立问题,上表和行内评论按失效机制归并。

  • 结构12项:3绿9红;覆盖普通、简单/复杂/被引用表格、inline code、pre、heading,以及表单、数学、媒体、SVG和布局边界。
  • 媒体5项:1绿4红;20个场景结果6通过14失败。包含来源优先级、候选顺序、非法候选、输出用途与属性转义。正常转义对照通过,不能泛称所有escaping错误。
  • renderer10项:1绿9红;覆盖继承、恢复例外、全文替换、实际几何、ARIA及动态控件。select保留全部选项符合当前契约,未误报;textarea旧状态问题明确为既有缺口。
  • 数学4项:2绿2红,其中性能函数用于观测增长,不以易抖动毫秒阈值判红;另1项可读标签测试证明加入空白/装饰SVG也会使标签消失。
  • 本轮没有重复把已解决的pre链接、语义表格、嵌套扫描问题报为新缺陷。原链接首尾空白问题经base对照为预存,也已排除。

应保留的设计

  • <font color>进入Stylo presentation hint及mutation失效处理,是修正正确的CSS层次,值得保留。
  • 用合法HTML/MathML保留表格、链接、公式结构,方向正确。当前认证中此前受影响的10页表格结构数量已恢复,mcubed导航/public-inbox下载URL也已恢复。
  • 只读DOM adapter、计算样式快照、共享的form/media/mathml helper、迭代遍历机制应保留。
  • 不应为了评分器只读Markdown围栏而拆平表格/丢链接;评分器不读取合法fallback应在评测侧说明并用语义指标校验。

原需求并非全是伪问题:当前base的html2md源码与此前红测基线一致,已移植的59个回归测试曾得到35红24绿。问题出在部分实现用弱信号推断内容,再由多条输出路径各自解释,且验收没有锁住同一语义。

建议按上面边界完成一次集中修正,再整批运行“表示方式变化不改变内容/目标/URL”“透明DOM包装不改变意义”“状态改变能正确反映”“删除不能同时损失原文和替代物”“输入翻倍成本近线性”的验收。不要把本轮失败字符串逐个抄成互不相关特例。PR对inline handler仍宣称已支持,与当前删除实现及测试反转冲突,也必须修正;不能将已知91组正文损失写成需求已完成。

本轮只做审查与隔离测试,没有修改产品代码、提交、push或merge。

Comment thread moli-html2md/src/html_table.rs
Comment thread moli-html2md/src/html_table.rs
Comment thread moli-html2md/src/media.rs Outdated
Comment thread moli-html2md/src/machine.rs
Comment thread moli-html2md/src/writer.rs
Comment thread moli-html2md/src/math.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs
Comment thread moli-html2md/src/form.rs
@lanyue-llk
lanyue-llk force-pushed the codex/fetch-content-audit-main branch from 17372cc to cc233ba Compare September 28, 2026 12:26

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审提交 b7a860600d3518cb10ced04f11c0c73267a94fe8。已同步本地 main 至 468729e7d;PR 共同祖先为 cb56b3b33。新 main 与 PR 改动文件无交集,只读三树检查无冲突,没有据此要求无意义的 rebase。复审覆盖当前28个变更文件、上轮同输入回归和跨路径/状态变形场景,由4个子agent分工核验。19项CI全部成功。

结论:有实质收敛,但还不适合合并。共享helper的方向正确,部分调用顺序、提前返回和恢复规则仍针对旧反例的具体形状;继续逐样例补条件会重复产生同类错误。 本轮把意见按既有问题族更新,不把每个新输入拆成独立小问题。

已修复并可关闭的旧具体问题

  • 半透明背景、文字阴影、不透明背景遮挡渐变、局部离屏坐标误删、aria-hidden货币符号丢失。
  • input/checkbox实时状态;旧tabpanel继承、摘要/全文全丢、根veil直接隐藏子文本等原输入。
  • 普通/HTML路径的多处可读标签、tooltip、SVG title、文字边界和块input;URL接受策略不一致。
  • ID优先级和非a的name误作锚点;逗号URL各上下文;data-original覆盖src、文件名关键词误判、placeholder遮挡data-srcset、降序descriptor和非法descriptor原例。
  • 原连续反斜杠扫描的平方级样例,以及上轮原样数学span/comment与字面链接/图片样例。

块input旧测试不认识新输出的div边界,已修正oracle并确认通过,不能继续报告为实现失败。fa-check纯class猜测无需复制到所有分支:移除没有真实文本/ARIA依据的猜测也是合理修正。

仍需收敛的根因与最小方案

问题族 当前实测 最小完整处理
可读fallback与遍历/转义不一致 Tools容器标签覆盖Save/Delete;标题两个链接只剩One;aria-label中的Markdown被激活 子节点实际输出应参与可读性判定;复用原遍历、capture和writer转义,不取第一个标签直接拼Markdown
数学识别与DOM形状耦合 原整段p测试绿;加前后文或放h2/li/td仍错;新早退丢段落和被引用ID 在连续行内文本层识别数学,保留节点身份、块边界和正常文本转义;不按p/div+整串等于公式特判
渲染事实与恢复猜测仍混合 spin+forwards泄漏隐藏数字;披露路径/区域泄漏兄弟和内部dialog;veil隐藏孙节点泄漏;visibility:hidden普通ARIA目标仍丢 真实状态留在浏览器层;祖先仅用于遍历、展开根恢复、独立隐藏子区域分别处理;目标索引用全体ID。普通top:-2px仍变sup,应取消任意位移到语义的推断
媒体规则尚未统一 data-srcset覆盖有效src;合法data图片被替换;无descriptor候选吞掉后续候选;unsafe最高项抹掉safe项 标准来源优先、私有来源fallback;一个共享parser解析候选,验证后选择,两输出器消费同一结果
目标身份只修优先级,未保留多别名/委托路径 同一a的id和name都被引用时丢name;MathML后代目标仍丢 区分fragment→节点和节点→多个合法名字,委托转换共用目标上下文
复杂度重新回归 普通span深度64/128/256/512查询12,165/40,773/147,141/556,485,上一版近线性;嵌套表也重新平方级;未闭合数学定界符反复扫后缀 基于实际输出或一次后序摘要决定fallback,避免每层重扫;数学采用单次扫描状态,不只优化最近一个反斜杠样例

这些修正不要求重写converter、引入完整中间DOM或庞大IR。继续保留Stylo presentation hint、只读adapter、live state、语义HTML/MathML及共享helper;需要收敛的是helper契约和控制流,而不是helper数量。

[P2] 回归测试契约仍未闭环(独立问题)

正式代码确实新增了4个converter测试,并扩充renderer正例,不应说“没有补测试”。但它们仍主要复刻上轮输入:数学只测整段p,图片只测逗号URL带显式1x和data-original单属性,恢复只覆盖直接子层;没有正式新增DOM查询或字符扫描复杂度断言。测试不足继续独立保留,不能在修好本轮几个字符串后关闭。

最低验收矩阵应固定:

  1. 标签/文字/目标在普通、标题、列表、simple/complex table、pre和委托MathML路径保持语义。
  2. 透明包装和前后普通文本不改变公式;属性文字不变成链接。
  3. 来源类型、候选顺序、有无descriptor、非法高优先级候选共同出现时选择一致。
  4. 展开路径、兄弟、内部独立隐藏区域及多层继承分开验证;动画以实际采样状态为oracle。
  5. DOM访问和字符扫描工作量随输入增长近线性;测试不以本机耗时作CI阈值。

本轮代表性结果:renderer23测试16绿7红,其中移植的16项旧审查测试15绿,唯一旧红为此前已有textarea缺口;新6项组合失败。媒体原20场景17绿3红、原8个逗号上下文全绿、新10场景5绿5红。结构原12项在修正块边界oracle后11绿,仅class猜测差异不强求保留;另有已定位的新内容/身份/复杂度回归。数学原4项全绿,新3项语义矩阵均红,另测得未闭合定界符平方级增长。

原需求与评测边界

  • 当前认证mcubed仍缺91组比赛详情(16,582字符,WINNER=0)。新版已撤回inline-handler支持承诺,不应要求重新引入任意JS字符串猜测;但这项原需求的能力收窄和实际损失需要明确披露,不能称全部展开正文已完成。
  • textarea.value已变Edited仍输出Initial,是此前已有缺口,不能算本次新回归;但当前描述明确写动态textarea验收,应补真实状态支持/验收或如实限定范围。select保留全部选项符合当前契约,不误报。
  • 55.25%可由已披露共同总体/抽取修订和origin补测复算;3,815条修订前后输出哈希不变。不能将评分口径变化当作篡改输出,也不能用分数和CI全绿代替上述语义验收。

测试在隔离快照中执行,未修改产品代码、重写PR分支、push或merge。

Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/machine.rs Outdated
Comment thread moli-html2md/src/anchors.rs
Comment thread moli-html2md/src/media.rs Outdated
Comment thread moli-html2md/src/media.rs
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
@lanyue-llk

Copy link
Copy Markdown
Contributor Author

已在 a9365786b 按共因处理本轮 8 条评论:

  • 文本节点在真实格式边界之间统一缓冲,数学定界符可跨透明 wrapper;删除仅针对 p/div 整段公式的早退,并保留块边界与 fragment 目标。扫描器改为单次前向状态机。
  • fallback 恢复正常逐子节点转换与 writer.text 转义;不会再只取首个后代标签,也不会把属性文本激活成 Markdown 链接。
  • fragment 上下文返回同一节点的全部合法 id/name 别名,委托给 MathML/HTML fallback 前一并物化。
  • 媒体候选统一为标准 srcset → 有效标准 src → 私有 lazy fallback;合法 data image 不再按占位图处理。srcset 末逗号候选、安全过滤和 renderer URL 解析同步修正。
  • 删除依据 animation name/duration/fill-mode 推测 opacity 已恢复的逻辑,只消费实际 computed opacity。
  • disclosure 现在区分隐藏祖先的“仅遍历路径”和目标根的“内容许可”;完整 ID 索引支持 visibility:hidden 目标,目标内独立隐藏子树、dialog 和无关兄弟继续抑制。
  • fallback 检查只在存在候选时扫描;新增深层透明 wrapper 的 DOM 查询增长回归,64→128 层保持线性。

验证:

  • cargo test -p moli-html2md:350 项通过。
  • cargo test -p moli-renderer-v8 markdown_uses_live_visibility_and_preserves_disclosure_content --lib:通过(8461 项按过滤条件未运行)。
  • cargo clippy -p moli-html2md -p moli-renderer-v8 --lib -- -D warnings:通过。
  • cargo clippy -p moli-html2md --all-targets -- -D warnings:通过。

完整仓库门禁交由本提交触发的 CI 执行。

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审版本:e944d066bc12493bc05e737f07c5721d5be32cf6;已同步核对最新 main 468729e7。本轮重新检查 PR #814 → #919 的需求、旧问题矩阵、最新修改与实测产物,按根因归并,不把同一问题的不同输入拆成多条。

结论:转换层已有实质收敛,但仍有需要修正的语义边界与复杂度问题;新增渲染层推断需以实际状态/可靠语义为依据。建议修完以下问题族后再合入。

已确认修复:35 个旧媒体场景全绿;标题/链接/转义、fragment ID/name 优先级、可读子控件、连续文本数学识别及 DOM 查询复杂度均有改善。原 mcubed 缺失的 91 段比赛详情,逐区域与冻结 HTML 比较已 91/91 完整恢复。不要继续沿用这些旧失败结论。

本地执行正式 moli-html2md 单元测试 3/3、regressions 75/75 通过;额外结构矩阵 17 项中 13 通过、4 个失败归并为 MathML 身份和 textarea 状态两类;媒体旧矩阵 35/35 通过,但 4 个非法语法恢复场景失败。数学普通语义矩阵通过,完整扫描工作量计数仍复现平方增长。渲染层 26 项(正式测试 1 + 旧矩阵 22 + 新反例 3)共 19 通过、7 失败:旧矩阵 18 通过/4 失败,新 3 个反例均失败且有实际点击/计算样式对照。具体反例见行内评论。

剩余 8 个产品问题族:JS 展示关系推断、有效动画规则选择、隐藏豁免的继承边界、相对定位误造上下标、textarea 实时值语义、HTML fallback 的 MathML 身份、数学完整扫描复杂度、srcset 非法语法恢复。另列 1 项测试覆盖不足。前三类不应继续靠追加字符串/单层条件修补;也不要求为此实现任意 JavaScript 静态分析器。

方案判断:连续文本缓冲、共享内容读取和实时 DOM 适配是合适方向,不应整体推倒重写。真正需要停止的是让导出器通过源码字符串猜测“脚本会操作哪个对象”和“哪条动画实际生效”;也不要只在某一条序列化路径补语义。最小收敛方案是:

  1. 浏览器层提供实际状态及可靠 disclosure/动画事实,导出层消费事实;若明确支持静态 handler 子集,应拒绝无法证明的分支和对象变换,不继续扩大猜测。
  2. 显式传递可见性来源及豁免边界;移除用相对定位像素偏移猜上下标的逻辑。共享控件当前值规则,区分已知空值与未知状态;委托 MathML 前统一保留原子树被引用的目标。
  3. 数学识别一次遍历并消费结果,避免每次匹配后重扫剩余文本;srcset 使用共同的候选语法解析,URL 解析与资源选择在其后分工。
  4. 将这些不变量交叉组合成验收矩阵:正文/HTML fallback、非空/清空、正例/反例、有效/非法输入混合、完整调用链复杂度。测试覆盖不足是独立整改项,不能用总通过数替代。

证据口径:当前 39.41 分使用修订后的共同分母;3815 条输出的 SHA-256 在评分修订前后完全一致,不能把分数变化误报为产品回归。唯一失败的 soak CI 在下载输入 artifact 时遭遇 ECONNRESET,产品测试尚未开始;它需要重跑,但不作为本轮代码缺陷。

Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-html2md/src/form.rs Outdated
Comment thread moli-html2md/src/html_table.rs
Comment thread moli-html2md/src/writer.rs Outdated
Comment thread moli-html2md/src/media.rs Outdated
Comment thread moli-html2md/src/math.rs Outdated

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审 39c9cb0abf7d78638820f5c79a17416088ab1194;最新 main 已同步至 7f9b8b63。本轮按上一轮全部问题族复测并检查同类边界,以下是收敛结论。

转换层已明显收敛,不建议整体重写。textarea 当前值/清空、MathML 原子树身份、相对定位误造上下标、数学重复扫描,以及上一轮 srcset 非法候选恢复都已修复。结构独立矩阵 20/20、旧媒体 39/39、数学独立测试 4/4 通过;正式 html2md 单元测试 4/4、regressions 78/78 通过。混合数学输入 256→2048 项的完整转换耗时约 124→959 微秒,不再复现此前平方增长。renderer 与 converter 也已真正共用 srcset parser,不能再沿用“两份 parser 各自打补丁”的旧结论。

renderer 31 项中旧 25 个输入及作者正式测试全部通过;5 个新增输入失败,分别为 stylesheet 隐藏的两种上下文、未匹配 media 中的 keyframes、important 覆盖和真实可点击披露。结合媒体,剩余问题按根因收敛为 4 类产品问题(披露能力回退、CSS 属性来源、有效动画条件、合法 srcset 密度)及 1 项独立测试不足。

当前 HEAD 的 19 项 CI 全成功,包括 soak;但通过不等于内容需求全部满足。使用 当前 HEAD 的 CI 产物 定向核查,mcubed 原始需求的 91 段可展开详情再次全部丢失。作者已明确说明撤回脚本推断,PR 也准确区分旧 e944 评分报告与当前 head;这里不是质疑披露,而是原需求仍未完成。删除不可靠静态推断是对的,把真实披露正文的正断言改成负断言不能替代解决方案。

最小收敛方向:保留已正确共享的转换语义;CSS 判定消费样式系统的有效声明、来源和条件结果,避免导出器重新解释原始 CSS;脚本披露保留真实交互验收,研究由浏览器执行后采样或明确的披露关系支持,不恢复字符串猜测;srcset 仅修共享数值校验,并同时验证合法等价写法和非法输入。详细证据、边界及测试不足见行内评论。

结论:暂不建议合入。已修复项应关闭;剩余 CSS 两类问题应在样式事实与导出层边界一次解决,不应继续补页面或字符串特判。

Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-html2md/src/media.rs Outdated
Comment thread moli-html2md/tests/regressions.rs

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审版本:58383bdbae1e399992f30607fb7883dd76f437c2;最新 main 为 7f9b8b63。本轮重新核对上一轮全部问题族,并按语义等价变化补充有限矩阵,不把同一根因的输入变体拆成多条。

已关闭:合法 srcset 浮点写法及其测试缺口,47 个既有媒体验收场景全部通过;结构与表单 20 项、数学 4 项均通过;正式 html2md 单元测试 4 项、regressions 79 项通过。共享 parser 和此前转换层修复方向正确,无需整体重写。

renderer 一次构建执行 36 项:31 通过、5 失败。上一轮 31 项中 30 项通过,剩余单按钮真实披露仍失败;新增成对真实披露正例通过,成对只读假例、变量继承、级联回滚、Shadow DOM 同名动画失败。所有相关点击状态/计算样式前置断言均通过,具体输出已附评论。

剩余收敛为 3 类需修正的产品问题及 1 项独立测试契约问题;另列 1 项 P3 的 srcset 前向兼容恢复缺口,不作为主要合入阻塞。

CSS 有实质改进:当前查询已进入样式引擎,enabled/media/supports 过滤得到修复,不能把它说成单纯搬动旧代码。但“命中的规则存在”仍不等于“最终级联来源”,也不等于“某个元素适用的动画”。应复用引擎已有的变量替换、级联回滚和按元素查询规则,避免在新接口中重新实现不完整的 CSS 决策。

披露识别则仍是结构和字符串启发式:相邻、成对、+/−或英文标签、onclick 中出现同一带引号 ID,均不能证明点击会展开该节点。它覆盖了原页面的外形,但没有建立可靠的披露语义。默认只读导出应消费明确关系或已知状态;需要采集脚本展开内容时,应在明确受控的交互采集层完成,并保留原需求的独立正例,不能靠更多标签或源码字符串特判闭环。

本轮不重复质疑评分报告:PR 已准确标明报告是旧 e944 基线。当前 CI 仍在运行,不能沿用上一版全绿结论,也不将等待中的检查算作代码缺陷。

结论:暂不建议合入。转换层已收敛;渲染层应停止用局部规则近似披露和 CSS 语义,按上述三个共同边界处理,再复跑同一组正反例,不继续按页面外形追加条件。

Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/style_engine/computed.rs Outdated
Comment thread moli-renderer-v8/src/style_engine/mod.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs Outdated
Comment thread moli-html2md/src/media.rs Outdated

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审 7060a0b35b01866f4b076714405a62d8a390aeb3,最新 main 为 7f9b8b63。

已修复并关闭:srcset 数值、非法候选及 w+h 前向兼容问题,旧 48 场景、descriptor 40 种组合及跨输出路径 8 场景全部通过;结构 20 项、数学 4 项通过;正式 html2md 单元测试 4 项、regressions 80 项通过。转换层已收敛,不建议继续扩大重构。

披露按明确的只读契约评估:不执行页面任意 handler、初始不导出没有明确关系的隐藏内容,是合理边界。正式测试现已真实点击展开/收起,并核对 DOM 状态及 Markdown 变化;此前缺少真实行为验证的问题可关闭。当前 HEAD 的 mcubed 默认折叠详情仍未展开,但这是已公开的能力边界,不再作为同一阻断缺陷,更不要求恢复字符串猜测。PR 仍准确标明 e944 为旧评分基线。

renderer 定向矩阵 39 项:旧 36 项全部通过(两个 JS 正例按明确只读契约验证点击前隐藏、点击后出现),新增 3 项失败,分别为有效变量隐藏、动画 layer 优先级、同一动画重复终点。相关 computed 样式前置断言均通过。三个失败归并为两个 CSS 根因;另有已测量的复制开销和独立测试缺口,共发布四条评论。

剩余重点是原有的 CSS 来源和动画选择两个共同边界,以及本次新增的按节点重复复制动画集合。前两者应从引擎实际解析/选择结果收口,不能把 var() 一律算继承,或继续在作用域分桶后按文本顺序决定动画。复制问题只需共享每个 scope 的数据,无需引入复杂架构。

本轮用当前 page_dump.rs 的映射展开代码做了独立分配测量:128/256/512/1024 个元素与同数量动画名,分配次数为 16,513/65,793/262,657/1,049,601,累计分配字节约 1.15/4.55/18.15/72.48 MB。这是该代码块的隔离测量,不是整页峰值内存;其 O(元素数×动画数) 的深复制由源码直接确认,且无动画的节点也走此路径。

当前 CI 的 Clippy、Nextest、WebMainBench 及已完成 smoke 检查通过;部分长任务仍排队,不将排队算作失败,也不声称全部 CI 已完成。结论:暂不建议合入,先修正上述共同边界并复跑相同矩阵。

Comment thread moli-renderer-v8/src/style_engine/computed.rs Outdated
Comment thread moli-renderer-v8/src/style_engine/mod.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_dump.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审基于当前 HEAD 7048d1b。已同步最新 main,并行核查需求、方案、Stylo 依赖、可见性、内容结构/媒体和测试证据。本轮收敛为 2 个功能根因 + 1 个独立测试覆盖问题,具体复现和修复方向见行内意见。

方案判断:这次有实质性的根因修复,不能再把整体方案称为纯粹补丁堆叠。visibility 来源已交给实际 cascade(变量替换/revert 后);关键帧终态复用引擎解析与计算、scope/layer/重复 offset 语义;整套作用域动画名称按节点复制的性能问题也已移除,并加入查询规模约束。上述旧问题关闭,不重复报告。剩余共同问题在 Moli 与引擎的接口:仍把结构化、有序的动画效果降成字符串列表和正 opacity 名称集合,丢掉了位置、转义与覆盖关系。最小完整修复应集中在这一接口,使用有序结构化效果,最后只向提取层提供最终 opacity 判定;无需另写 CSS 规则重放或完整动画播放器。

需求范围核对:可见正文/隐藏内容、只读披露内容与实际交互后的状态、表单当前值、数学/上下标、链接/图片/媒体转换分别检查;已接受的只读 dump 行为不再作为遗漏任意 JS 内容的问题提出。未发现这些其余路径的新可复现缺陷。

验证:精确 HEAD 的实际 PageVm→Markdown 定向测试 44 项,41 通过、3 失败;其中旧 39 项全部通过,新增动态 visibility 与关键帧变量/underlying 测试通过,3 个红测归并为上述两个功能根因。转换层正式及独立测试共 119 个测试函数通过(含 96 个媒体参数场景)。锁定依赖一致,Stylo CI 通过;当前 PR 20 项检查均通过。CDP 首次 iframe-input 超时,仅复跑失败 job 后同一 HEAD release 产物 50/50 通过,不作为确定回归:https://github.com/lexmount/moli/actions/runs/36589786706/job/109715212432 。

建议修复上述两处调用语义并补齐第三项场景矩阵后再合入。此次没有修改或提交产品代码;这是审查结论,不是修复完成声明。

Comment thread moli-renderer-v8/src/runtime/page_dump/visibility.rs Outdated
Comment thread moli-renderer-v8/src/style_engine/computed.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审基于当前 HEAD d2a83a08433c02642a395b969c1fa7eb20d16707,已同步最新 main,四路并行复核实现、测试、接口及非动画路径。结论收敛为 1 个动画终态分类根因 + 1 个独立测试覆盖问题,详见两条行内意见。

上轮意见处理:none 槽位、转义动画名、显式 opacity 0/1 的覆盖顺序已修复;正式矩阵补齐首/中/尾槽位、长属性循环、纯 transform、strip_css 双模式,旧 44 项独立复测全部通过。旧三条意见在其报告范围内关闭,不重复计算。变量/cascade 来源、layer/scope/重复终点及按实际动画查询的规模约束亦保持通过。

剩余根因:有序列表是正确方向,但目前把每个动画终态独立求成数值后覆盖,或因不满足 forwards 条件直接当成未知,未完整区分中性终点和结束后撤销的效果。因此“先淡入,后接缺省 opacity 终点”与“先淡入,后接有限且无 forward fill 的动画”仍遗漏正文。不是要重写整个方案,也不是需要完整动画播放器;应在现有 Stylo 终点接口保留 opacity 效果来源,由调用层累积这一个属性的值及已知状态。不能继续在 dump 层添加某种 keyframe 文本的特判。现有引擎内部采用同样底值不能证明正确;本轮用真实 Chrome 与规范校正了审查判断。

实测证据:精确 HEAD 的 PageVm→Markdown 47 个定向测试,45 通过、2 失败。2 个红测分别覆盖缺省终点、有限动画 fill none/backwards;均实测 strip_css=false/true,后置时丢正文、顺序互换时正常。Chrome 相同缺省终点及 fill none 夹具在调用所有动画 finish() 后,两种顺序 opacity 均为1;单独缺省终点及显式隐藏终点为0,排除了“所有动画都恢复”的错误预期。新增 paused/infinite 的已知/未知顺序配对通过。

其他范围:PR 问题与方案分类已清晰;增量只涉及7个 renderer 文件。字段位置、节点标识及 clone/strip 路径无新错配。转换层源码/正式测试/依赖与上一版逐字节一致,沿用上一轮119项通过证据,本轮未重复编译该层。当前 CI Format、Clippy、Nextest、SecTrust、Windows 与 harness 检查已通过,release 构建仍运行,不能称整套 CI 已完成;没有重复触发全量工作流。

建议修复上述终态分类,并以浏览器/规范为预期补齐对应正反例后再合入。此次仅审查与隔离测试,没有修改、提交或推送产品代码。

Comment thread moli-renderer-v8/src/style_engine/computed.rs Outdated
Comment thread moli-renderer-v8/src/runtime/page_vm/tests/markdown_dump.rs Outdated

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审范围:当前 HEAD fccd8d88311bc4fad06a6a203530725513446fde,对比上一轮 d2a83a084,并核对当前 main;四路并行审查实际实现、依赖增量、测试契约与非动画路径。

结论:本轮未发现新的可复现代码缺陷或需要阻断的测试覆盖缺口;上轮功能问题与相应测试意见可关闭。

验证:精确 HEAD 的 PageVm→Markdown 定向测试48项全部通过,旧47项(包括上一轮两个红测)全部转绿/保持通过。新增CSS-wide对照矩阵含36场景,覆盖revert/revert-layer/inherit/initial/unset、变量回退、无效变量、缺省终点与显式0/1,并组合单独运行及前后顺序;strip_css两模式共72条结果全部匹配真实Chrome。正式测试也已纳入中性终点、结束后无效果、paused/infinite正反例,未删旧断言换取通过。

方案判断:上轮问题已在合适的边界修复。Stylo 保留 NoEffect / Underlying / Replace / Unknown,Moli 按结构化动画列表和原始槽位组合 opacity;缺省终点不再固化为元素底值,有限且结束后不保留效果的动画不再抹掉下层结果。无需重写整个方案,也没有依据再要求增加另一套 CSS 解释器。

审查中特别核对了 CSS 全局关键字:revert 与缺省终点不同,动画与 author origin 一起回滚,测试中的结果是 Replace(1);revert-layer 留下 author opacity:0,结果是 Replace(0)。实际路径保留声明,经变量替换和原生 cascade 求值,不应把二者一概当作 Underlying。Chrome 对照和规范一致:https://www.w3.org/TR/css-cascade-5/#default 。

其他范围:PR 对问题、根因、各方案与验收的分类清楚。依赖 f3d07e7 的11个锁定包与7个patch一致,metadata --locked --offline通过,Stylo跨平台CI通过。依赖额外包含env(preferred-text-scale)默认1.0,已检查其默认值、有效值约束及Moli调用情况,未发现可成立的缺陷;不能将此次依赖变动描述成仅动画API。转换层源码和测试未变且不依赖Stylo,沿用此前119项通过证据,本轮未重复执行该层。

截至发布:当前HEAD未变化,20项CI中13项已通过(含Format、Clippy、Nextest、两份release构建、545页WebMainBench、CDP/WebDriver smoke),其余7项排队中,无失败。代码审查意见已收敛,尚未完成的CI仍按仓库合入门槛处理;本轮未重复触发全量工作流。

本次只做审查和隔离测试,没有修改、提交或推送产品代码。

Comment thread Cargo.toml Outdated
stylo_dom = { git = "https://github.com/lexmount/stylo", branch = "moli" }
stylo_static_prefs = { git = "https://github.com/lexmount/stylo", branch = "moli" }
stylo_traits = { git = "https://github.com/lexmount/stylo", branch = "moli" }
selectors = { git = "https://github.com/lexmount/stylo", rev = "db0a97a2d2939d621eb0c9d16dd85cb3e22535f5" }

@lanyue-llk lanyue-llk Sep 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

依赖 stylo 的 pr 2 先合入

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