docs(plan): P2 Task 5 勾选 + Task 6 对接清单

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-21 11:27:18 +08:00
parent 7506fef875
commit 15e1e51a14
@@ -95,7 +95,7 @@ cms-one/
- [ ] Step 2 实现 `mapItem(item, config): MappedResult`(config: 类型路由表 {post:'wp:post', page:'wp:page', product:'wp:product', attachment:'wp:attachment'} + site locale)——纯函数
- [ ] Step 3 绿 → commit `feat(adapter-wp): WXR→UniversalRow 映射器(status 值域/悬空保留/unsupported 分流)`
### Task 5: HTML 白名单清洗
### Task 5: HTML 白名单清洗 ✅ 完成(8dd6eaf + 修复 7506fef,双审通过;228 测试;审查修复:srcset 审计三子情形精确化(parse-srcset 直依赖)、false 形态防御、**镜像改为直调 launder.naughtyHref(与库同一函数零漂移)**、等价测试参数化 15 对抗样本)
**Files:** Create `src/sanitize/html.ts`(sanitize-html 锁 ^2);Test `test/html-sanitize.test.ts`
@@ -111,7 +111,8 @@ cms-one/
**Files:** Create `src/adapter.ts`(parse→map→sanitize 串联为 `AsyncIterable<RowResult>`,RowResult = {kind:'row', row}|{kind:'unsupported',…}|{kind:'error',…});`src/report.ts`(计数汇总);Test `test/adapter.test.ts`
- [ ] Step 1 失败测试:mini.xml 全链 → 3 row(post/product/page)+ 2 attachment row + 0 unsupported + 差异计数(wppop 解析 1 成功);报告结构与 spec §7.7 字段对齐(**首条版本块:Adapter/Mapping/Sanitizer 版本常量**、按类型 Created/Skipped/Failed/Unsupported、清洗统计、行级错误带 rawLocation)
- [ ] Step 1 失败测试:mini.xml 全链 → 3 row(post/product/page)+ 2 attachment row + 0 unsupported + 差异计数(wppop 解析 1 成功);报告结构与 spec §7.7 字段对齐(**首条版本块:Adapter/Mapping/Sanitizer 版本常量——sanitize 模块需导出 SANITIZER_VERSION**、按类型 Created/Skipped/Failed/Unsupported、清洗统计、行级错误带 rawLocation)
- [ ] **Task 5 审查移交的对接清单**:HTML 报告渲染 SanitizeDiff.excerpt 时必须转义 `<>&"`(含恶意标记注入面测试);"内容变更"统计用 `html !== input` 字符串比较(diffs.length===0 ≠ 未变更——空值属性删除/裸 & 转义零 diff);清洗统计按 diff.type 分计数;清洗耗时纳入报告耗时统计(timeBudgetMs 是解析侧预算)
- [ ] Step 2 实现(含 validateUniversalRow **加法式**检查:复用 isUniversalRow + 返回 issue[] 的浅扩展,不动 contracts 包)
- [ ] Step 3 绿 → commit `feat(adapter-wp): 全链组装与导入前报告`