Files
浅念 21ef37232d test(evidence): 阶段2真实WXR冒烟通过
真实 hesupipe WXR(5,490,399B,SHA-256 与 Plan 1 基线一致)跑 wxr:probe 全链:
计数 18 项对照全过(rows 1047 / terms 451 / unsupported 75 细分一致 / failed 0 /
item 总数 1122);heapUsed max 62.2MiB < 100MiB(setInterval(100ms) 双 max 口径,
全程 167ms 仅 2 样本如实注明);parseMs 含流 IO 等待口径注明。
nicename 锚点核对:在表 taxonomy 706/706 全命中(nicename≡slug,违例 0);
category/post_tag 共 807 引用因 wp:term 表缺该 taxonomy 不可解析——阶段 3 需按
(domain, nicename) 自建缺失 term,不能假设 term 表完备。
eslint.config.js:scripts/*.mjs 显式 node 全局(no-undef 误报)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-21 13:25:09 +08:00

9.4 KiB
Raw Permalink Blame History

阶段 2 真实 WXR 冒烟证据(Plan 2 · Task 8)

verdict:PASS(计数对照 18 项全过 + 内存断言通过 + nicename 锚点核对完成)

项 值
日期 2026-10-21
环境 Windows 11 · Node v24.13.0 · pnpm 10.7.1 · tsx 直吃 TS 源码(与 sf CLI 同机制)
输入 D:/project/cms/storage/wxr/fd04d6ba8a1316b6.xml(5,490,399 B ≈ 5.5MB,绝对只读)
输入完整性 SHA-256 f9bc5d4497a1792af37abff78e0096268bda975cb367a956da42bcf9552b9f62 与 Plan 1 基线一致——文件自 Task 0.4 起未变
冒烟脚本 scripts/smoke-real-wxr.mjs(probe 全链 + setInterval(100ms) 内存采样 + 基线断言 + nicename 核对)
证据 run artifacts/probe/20261021T132153-1yft49/(smoke.json / report.json / report.html)
CLI run artifacts/probe/20261021T132302-26azne/(report.json / report.html)

实际执行的命令原文

# 冒烟主路径(仓库根 D:\project\cms-one):probe 同链路 + 内存采样 + 基线断言 + nicename 核对,stdout 出 JSON
pnpm exec tsx scripts/smoke-real-wxr.mjs            # 缺省 --wxr 即 hesupipe 文件;exit 0 = PASS

# 计划钉死的 CLI 命令(Step 1 原文,只读诊断通道直读 cms)——计数与冒烟脚本一致
pnpm sf wxr:probe --wxr "D:/project/cms/storage/wxr/fd04d6ba8a1316b6.xml"

注:smoke 脚本为 .mjs,但 @sf/adapter-wp 经根 tsconfig paths 直连 packages 的 TS 源码,故须 tsx 运行(纯 node 无法解析 workspace TS 包);与 scripts/sf.ts 的 CLI 执行机制(Plan 2 评审钉死)相同。

Step 1 计数对照(实际 vs 基线,逐项)

基线:docs/evidence/real-wxr-baseline.md。断言规则:任何一项不一致都算 FAIL。以下 18 项全部 ok(smoke.json checks 数组原样可查):

对照项 基线 实际 结果
输入字节数 5,490,399 5,490,399 ok
输入 SHA-256 f9bc5d44…b9f62 f9bc5d44…b9f62 ok
totals.rows 1,047(855+129+48+15) 1,047 ok
totals.terms 451 451 ok
totals.unsupported 75 75 ok
totals.failed 0 0 ok
item 总数(rows+unsupported+failed) 1,122 1,122 ok
rows wp:attachment 855 855 ok
rows wp:post 129 129 ok
rows wp:product 48 48 ok
rows wp:page 15 15 ok
unsupported wp:nav_menu_item 68 68 ok
unsupported wp:wpcf7_contact_form 3 3 ok
unsupported wp:elementor_library 2 2 ok
unsupported wp:wp_navigation 2 2 ok
counts 桶键集合(无多余/缺失桶) 上述 8 键 完全一致 ok
probe.fatalError null null ok
内存 heapUsed max < 100MB 65,268,760 B(62.2MiB) ok

计数细分(created=清洗有变化将产新内容 / skipped=无变化,导入前投影语义):

sourceType created skipped unsupported 基线口径
wp:attachment 0 855 0 855 rows
wp:post 87 42 0 129 rows
wp:product 47 1 0 48 rows
wp:page 4 11 0 15 rows
wp:nav_menu_item – – 68 68 unsupported
wp:wpcf7_contact_form – – 3 3 unsupported
wp:elementor_library – – 2 2 unsupported
wp:wp_navigation – – 2 2 unsupported

清洗统计(背景数据,非对照项):changedRows=138(post 87 + product 47 + page 4;attachment 无正文零清洗全 skipped);removed-tag=3、removed-attr=4,667;rowErrors 固化 4,793 条(上限 10,000,未触顶 truncated=0)。

Step 2 内存与耗时

内存(计划钉死口径:smoke 脚本内 setInterval(100ms) 采 process.memoryUsage() 的 heapUsed/rss 双 max)

指标 值
heapUsed max 65,268,760 B = 62.2MiB < 100MiB(断言通过)
rss max 175,218,688 B = 167.1MiB(进程整体常驻,含 node+tsx 运行时基线,仅记录不断言)
采样样本数 2(见下方口径说明)

口径说明(如实记录):

  • 采样的是整个进程的 heapUsed/rss——含 tsx 加载器与模块基线,非解析增量;断言语义是"流式解析 5.5MB 文件时进程堆峰值仍 < 100MB",通过即证明无整文件缓冲(整读 5.5MB 原文 + 解析树必然显著更高,且会随文件增长线性突破)。
  • probe 全程仅 ~167ms(见下),100ms 间隔只落到 2 个样本(1 个 interval tick + 终末补采 1 次)。max 以实测下界口径记录;考虑解析器 per-item yield、不 buffer item 列表的结构保证(Task 3 Step 2 钉死),两样本已覆盖解析爬坡段与收尾段,实测 62.2MiB 与 100MiB 线余量充足。

耗时(smoke run / CLI run 各一次,量级一致)

指标 smoke run(1yft49) CLI run(26azne)
parseMs 73.6ms 79.2ms
sanitizeMs 81.7ms 79.2ms
totalMs 166.9ms 169.5ms

parseMs 口径(Task 6 移交,务必连同数字一起引用):parseMs 是 parser.next() await 窗口累计——含流式 IO 等待(磁盘读、backpressure),非纯 CPU 解析耗时;totalMs 覆盖整个消费循环(含映射与报告聚合);totalMs ≥ parseMs+sanitizeMs 的差值即映射/聚合时间。

nicename 锚点核对(Task 4 冻结点)

核对方法:第二遍独立流式解析(同一 parseWxrStream),全量收集 wp:term 表(taxonomy → slug 集)与 item 引用(domain → nicename 计数),流结束后交叉验证;抽检规则=文档序前 10 个含 domain="category" 引用的 item(该类 item 共 129 个)。

抽检 10 条明细(全部未解析到 term slug,原因见下):

rawLocation postId post_type category nicename(value) ∈ wp:term slug 集
wxr://item/941 1646 post company-news(Company News) 否
wxr://item/942 2281 post trade-news(Trade News) 否
wxr://item/943 2549 post progect(Progects) 否
wxr://item/944 2833 post progect(Progects) 否
wxr://item/945 3121 post progect(Progects) 否
wxr://item/946 3124 post progect(Progects) 否
wxr://item/947 3127 post progect(Progects) 否
wxr://item/948 3130 post progect(Progects) 否
wxr://item/949 3138 post progect(Progects) 否
wxr://item/950 3143 post progect(Progects) 否

抽检一致率(category nicename 可解析到 wp:term slug):0/10。根因不是 nicename≠slug,而是该 WXR 的 wp:term 表根本没有 category/post_tag 条目。全量分层核对(grep 级独立复核结论一致):

domain(item 引用数) 可解析 wp:term 表中有该 taxonomy? 结论
product_tag(588) 588/588 = 100% 有(439 term) nicename ≡ term_slug
product_cat(49) 49/49 = 100% 有(10 term) nicename ≡ term_slug
nav_menu(68) 68/68 = 100% 有(1 term:mainmenu) nicename ≡ term_slug
elementor_library_type(1) 1/1 = 100% 有(1 term) nicename ≡ term_slug
category(148 引用,5 个不同 nicename:trade-news 59 / progect 29 / news 28 / company-news 20 / notification 12) 0/148 无(0 term) taxonomy 未导出,锚点无从对拍
post_tag(659 引用,471 个不同 nicename) 0/659 无(0 term) taxonomy 未导出,锚点无从对拍

汇总:wp:term 表内 taxonomy 的全部 706 条引用 100% 命中 slug,nicename≠slug 违例 0 条;category/post_tag 共 807 条引用因 term 表缺该 taxonomy 不可解析。(wp:term 总数 451 = product_tag 439 + product_cat 10 + nav_menu 1 + elementor_library_type 1,与 totals.terms 一致。)

对阶段 3 taxonomyRefs 映射策略的结论:

  1. Task 4 的锚点设计(sourceTermId = item 内 @nicename)被实数据正向验证:凡 term 表覆盖的 taxonomy,nicename 与 term_slug 完全等同(706/706),"真实 WP 中 category @nicename 即 term slug"的假设在本文件所有可对拍域上成立;
  2. 但不能假设 wp:term 表完备:本 WXR 未导出 category/post_tag 的 term 条目(WordPress 7.1.3 导出行为,含 nav_menu/elementor/product 域却缺这两个常规域)。阶段 3 做 slug → term_id 解析时,category(148 引用/5 nicename)与 post_tag(659 引用/471 nicename)将全部 miss——需按 (domain, nicename) 自建缺失 term(value 可作 name),不能只依赖 wp:term 事件;
  3. 数据怪癖原样保留:progect(源站拼写如此,29 处引用)按原文迁移不修正。

报告产物

产物 路径
冒烟结果(断言/内存/nicename 全量数据,JSON) artifacts/probe/20261021T132153-1yft49/smoke.json
probe 报告 JSON(smoke run) artifacts/probe/20261021T132153-1yft49/report.json
probe 报告 HTML(smoke run) artifacts/probe/20261021T132153-1yft49/report.html
probe 报告 JSON/HTML(CLI run) artifacts/probe/20261021T132302-26azne/report.{json,html}

(artifacts/ 不入库(.gitignore),产物仅存本地;smoke.json 的 checks 数组即上表 18 项断言的机器可读原貌。)

只读声明

本次冒烟对 D:/project/cms/storage/wxr/fd04d6ba8a1316b6.xml 仅执行读取操作(stat、sha256 流式读、两遍 createReadStream 解析读),未修改该文件及 D:\project\cms 下任何内容;全部写入仅发生在本仓库 artifacts/probe/ 与上述两个新建文件。