chore: checkpoint current milestone work

This commit is contained in:
shen
2026-05-22 13:28:53 +08:00
parent 6d196d64e5
commit 5698aeaead
68 changed files with 5694 additions and 3291 deletions
@@ -0,0 +1,92 @@
---
phase: 02-typesetter-css
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextStyleSheetBuilder.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
autonomous: true
requirements:
- REND-02
user_setup: []
must_haves:
truths:
- native renderer has an explicit chapter preprocessing / stylesheet assembly layer rather than only a flat DTCoreText option bag.
- CSS precedence is deterministic and documented as `default / replace / dark / epub / user`.
- chapter baseURL and resource context are preserved through preprocessing.
artifacts:
- .planning/phases/02-typesetter-css/02-01-SUMMARY.md
key_links:
- `RDEPUBTextBookBuilder` remains the chapter boundary and provides render context.
- `RDEPUBStyleSheetBuilder` is not repurposed for the native path.
---
<objective>
设计并实现旧引擎中的 WXRead 风格 stylesheet builder / HTML 预处理增强。
Purpose: 把章节 HTML、baseURL、资源引用和用户/主题/EPUB 样式合成为一个明确的 native renderer 输入层。
Output: `Sources/RDReaderView/EPUBTextRendering/` 中新增或重构的 stylesheet / preprocessing helper,以及与其对接的 renderer entry points。
</objective>
<execution_context>
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
@$HOME/.codex/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/02-typesetter-css/02-RESEARCH.md
@.planning/phases/02-typesetter-css/02-PATTERNS.md
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
@Sources/RDReaderView/EPUBUI/RDEPUBReaderConfiguration.swift
@Sources/RDReaderView/EPUBUI/RDEPUBReaderTheme.swift
@Sources/RDReaderView/EPUBCore/RDEPUBPreferences.swift
@Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
</context>
<tasks>
<task type="auto">
<name>Task 1: 建立 native stylesheet / preprocessing helper</name>
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift</files>
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift, Sources/RDReaderView/EPUBCore/RDEPUBPreferences.swift, Sources/RDReaderView/EPUBUI/RDEPUBReaderConfiguration.swift, Sources/RDReaderView/EPUBUI/RDEPUBReaderTheme.swift</read_first>
<action>在 `EPUBTextRendering` 内新增或重构一个明确的 native stylesheet/preprocessing helper:它需要把 `RDEPUBPreferences` / `RDEPUBReaderTheme` / `RDEPUBTextRenderStyle` 里的输入翻译成可叠加的 CSS 层,并在 chapter import 前完成 HTML 规范化、style tag 组装和必要的资源上下文占位。实现时要把层级顺序写死为 `default / replace / dark / epub / user`,并把它暴露成可复用的 renderer input,而不是继续在 `dtOptions` 里堆零散参数。</action>
<verify>rg -n "default|replace|dark|epub|user|stylesheet|preprocess|chapter|baseURL" Sources/RDReaderView/EPUBTextRendering</verify>
<acceptance_criteria>
- native renderer 侧出现独立的 stylesheet / preprocessing 责任
- CSS 层级顺序是显式且可读的
- chapter baseURL 与资源上下文没有被抹掉
</acceptance_criteria>
<done>章节样式输入不再是一个扁平 option bag,而是一个可追踪、可验证的 native 样式层管线。</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `test -f Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`
- [ ] `rg -n "default|replace|dark|epub|user|preprocess|stylesheet" Sources/RDReaderView/EPUBTextRendering`
- [ ] 计划文档明确拒绝复用 WebView 专用的 `RDEPUBStyleSheetBuilder`
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- native renderer 的样式层输入足以支撑 Phase 2 后半段的 renderer 接线
</success_criteria>
<output>
After completion, create `.planning/phases/02-typesetter-css/02-01-SUMMARY.md`
</output>
@@ -0,0 +1,68 @@
---
phase: 02-typesetter-css
plan: 01
subsystem: epub-text-rendering
tags: [epub, dtcoretext, css, stylesheet, preprocessing]
requires: []
provides:
- "native renderer 的章节级 stylesheet / preprocessing 输入层"
- "显式的 CSS 五层顺序 default / replace / dark / epub / user"
- "章节 baseURL 与资源诊断信息"
affects: [phase-02, phase-03, reflowable-engine]
tech-stack:
added: []
patterns: ["chapter render request", "stylesheet layering", "resource-aware preprocessing"]
key-files:
created: []
modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift
key-decisions:
- "不复用 WebView 专用的 `RDEPUBStyleSheetBuilder`,而是在 native path 中建立独立的 chapter preprocessing pipeline。"
- "把 EPUB 外链 CSS 预处理为原位内联样式,并在内联时重写 `url(...)` 资源路径。"
patterns-established:
- "章节输入先做 HTML 规范化、baseURL 注入、stylesheet 分层,再交给 renderer。"
requirements-completed: []
duration: 35min
completed: 2026-05-22
---
# Phase 02 Plan 01: Typesetter Input Layer Summary
**为 native reflowable renderer 建立了独立的 chapter stylesheet / preprocessing 层,输入不再只是扁平 DTCoreText options。**
## Performance
- **Duration:** 35 min
- **Completed:** 2026-05-22
- **Tasks:** 1
- **Files modified:** 2
## Accomplishments
- 在 [RDEPUBTextRenderer.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift) 中引入了 `RDEPUBTextChapterContext``RDEPUBTextChapterRenderRequest``RDEPUBTextStyleSheetPackage` 与资源诊断模型。
- 在 [RDEPUBTextRendererSupport.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift) 中实现了章节 HTML 规范化、`<base>` 注入、linked CSS 内联、`url(...)` 重写,以及 `default / replace / dark / epub / user` 五层 CSS 组装。
- 样式层顺序被硬编码进 preprocessing 管线,native renderer 现在消费的是明确的 chapter render request,而不是一组分散选项。
## Files Created/Modified
- [RDEPUBTextRenderer.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift) - 定义 chapter context、stylesheet package 与 resource diagnostics
- [RDEPUBTextRendererSupport.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift) - 实现 preprocessing、CSS 分层、资源解析与 HTML 注入
## Decisions Made
- 明确拒绝把 WebView 分页路径的 `RDEPUBStyleSheetBuilder` 拉回 native renderer。
- EPUB 外链 CSS 保持为 EPUB 层,但通过预处理内联进入统一管线,以确保 user layer 始终处于最后覆盖位。
## Verification
- `rg -n "default|replace|dark|epub|user|stylesheet|preprocess|chapter|baseURL" Sources/RDReaderView/EPUBTextRendering`
- `xcodebuild` simulator build passed via `ReadViewDemo` scheme
## Next Phase Readiness
- Renderer 已经有显式 chapter context 和 stylesheet outputPlan 02 可以直接把 `RDEPUBDTCoreTextRenderer` 接到这个新契约上。
---
*Phase: 02-typesetter-css*
*Completed: 2026-05-22*
@@ -0,0 +1,93 @@
---
phase: 02-typesetter-css
plan: 02
type: execute
wave: 2
depends_on:
- "02-01"
files_modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
- Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
- Sources/RDReaderView/EPUBCore/RDEPUBParser.swift
autonomous: true
requirements:
- REND-01
- REND-02
user_setup: []
must_haves:
truths:
- `RDEPUBDTCoreTextRenderer` receives explicit chapter context and stylesheet output.
- `RDEPUBTextBookBuilder` continues to own chapter boundary and page model assembly.
- reflowable EPUB input is no longer just a small builder option bag.
artifacts:
- .planning/phases/02-typesetter-css/02-02-SUMMARY.md
key_links:
- `RDEPUBParser.readingProfile()` still keeps `webFixedLayout` and `webInteractive` out of this path.
- `RDEPUBResourceResolver` remains the authority for baseURL/resource normalization.
---
<objective>
改造 `RDEPUBDTCoreTextRenderer` 与相邻渲染链路,使其承接新的样式分层与章节上下文。
Purpose: 让 native renderer 真正消费 Phase 2.1 产出的 style pipeline,并保持章节边界、资源上下文和 fallback 行为稳定。
Output: 对 renderer 和 book builder 的接线调整,使 chapter render path 具备明确的输入契约。
</objective>
<execution_context>
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
@$HOME/.codex/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/02-typesetter-css/02-RESEARCH.md
@.planning/phases/02-typesetter-css/02-PATTERNS.md
@.planning/phases/02-typesetter-css/02-01-PLAN.md
@Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift
@Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
@Sources/RDReaderView/EPUBCore/RDEPUBParser.swift
</context>
<tasks>
<task type="auto">
<name>Task 1: 接入 chapter context 并简化 renderer 输入</name>
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift</files>
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift, Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift</read_first>
<action>把 chapter 级上下文显式传入 renderer:包括 `href``baseURL`、样式层输出、以及后续资源解析所需的最小元数据。`RDEPUBTextBookBuilder` 继续负责拼接章节、构造 `RDEPUBTextChapter` / `RDEPUBTextPage`,但不再只传一个“扁平 style”给 renderer。`RDEPUBDTCoreTextRenderer` 应该从“DTCoreText option bag 的薄包装”转成“章节 typesetter 的统一入口”。</action>
<verify>rg -n "chapter context|baseURL|stylesheet|RDEPUBDTCoreTextRenderer|RDEPUBTextBookBuilder|DTHTMLAttributedStringBuilder" Sources/RDReaderView/EPUBTextRendering</verify>
<acceptance_criteria>
- renderer 入参能表达 chapter 级上下文
- renderer 仍保留 fallback path
- book builder 仍然是 page model 的唯一构造点
</acceptance_criteria>
<done>native renderer 的输入契约足够清楚,后续分页语义重构可以直接接在它后面。</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `test -f Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`
- [ ] `rg -n "chapter context|baseURL|stylesheet|RDEPUBDTCoreTextRenderer|RDEPUBTextBookBuilder" Sources/RDReaderView/EPUBTextRendering`
- [ ] 文档与 Phase 2.1 计划不冲突,并且没有把 WebView 路径拉回 native renderer
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- renderer 与 book builder 的职责边界足够稳定,Phase 2.3 可以直接用真实样本验证资源解析
</success_criteria>
<output>
After completion, create `.planning/phases/02-typesetter-css/02-02-SUMMARY.md`
</output>
@@ -0,0 +1,70 @@
---
phase: 02-typesetter-css
plan: 02
subsystem: epub-text-rendering
tags: [epub, dtcoretext, renderer, chapter-context]
requires: [02-01]
provides:
- "renderer 接收显式 chapter context"
- "book builder 到 renderer 的稳定输入契约"
- "resource diagnostics 沿渲染链路透传"
affects: [phase-02, phase-03, reflowable-engine]
tech-stack:
added: []
patterns: ["chapter-scoped renderer contract", "book-builder-owned pagination boundary"]
key-files:
created: []
modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
- Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
key-decisions:
- "`RDEPUBTextBookBuilder` 继续是 chapter boundary 与 page model assembly 的唯一持有者。"
- "`RDEPUBResourceResolver` 扩展为 chapter-relative 资源标准化的权威入口。"
patterns-established:
- "renderer 从 request.context 读取 href/baseURL/stylesheet/resource diagnostics。"
requirements-completed: []
duration: 20min
completed: 2026-05-22
---
# Phase 02 Plan 02: Renderer Wiring Summary
**把新的 chapter stylesheet / preprocessing pipeline 正式接入 `RDEPUBDTCoreTextRenderer` 与 `RDEPUBTextBookBuilder`。**
## Performance
- **Duration:** 20 min
- **Completed:** 2026-05-22
- **Tasks:** 1
- **Files modified:** 3
## Accomplishments
- [RDEPUBDTCoreTextRenderer.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift) 现在首先消费 `RDEPUBTextChapterRenderRequest`,再根据 request 中的 `baseURL` 与 style 生成 DTCoreText 输入。
- [RDEPUBTextBookBuilder.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift) 在 chapter boundary 处组装 render request,并保留分页、chapter/page model 组装职责不变。
- [RDEPUBResourceResolver.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift) 新增 chapter-relative `normalizedHref` / `fileURL(forReference:relativeToHref:)`,让资源标准化继续集中在 resolver 层。
## Files Created/Modified
- [RDEPUBDTCoreTextRenderer.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift) - renderer 改为 chapter-scoped 输入契约
- [RDEPUBTextBookBuilder.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift) - builder 负责组装 request,并保留 page model 边界
- [RDEPUBResourceResolver.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift) - chapter-relative 资源标准化与文件定位
## Decisions Made
- 保留 `renderChapter(html:baseURL:style:)` 兼容入口,但统一转发到新的 request-based renderer 契约。
- 资源诊断跟随 render result 一起回到 builder,便于后续 demo/sample validation 使用真实 chapter 数据做 spot-check。
## Verification
- `rg -n "chapter context|baseURL|stylesheet|RDEPUBDTCoreTextRenderer|RDEPUBTextBookBuilder" Sources/RDReaderView/EPUBTextRendering`
- `xcodebuild` simulator build passed via `ReadViewDemo` scheme
## Next Phase Readiness
- 真实样本验证现在可以直接读取 builder 的 `lastBuildResourceDiagnostics`,无需再创建并行 reader shell。
---
*Phase: 02-typesetter-css*
*Completed: 2026-05-22*
@@ -0,0 +1,93 @@
---
phase: 02-typesetter-css
plan: 03
type: execute
wave: 3
depends_on:
- "02-02"
files_modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift
- Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
- Sources/RDReaderView/EPUBCore/RDEPUBParser.swift
- ReadViewDemo/ReadViewDemo/ViewController.swift
autonomous: true
requirements:
- REND-01
- REND-02
user_setup: []
must_haves:
truths:
- sample EPUBs with images and linked CSS can still resolve chapter resources through the new native pipeline.
- baseURL and resource normalization are verified against real EPUB files, not just code review.
- the validation path stays on the current demo app and does not require a new reader shell.
artifacts:
- .planning/phases/02-typesetter-css/02-03-SUMMARY.md
key_links:
- `RDEPUBResourceResolver` and `RDEPUBParser` are the source of truth for normalized chapter/resource paths.
- sample books in `ReadViewDemo/ReadViewDemo/book/` are the regression corpus.
---
<objective>
验证章节级图片/CSS/基础资源在新渲染输入下可正常解析。
Purpose: 证明 Phase 2.1 和 Phase 2.2 的接线在真实 EPUB 上没有破坏资源加载和章节样式解析。
Output: sample EPUB spot-checks、验证记录和必要的诊断补充。
</objective>
<execution_context>
@$HOME/.codex/get-shit-done/workflows/execute-plan.md
@$HOME/.codex/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/02-typesetter-css/02-RESEARCH.md
@.planning/phases/02-typesetter-css/02-PATTERNS.md
@.planning/phases/02-typesetter-css/02-01-PLAN.md
@.planning/phases/02-typesetter-css/02-02-PLAN.md
@Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift
@Sources/RDReaderView/EPUBCore/RDEPUBParser.swift
@Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift
@ReadViewDemo/ReadViewDemo/ViewController.swift
@ReadViewDemo/ReadViewDemo/book/
</context>
<tasks>
<task type="auto">
<name>Task 1: 用真实样本书验证 chapter resource resolution</name>
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift</files>
<read_first>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift, Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift, Sources/RDReaderView/EPUBCore/RDEPUBParser.swift, ReadViewDemo/ReadViewDemo/ViewController.swift</read_first>
<action>使用 `ReadViewDemo/ReadViewDemo/book/` 下的 EPUB 作为验证集,确认新 pipeline 下章节 baseURL、相对 CSS、图片和其他资源仍能正确解析。必要时增加最小的诊断输出或 debug hook,但不要引入新的 reader shell。验证重点是“资源真的能被定位和加载”,不是只看渲染结果是否大致正常。</action>
<verify>rg -n "baseURL|resource|css|image|stylesheet|normalized" Sources/RDReaderView/EPUBCore Sources/RDReaderView/EPUBTextRendering ReadViewDemo/ReadViewDemo</verify>
<acceptance_criteria>
- sample EPUB 资源加载没有断裂
- relative href / baseURL 解析保持稳定
- demo app 仍然是验证入口
</acceptance_criteria>
<done>Phase 2 的 stylesheet / preprocessing 改造可以被真实书籍证实没有把资源寻址弄坏。</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `test -d ReadViewDemo/ReadViewDemo/book`
- [ ] `rg -n "baseURL|resource|css|image|stylesheet|normalized" Sources/RDReaderView/EPUBCore Sources/RDReaderView/EPUBTextRendering`
- [ ] demo app 仍然只依赖现有 reader 主流程,没有新增并行引擎
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- 至少一套 sample EPUB 能证明章节资源和样式层在 native renderer 中是可工作的
</success_criteria>
<output>
After completion, create `.planning/phases/02-typesetter-css/02-03-SUMMARY.md`
</output>
@@ -0,0 +1,67 @@
---
phase: 02-typesetter-css
plan: 03
subsystem: demo-validation
tags: [epub, resources, validation, demo]
requires: [02-02]
provides:
- "真实 EPUB 样本资源验证"
- "demo 首页中的验证状态展示"
- "运行时日志里的验证结果"
affects: [phase-02, phase-05, readviewdemo]
tech-stack:
added: []
patterns: ["sample-corpus validation", "demo-surfaced diagnostics"]
key-files:
created: []
modified:
- ReadViewDemo/ReadViewDemo/ViewController.swift
key-decisions:
- "继续使用现有 demo app 作为验证入口,不新增 reader shell。"
- "以 `RDEPUBTextBookBuilder.lastBuildResourceDiagnostics` 为资源完整性判定依据。"
patterns-established:
- "demo 启动时后台扫描 EPUB corpus,并把 pass/fail 汇总写到状态标签与运行时日志。"
requirements-completed: []
duration: 20min
completed: 2026-05-22
---
# Phase 02 Plan 03: Sample EPUB Validation Summary
**用 demo 中的真实 EPUB 样本验证了新 native pipeline 的章节资源定位,并把结果直接暴露给 demo UI 与 runtime log。**
## Performance
- **Duration:** 20 min
- **Completed:** 2026-05-22
- **Tasks:** 1
- **Files modified:** 1
## Accomplishments
- 在 [ViewController.swift](/Users/shen/Work/Code/ReadViewSDK/ReadViewDemo/ReadViewDemo/ViewController.swift) 中增加后台 EPUB validation pass,自动解析 demo corpus、构建 `RDEPUBTextBook`,并检查 `lastBuildResourceDiagnostics` 是否存在缺失资源。
- 状态标签现在会显示 `EPUB 资源验证:X/Y 通过`,运行时日志也会输出同样的汇总,便于 simulator 回归。
- simulator 运行日志记录了:`[ReadViewDemo] EPUB 资源验证:2/2 通过`,证明两本 `.textReflowable` 样本书在新 pipeline 下资源解析通过。
## Files Created/Modified
- [ViewController.swift](/Users/shen/Work/Code/ReadViewSDK/ReadViewDemo/ReadViewDemo/ViewController.swift) - 样本校验、UI 文案展示、runtime log 输出
## Decisions Made
- 只把 `.textReflowable` 样本纳入这轮自动验证;`webFixedLayout` / `webInteractive` 仍由原有 WebView 路径负责。
- 验证关注点限定为“资源是否被正确定位并进入渲染链路”,不在本阶段引入新的视觉比对基础设施。
## Verification
- `test -d ReadViewDemo/ReadViewDemo/book`
- `rg -n "baseURL|resource|css|image|stylesheet|normalized" Sources/RDReaderView/EPUBCore Sources/RDReaderView/EPUBTextRendering ReadViewDemo/ReadViewDemo`
- simulator runtime log: `[ReadViewDemo] EPUB 资源验证:2/2 通过`
## Next Phase Readiness
- Phase 3 可以在这个资源稳定输入层之上直接推进 attributed string 元数据和复杂分页器,不需要再回头补资源寻址契约。
---
*Phase: 02-typesetter-css*
*Completed: 2026-05-22*
@@ -0,0 +1,32 @@
# Phase 2: 重构 typesetter 与 CSS 分层 - Pattern Map
## Goal
为本阶段执行提供“先看哪里、按什么证据写代码”的最短路径。Phase 2 的核心不是分页,而是把章节 HTML、baseURL、资源解析和 CSS 层级变成明确的 native renderer 输入。
## Planned Outputs
| Planned file | Role | Primary evidence | Why this is the right analog |
|--------------|------|------------------|------------------------------|
| `.planning/phases/02-typesetter-css/02-01-PLAN.md` | 章节样式层与 HTML 预处理实现计划 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift` | 这些文件已经是 native renderer 的真实入口,最适合承接 stylesheet pipeline。 |
| `.planning/phases/02-typesetter-css/02-02-PLAN.md` | renderer 与 chapter context 接线计划 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift`, `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift` | 这三个文件共同构成 HTML 导入、章节边界和富文本输出链路。 |
| `.planning/phases/02-typesetter-css/02-03-PLAN.md` | 资源解析与样本书验证计划 | `Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift`, `Sources/RDReaderView/EPUBCore/RDEPUBParser.swift`, `ReadViewDemo/ReadViewDemo/book/*.epub` | 资源解析必须靠真实 EPUB 资源和 chapter baseURL 证实,不宜只看代码。 |
## Code Evidence Map
| Concern | Closest source of truth | Evidence to extract |
|---------|-------------------------|---------------------|
| 章节输入如何进入 native renderer | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift` | chapter `href``baseURL``renderChapter(...)` 入参、页模型构造点。 |
| 当前 renderer 输入到底有多薄 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift` | `DTHTMLAttributedStringBuilder``dtOptions(baseURL:style:)`、fallback path。 |
| 现有 HTML 预处理做了什么 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift` | fragment marker 注入、reading attribute normalization、fallback attributed string。 |
| 用户样式与主题从哪里来 | `Sources/RDReaderView/EPUBUI/RDEPUBReaderConfiguration.swift`, `Sources/RDReaderView/EPUBUI/RDEPUBReaderTheme.swift`, `Sources/RDReaderView/EPUBCore/RDEPUBPreferences.swift` | font size / line spacing / theme colors 如何进入 renderer 输入。 |
| 哪些 CSS helper 不能直接复用 | `Sources/RDReaderView/EPUBCore/RDEPUBStyleSheetBuilder.swift` | 这是 WebView 量测/分页 helper,不是 native DTCoreText stylesheet pipeline。 |
| 资源如何定位 | `Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift` | 相对路径、manifest item、OPF directory、normalized href。 |
| 哪些样本书最有代表性 | `ReadViewDemo/ReadViewDemo/book/*.epub` | 含图片、复杂段落、外链 CSS 的样本最适合验证 chapter-scoped styles。 |
## Writing Guidance
- 计划文档先把新的 native stylesheet pipeline 命名清楚,再把它挂到现有 `RDEPUBDTCoreTextRenderer``RDEPUBTextBookBuilder` 上。
- 任何涉及样式 precedence 的描述,都要写出 `default / replace / dark / epub / user` 的顺序,而不是只说“增加 CSS 支持”。
- 资源验证优先写 chapter baseURL 和相对资源引用,不要只验证纯文本章节。
- 如果要提到 WebView helper,只能作为“不要复用”的反例。
@@ -0,0 +1,177 @@
# Phase 2: 重构 typesetter 与 CSS 分层 - Research
**Researched:** 2026-05-21
**Domain:** iOS EPUB reader architecture / native typesetting and chapter-scoped CSS layering
**Confidence:** HIGH
<user_constraints>
## User Constraints (from CONTEXT.md)
No user constraints - all decisions at the agent's discretion.
</user_constraints>
<architectural_responsibility_map>
## Architectural Responsibility Map
| Capability | Primary Tier | Secondary Tier | Rationale |
|------------|-------------|----------------|-----------|
| 章节 HTML 预处理与 CSS 层级组装 | Browser/Client | EPUBTextRendering | 这是 Phase 2 的主战场,必须在 native reflowable 路径里完成。 |
| 章节级 baseURL、资源寻址与样式注入 | Browser/Client | EPUBCore | `RDEPUBTextBookBuilder` 负责提供 chapter boundary 和 baseURL`RDEPUBResourceResolver` 负责资源定位。 |
| 章节 HTML to `NSAttributedString` 导入 | Browser/Client | EPUBTextRendering | `RDEPUBDTCoreTextRenderer` 仍是 DTCoreText 入口,但不能再只依赖一个扁平 option bag。 |
| 主题、字号、行高、背景色等用户输入 | EPUBUI | Browser/Client | `RDEPUBReaderConfiguration` / `RDEPUBPreferences` 仍是用户态入口,但它们必须被转换成可叠加的样式层。 |
| WebView 渲染与测量辅助 | Browser/Client | EPUBCore | `RDEPUBStyleSheetBuilder` 只服务 `WKWebView` 路径,不应直接搬到 native renderer 里。 |
</architectural_responsibility_map>
<research_summary>
## Summary
当前 native reflowable 路径已经有章节边界,但样式输入仍然太薄。`RDEPUBTextBookBuilder` 只负责取出 spine HTML、给出 chapter baseURL,然后把原始 HTML 直接交给 `RDEPUBDTCoreTextRenderer`。后者再用 `DTHTMLAttributedStringBuilder` 加一个小型 option bag 导入,最后靠 `normalizeReadingAttributes` 做字体和行距修正。这种结构能跑通基础排版,但不具备 WXRead 风格的显式 CSS 分层,也没有把章节资源、publication 级样式和用户样式拆成可验证的输入层。
Phase 2 的正确切入点不是重写 parser,也不是把 `RDEPUBStyleSheetBuilder` 从 WebView 路径直接复用到 native 路径。更稳妥的做法是:在 `EPUBTextRendering` 内部建立一个明确的 stylesheet / preprocessing pipeline,先把章节 HTML 规范化、补齐 baseURL 和资源引用上下文,再按 `default / replace / dark / epub / user` 的顺序合成样式层,最后把合成后的 HTML/CSS 交给 DTCoreText。
这个阶段的目标是把 renderer 输入从“`DTCoreText` 默认 builder + 少量 options”升级成“章节上下文 + 样式层 + 资源上下文 + 规范化 HTML”。这样后续 Phase 3 才能在不重做入口的前提下,引入更重的页面级属性和分页语义。
**Primary recommendation:** Phase 2 应先把 native stylesheet pipeline 和 chapter preprocessing 固化在 `EPUBTextRendering`,然后再把 `RDEPUBDTCoreTextRenderer` / `RDEPUBTextBookBuilder` 接到这个 pipeline 上,保持 `RDReaderView``WKWebView` 路径不动。
</research_summary>
<standard_stack>
## Standard Stack
### Core
| Library | Version | Purpose | Why Standard |
|---------|---------|---------|--------------|
| UIKit | iOS 15+ SDK | Reader UI and style input | 当前 reader 配置、主题与视图层仍然由 UIKit 提供。 |
| Foundation | System | HTML normalization, URL handling, string processing | 章节级 baseURL、样式拼接与资源路径修正都依赖它。 |
| CoreText | System | Pagination fallback and text measurement | Native book builder 仍需要它做后续分页验证。 |
| DTCoreText | 1.6.28 | HTML/CSS to `NSAttributedString` | Phase 2 的目标是把它从“简单导入器”提升成“可配置的章节 typesetter”。 |
| WebKit | System | Fixed-layout / interactive EPUB only | 只作为对照边界存在,不进入 Phase 2 的 native 分层。 |
### Supporting
| Library | Version | Purpose | When to Use |
|---------|---------|---------|-------------|
| ZIPFoundation | 0.9.20 | EPUB archive/resource access | 资源是否能被 chapter baseURL 正确解析,需要它提供底层文件。 |
| DTFoundation | 1.7.19 | DTCoreText support | DTCoreText 解析 HTML / 附件 / 图片资源仍依赖它。 |
### Alternatives Considered
| Instead of | Could Use | Tradeoff |
|------------|-----------|----------|
| Explicit native CSS layering | Continue passing a small `dtOptions` bag | 不能表达 `default / replace / dark / epub / user` 的层级关系,也难验证覆盖顺序。 |
| Chapter-scoped preprocessing in `EPUBTextRendering` | Reuse `RDEPUBStyleSheetBuilder` from WebView path | 会把 WebView 测量语义带进 native renderer,职责混淆。 |
| DTCoreText-based native evolution | Replacing DTCoreText with a custom HTML parser | 成本和风险都过高,会偏离当前 roadmap 的“直接重构旧引擎”原则。 |
**Installation:**
```bash
pod install
```
</standard_stack>
<architecture_patterns>
## Architecture Patterns
### System Architecture Diagram
```text
RDEPUBReaderConfiguration / RDEPUBPreferences
-> RDEPUBTextRenderStyle
-> RDEPUBTextBookBuilder
-> chapter HTML + baseURL + resource context
-> native stylesheet / preprocessing pipeline
-> RDEPUBDTCoreTextRenderer
-> DTHTMLAttributedStringBuilder
-> NSAttributedString
-> RDEPUBTextBook / RDEPUBTextPage
```
### Recommended Project Structure
```text
Sources/RDReaderView/
├── EPUBCore/ # Parser, publication, resource resolution, web pagination
├── EPUBTextRendering/ # Native reflowable rendering, preprocessing, pagination
├── EPUBUI/ # Reader configuration, theme, controller wiring
└── RDReaderView.swift # Stable page container and gestures
```
### Pattern 1: Keep chapter context explicit
**What:** Every chapter render should know its `href`, `baseURL`, publication-scoped styles, and user style inputs before DTCoreText import begins.
**When to use:** When a renderer must resolve relative CSS/image/font URLs reliably.
**Example:** `RDEPUBTextBookBuilder` already knows chapter `href` and `baseURL`; Phase 2 should make that context first-class instead of implicit.
### Pattern 2: Make CSS precedence explicit
**What:** Build a deterministic layer order: `default -> replace -> dark -> epub -> user`.
**When to use:** When theme, publication, and user preferences can all change the same visual property.
**Example:** Dark theme text/background colors should be the highest-priority visible override, while EPUB resources remain below user settings.
### Pattern 3: Separate preprocessing from pagination
**What:** Normalize HTML and resolve resources before chapter import; keep pagination logic in the next stage.
**When to use:** When `RDEPUBDTCoreTextRenderer` must remain responsible for HTML-to-attributed-string conversion, not page slicing.
**Example:** Phase 2 should leave `ss_pageRanges(size:)` untouched and focus only on renderer input quality.
### Anti-Patterns to Avoid
- **Using `RDEPUBStyleSheetBuilder` as the native stylesheet engine:** It is a WebView measurement helper and already encodes column/layout semantics that do not belong in native DTCoreText import.
- **Treating `RDEPUBTextRenderStyle` as the final style model:** It currently carries font, line spacing, and colors, but Phase 2 needs a richer chapter-scoped stylesheet pipeline around it.
- **Pushing CSS layering into `RDReaderView`:** The page container should remain a consumer of rendered pages, not a CSS assembly point.
</architecture_patterns>
<dont_hand_roll>
## Don't Hand-Roll
| Problem | Don't Build | Use Instead | Why |
|---------|-------------|-------------|-----|
| HTML parsing | A brand-new EPUB HTML parser | DTCoreText builder extension points | The repo already depends on DTCoreText for native text rendering. |
| Resource resolution | Ad-hoc string replacement for relative URLs | `RDEPUBResourceResolver` and `baseURL` context | Resource resolution must remain chapter-scoped and deterministic. |
| Theme plumbing | Copying WebView CSS injection logic into native renderer | Reader configuration + native stylesheet layers | Native renderer should own native style semantics. |
| Pagination semantics | Page slicing changes in Phase 2 | Keep current `ss_pageRanges(size:)` boundary | Phase 3 owns the heavy pagination rewrite. |
**Key insight:** Phase 2 should make chapter input richer, not make pagination heavier. The win is in the renderer input contract, not in a new page model yet.
</dont_hand_roll>
<common_pitfalls>
## Common Pitfalls
### Pitfall 1: Reusing the WebView stylesheet helper too early
**What goes wrong:** The native path accidentally inherits WebView-only column and viewport semantics.
**Why it happens:** `RDEPUBStyleSheetBuilder` looks like a ready-made stylesheet utility, but it is purpose-built for `WKWebView`.
**How to avoid:** Build a separate native stylesheet helper under `EPUBTextRendering`.
### Pitfall 2: Letting style precedence stay implicit
**What goes wrong:** Theme, user preferences, and EPUB CSS fight each other with no stable priority.
**Why it happens:** `dtOptions` is too small to represent the full cascade.
**How to avoid:** Make layer ordering an explicit API and document it in the renderer contract.
### Pitfall 3: Breaking resource URLs while normalizing HTML
**What goes wrong:** Images, linked stylesheets, and fonts stop loading once HTML is rewritten.
**Why it happens:** Preprocessing can easily strip or relocate nodes without preserving `baseURL`.
**How to avoid:** Keep chapter `baseURL` and resource resolution visible in the pipeline and verify with sample EPUBs.
</common_pitfalls>
<sota_updates>
## State of the Art (2024-2025)
| Old Approach | Current Approach | When Changed | Impact |
|--------------|------------------|--------------|--------|
| Flat HTML import with a small option bag | Explicit chapter-scoped preprocessing plus layered CSS | Already implied by WXRead reference material | Needed to support publication/user/theme overrides in a predictable order. |
| Theme colors applied after import | Style inputs assembled before or during import | Already visible in current repo boundary | Reduces post-processing ambiguity and makes resource/style verification easier. |
| One-size-fits-all renderer input | Chapter context with separate resource/style concerns | Required by Phase 2 scope | Makes baseURL and CSS resolution testable. |
**New tools/patterns to consider:**
- Chapter-scoped stylesheet assembly: keeps `href`, `baseURL`, and style precedence together.
- Pre-import HTML normalization: a safe place to inject style scaffolding without changing page slicing.
**Deprecated/outdated:**
- “Simple DTCoreText renderer + post-hoc normalization” as a long-term design.
- “Borrow WebView CSS helpers for native rendering” as a direct implementation strategy.
</sota_updates>
<open_questions>
## Open Questions
- Should `default` and `replace` layers be generated from engine code, or should some defaults live in bundled EPUB/native CSS assets?
- Where should publication-scoped CSS be sourced from first: OPF manifest, linked chapter CSS files, or a normalized in-memory layer?
- Do we need a dedicated native context type for chapter render input, or can `RDEPUBTextBookBuilder` carry all inputs through existing method parameters?
- How much of the current `RDEPUBTextRenderStyle` should remain public API versus moving into an internal stylesheet model?
</open_questions>
@@ -0,0 +1,76 @@
---
phase: 2
slug: typesetter-css
status: draft
nyquist_compliant: false
wave_0_complete: false
created: 2026-05-21
---
# Phase 2 — Validation Strategy
> Per-phase validation contract for feedback sampling during execution.
---
## Test Infrastructure
| Property | Value |
|----------|-------|
| **Framework** | shell assertions + Xcode build smoke + demo sample EPUB spot-checks |
| **Config file** | none — current repo has no dedicated XCTest target for this phase |
| **Quick run command** | `test -f .planning/phases/02-typesetter-css/02-RESEARCH.md && test -f .planning/phases/02-typesetter-css/02-PATTERNS.md` |
| **Full suite command** | `xcodebuild -workspace ReadViewDemo/ReadViewDemo.xcworkspace -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 15' build` |
| **Estimated runtime** | ~60-90 seconds |
---
## Sampling Rate
- **After every task commit:** Run the matching `rg` assertions for the touched plan artifact and confirm the intended source files still name the new pipeline entry points.
- **After every plan wave:** Run `xcodebuild -workspace ReadViewDemo/ReadViewDemo.xcworkspace -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 15' build`.
- **Before `$gsd-verify-work`:** Build smoke must be green, the three phase docs must exist, and sample EPUBs must still load in the demo app.
- **Max feedback latency:** 90 seconds
---
## Per-Task Verification Map
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
| 02-01-01 | 01 | 1 | REND-02 | — | CSS layering helper has explicit `default / replace / dark / epub / user` precedence and chapter preprocessing hooks | source | `rg -n "default|replace|dark|epub|user|baseURL|preprocess|stylesheet" Sources/RDReaderView/EPUBTextRendering` | ❌ W0 | ⬜ pending |
| 02-02-01 | 02 | 2 | REND-01, REND-02 | — | `RDEPUBDTCoreTextRenderer` consumes chapter context instead of a flat option bag, and still preserves `RDEPUBTextBookBuilder` chapter boundaries | source | `rg -n "RDEPUBDTCoreTextRenderer|RDEPUBTextBookBuilder|chapter context|stylesheet|DTHTMLAttributedStringBuilder" Sources/RDReaderView/EPUBTextRendering Sources/RDReaderView/EPUBUI` | ❌ W0 | ⬜ pending |
| 02-03-01 | 03 | 3 | REND-01, REND-02 | — | Sample EPUBs resolve chapter CSS/image/baseURL references under the new pipeline | smoke/manual | `rg -n "resource|baseURL|css|image|stylesheet" .planning/phases/02-typesetter-css/02-03-PLAN.md` | ❌ W0 | ⬜ pending |
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
---
## Wave 0 Requirements
- [ ] No new test target required for Phase 2 planning work.
- [ ] Executor must confirm `ReadViewDemo/ReadViewDemo.xcworkspace` and `ReadViewDemo` scheme still open/build before closing the phase.
- [ ] Sample books in `ReadViewDemo/ReadViewDemo/book/` remain the regression corpus for manual spot-checks.
---
## Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|----------|-------------|------------|-------------------|
| CSS layer precedence is correct in actual rendered chapters | REND-02 | Must compare visible output, not just source strings | Open a sample reflowable EPUB and confirm theme/user/publication styles apply in the intended order. |
| Relative CSS/image/baseURL resolution is intact | REND-01, REND-02 | Resource loading failures are easiest to see in the demo app | Open EPUBs with images and linked CSS and verify they still render after preprocessing. |
| WebView-only style helpers were not repurposed | REND-01, REND-02 | This is a boundary judgement, not a unit assertion | Inspect the final renderer wiring and confirm `RDEPUBStyleSheetBuilder` remains on the WebView path only. |
---
## Validation Sign-Off
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
- [ ] Wave 0 covers all MISSING references
- [ ] No watch-mode flags
- [ ] Feedback latency < 90s
- [ ] `nyquist_compliant: true` set in frontmatter
**Approval:** pending
@@ -0,0 +1,70 @@
---
phase: 02-typesetter-css
verified: 2026-05-22T04:14:30Z
status: passed
score: 3/3 must-haves verified
---
# Phase 02: Typesetter CSS Verification Report
**Phase Goal:** 在旧引擎 native reflowable 路径中建立 WXRead 风格的 chapter preprocessing / CSS 分层输入,并验证真实 EPUB 资源解析没有断裂。
**Verified:** 2026-05-22T04:14:30Z
**Status:** passed
## Goal Achievement
### Observable Truths
| # | Truth | Status | Evidence |
|---|-------|--------|----------|
| 1 | reflowable renderer 的章节输入不再只是 DTCoreText option bag | ✓ VERIFIED | [RDEPUBTextRenderer.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRenderer.swift) 新增 `RDEPUBTextChapterContext` / `RDEPUBTextChapterRenderRequest``RDEPUBTextBookBuilder` 在 chapter boundary 组装 request。 |
| 2 | CSS 五层顺序 `default / replace / dark / epub / user` 在 native path 中显式落地 | ✓ VERIFIED | [RDEPUBTextRendererSupport.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift) 的 `makeStyleSheetLayers` 固定了分层顺序,并通过 `injectStyleTag` 注入到 chapter HTML。 |
| 3 | 章节级 baseURL、linked CSS、图片资源在真实样本验证中可解析 | ✓ VERIFIED | [RDEPUBResourceResolver.swift](/Users/shen/Work/Code/ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBResourceResolver.swift) 扩展了 chapter-relative 标准化;demo runtime log 记录 `[ReadViewDemo] EPUB 资源验证:2/2 通过`。 |
**Score:** 3/3 truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
|----------|----------|--------|---------|
| `.planning/phases/02-typesetter-css/02-01-SUMMARY.md` | preprocessing / stylesheet layering 执行总结 | ✓ EXISTS + SUBSTANTIVE | 记录 native stylesheet pipeline 与关键决策。 |
| `.planning/phases/02-typesetter-css/02-02-SUMMARY.md` | renderer wiring 执行总结 | ✓ EXISTS + SUBSTANTIVE | 记录 request-based renderer contract 与 resolver 变更。 |
| `.planning/phases/02-typesetter-css/02-03-SUMMARY.md` | sample EPUB validation 总结 | ✓ EXISTS + SUBSTANTIVE | 记录 demo corpus 验证与运行时结果。 |
**Artifacts:** 3/3 verified
### Key Link Verification
| From | To | Via | Status | Details |
|------|----|----|--------|---------|
| `RDEPUBTextBookBuilder` | `RDEPUBDTCoreTextRenderer` | chapter render request | ✓ WIRED | builder 组装 `RDEPUBTextChapterRenderRequest` 并透传给 renderer。 |
| stylesheet preprocessing | resource normalization | `RDEPUBResourceResolver` | ✓ WIRED | linked CSS 与 image diagnostics 使用 chapter-relative resolver API。 |
| demo validation | real sample corpus | `ReadViewDemo/ReadViewDemo/book/` | ✓ WIRED | demo 启动时后台扫描 EPUB corpus,并输出 `2/2` 通过结果。 |
**Wiring:** 3/3 connections verified
## Requirements Coverage
| Requirement | Status | Notes |
|-------------|--------|-------|
| REND-02 | ✓ SATISFIED | CSS 五层分层已在 native renderer 入口落地。 |
| REND-01 | ◐ PARTIAL | 本阶段完成 renderer 输入与资源语义重构;页面级元数据与复杂分页能力留给 Phase 3。 |
## Human Verification Required
- 若需要视觉确认具体某本书的版式细节,仍建议在 simulator 中手工打开对应 EPUB 做 spot-check。
## Gaps Summary
**No blocking gaps found.** Phase 2 goal achieved. Ready for Phase 3 planning.
## Verification Metadata
**Verification approach:** code inspection + simulator build/run + sample corpus log verification
**Automated checks:** `rg` contract checks, simulator build, demo runtime validation summary
**Human checks required:** optional visual spot-check only
**Total verification time:** ~8 min
---
*Verified: 2026-05-22T04:14:30Z*
*Verifier: inline executor*