Skip to content

Commit 974343b

Browse files
committed
docs(notes): v0.7.6 纯本地结构渲染层规划(章节+术语表入笔记,REQ-177~181 登记)
1 parent f2efab9 commit 974343b

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

‎docs/product/requirements-pool.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@
239239
| REQ-175 | 前端全局采集徽标拉取兜底:App.tsx 监听 session:fusing + 停止 invoke 成功后 live_session_status 确认 | P1 | 已排期 | v0.7.5 | 徽标不再单一依赖 live:status 事件;停止后 ≤2s 清除 |
240240
| REQ-176 | DB 残留 recording 会话兜底标记:list_sessions 发现 recording 但 manager 无活动线程 → 自动标 failed | P1 | 已排期 | v0.7.5 | 复用 mark_interrupted_sessions 语义;无需重启翻案;进行中会话不误标 |
241241

242+
### v0.7.6 · 笔记纯本地结构渲染层(章节入笔记 + 术语表入笔记)
243+
244+
> v0.7.5 裁决缓做的"结构组织"六项中纯本地可行的两项(章节/TOC、术语表)落地;摘要/结论、语义切段归 v0.8.0 AI 精修(REQ-141),时间对齐内联/要点标记后续批次。
245+
> 设计:[v0.7.6 版本文档](../versions/v0.7.6.md)。
246+
247+
| ID | 需求 | 优先级 | 状态 | 目标版本 | 备注 |
248+
|----|------|--------|------|---------|------|
249+
| REQ-177 | 章节入笔记:章节边界 → `## 章节 N [MM:SS]` 标题层级;章节名取窗口内 outline 标题(OCR 大字块/屏标题),无命中占位 | P1 | 已排期 | v0.7.6 | 复用 REQ-044/064 章节检测 + REQ-077 outline 标题检测,缺的只是"接进笔记";边界段内不切段(诚实粗粒度) |
250+
| REQ-178 | 术语表入笔记:glossary 候选 → 笔记尾部 `## 词汇表` 块(画面×N/语音×M + [MM:SS] 锚点);自动候选直入(可手动删,不做确认 UI);上限 20 防噪音 | P1 | 已排期 | v0.7.6 | 复用 REQ-046/061 glossary;与 v0.8.0 知识补充(REQ-142)语义区分:本项=会话内已有术语,非模型外部知识 |
251+
| REQ-179 | 结构渲染配置化:NoteStructureConfig(chapter_headings/glossary_block/glossary_max_terms)JSON 可校准 | P2 | 已排期 | v0.7.6 | purify_config.json 先例;全关 = v0.7.5 输出逐字节一致(零回归护栏) |
252+
| REQ-180 | 结构元数据:StructureStats 并入 purify_stats + RULE_VERSION 递增 note-rules-0.7.6 | P2 | 已排期 | v0.7.6 | REQ-171 机制延续;旧笔记 NULL 诚实降级 |
253+
| REQ-181 | 黄金语料回归扩展:会话31 夹具 → 期望带结构笔记断言(TDD) | P1 | 已排期 | v0.7.6 | REQ-172 机制扩展;预览/落库双出口逐字节一致 |
254+
242255
### V1.0 · 体验增强(远期)
243256

244257
| ID | 需求 | 优先级 | 状态 | 目标版本 | 备注 |

‎docs/versions/v0.7.6.md‎

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# v0.7.6 — 笔记纯本地结构渲染层(章节入笔记 + 术语表入笔记)
2+
3+
> **状态**: 规划中(2026-08-20 头脑风暴完成,设计已确认;待实施)
4+
> **目标**: 把 v0.7.5 裁决缓做的"结构组织"中**纯本地可行**的两项做掉——章节/TOC 入笔记(章节边界 → Markdown 标题层级)+ 术语表入笔记(词汇表块);不依赖云端 AI,与 v0.8.0 AI 精修(REQ-141)并存兼容。
5+
> **关联**: [v0.7.5 版本文档](./v0.7.5.md)(§六 缓做裁决)· REQ-044/064(章节检测已实施)· REQ-077(大纲标题检测已实施)· REQ-046/061(术语表已实施)· REQ-171(规则版本元数据)· REQ-172(黄金语料回归)· v0.8.0(AI 精修接管语义层,本版不做语义级结构)
6+
7+
## 一、范围裁决(2026-08-20 头脑风暴)
8+
9+
v0.7.5 §六 缓做六项逐一评估纯本地可行性:
10+
11+
| 缓做项 | 纯本地可行性 | 本版裁决 |
12+
|--------|-------------|---------|
13+
| 章节/TOC 入笔记 | ✅ 完全可行(chapter_detect + outline 均已实施,缺"接进笔记") | **做** |
14+
| 术语表入笔记 | ✅ 完全可行(glossary 已实施,缺"接进笔记") | **做** |
15+
| 讲述↔画面时间对齐内联 | ⚠️ 部分可行(屏/段时间戳已有,交错呈现涉及前端布局重构) | 不做(前端工作量独立) |
16+
| 要点/行动项 | ⚠️ 部分可行(highlight_detect 已有——可做"重点段标记") | 不做(下批候选) |
17+
| 摘要/结论 | ❌ 语义层,必须 LLM | v0.8.0 REQ-141 |
18+
| 语义切段 | ❌ 语义层,必须 LLM | v0.8.0 REQ-141 |
19+
20+
**用户裁决**:章节/TOC + 术语表两项全收;章节标题复用 outline(OCR 大字块/屏标题);术语自动候选直接入笔记(可手动删,不做确认 UI);独立小版本 **v0.7.6** 发布(不与 v0.8.0 AI 合并)。
21+
22+
## 二、设计:独立结构渲染层(方案 B)
23+
24+
### 架构
25+
26+
```
27+
filter_note(净化,零改动) structure_note.rs(新增,纯函数)
28+
segments/ocr_blocks ──► NoteFilterResult ──► render_note_structure ──► 带结构的 NoteFilterResult
29+
▲ │
30+
│ ├─ chapters(章节边界,analyze_session_opt 已有)
31+
│ ├─ outline(章节标题,detect_outline_smart 复用)
32+
│ └─ glossary(术语候选,analyze_session_opt 已有)
33+
```
34+
35+
- `note_filter.rs` / `concat.rs` **零改动**(零回归)
36+
- 新模块 `structure_note.rs`:纯函数、无 IO、单文件 ≤300 行、显式依赖注入
37+
- 与 v0.8.0 AI 精修兼容:AI 版将来以"结构块数组"重写本层输出,规则版=生成结构块,同一协议(精修=整理不创作原则不受影响)
38+
39+
### 核心纯函数
40+
41+
```rust
42+
// structure_note.rs
43+
pub struct NoteStructureConfig {
44+
pub chapter_headings: bool, // 章节标题入笔记(默认 true)
45+
pub glossary_block: bool, // 词汇表块(默认 true)
46+
pub glossary_max_terms: usize, // 词汇表条目上限(默认 20,防噪音)
47+
}
48+
49+
pub fn render_note_structure(
50+
result: &mut NoteFilterResult,
51+
chapters: &[ChapterBoundary],
52+
outline: &[OutlineEntry],
53+
glossary: &[GlossaryCandidate],
54+
config: &NoteStructureConfig,
55+
) -> StructureStats // { chapters, titled_chapters, glossary_terms } 并入 purify_stats
56+
```
57+
58+
**章节 → 标题**(`## 章节 N [MM:SS]`):
59+
- 章节边界 `time_ms` → 在 `## 讲述内容` 内该时刻的段落前插入标题行(段落切分复用 `concat::split_transcript_paragraphs_with` 口径,与净化管线一致)
60+
- 章节名 = 本边界→下一边界窗口内**第一个 outline 条目文本**(OCR 大字块/屏标题,复用 `outline::detect_outline_smart`);无命中 → 占位"章节 N"
61+
- 边界落在段内 → 段首插(粗粒度边界,不切段——诚实标注不伪造粒度)
62+
63+
**术语表 → 词汇表块**(笔记尾部 `## 词汇表`):
64+
- 每项 `- 术语(画面 ×N / 语音 ×M)`,按 score 降序,上限 `glossary_max_terms`
65+
- 锚点:术语在 kept 段中首次出现处 → `[MM:SS]` 前缀(回跳语义,复用 REQ-165 锚点风格)
66+
67+
**空输入降级(诚实降级)**:无章节(口播档案)→ 不插标题;无术语 → 不出词汇表;配置全关 → 原样返回。
68+
69+
### 接线(commands_session.rs,双出口同口径)
70+
71+
`convert_to_note` 与 `preview_session_note` 在 `refresh_screen_points` 之后、落库/返回之前调用:
72+
1. 装配 `SessionDetail`(load_note_material 已有 segments/ocr_blocks,补 events——章节真实信号)
73+
2. `analyze_session_opt(detail, profile, ...)` 取 chapters/glossary(profile 从 `session.profile` 解析,回退 Lecture)
74+
3. `outline::detect_outline_smart(ocr_blocks, &result.ocr_screens, ...)` 取章节标题
75+
4. `render_note_structure(...)` 重写 markdown + 更新 stats
76+
77+
**结构渲染实现方式**:章节标题行作为段落数组元素插入(`kept` → `concat::split_transcript_paragraphs_with` 复切段落 → 按章节边界在段落间插入 `## 章节 N` 行 → `concat::assemble_markdown(title, paragraphs, ocr_points)` 复用现有组装 → 尾部追加 `## 词汇表` 块)。与净化管线段落口径一致(同一阈值配置)。
78+
79+
> 预览与落库**同一管线**(REQ-081 契约),结构输出一致性由构造保证。
80+
81+
### 配置(REQ-179)
82+
83+
`NoteStructureConfig`(chapter_headings / glossary_block / glossary_max_terms)**并入 `PurifyConfig`**(嵌套结构字段):复用现有 JSON 校准与装配链(AppState.purify → PurifyEnv),零新装配点;`structure_note.rs` 消费独立类型,模块边界不破。全关 = v0.7.5 输出逐字节一致。
84+
85+
### 元数据
86+
87+
- `RULE_VERSION` 递增:`note-rules-0.7.5` → `note-rules-0.7.6`(REQ-171:产物可回答"用哪版规则生成")
88+
- `StructureStats` 并入 `purify_stats` JSON(前端预览统计卡可显示"章节 ×N / 术语 ×M";旧笔记 NULL 诚实降级)
89+
90+
## 三、范围(需求追溯)
91+
92+
| REQ | 内容 | 验收要点 | 规划状态 |
93+
|-----|------|---------|---------|
94+
| REQ-177 | 章节入笔记:章节边界 → `## 章节 N [MM:SS]` 标题层级;章节名取窗口内 outline 标题(OCR 大字块/屏标题),无命中占位 | 网课档案转笔记带章节标题;边界位置正确(段前插入、段内不切段);口播档案无章节零变化;标题可手动删 | **已排期** |
95+
| REQ-178 | 术语表入笔记:glossary 候选 → 笔记尾部 `## 词汇表` 块(`- 术语(画面 ×N / 语音 ×M)` + [MM:SS] 锚点);自动候选直接入笔记(不强制确认 UI);上限 20 防噪音 | 词汇表块生成正确、排序降序、上限生效、锚点回跳;无术语不出块;块可整体删除 | **已排期** |
96+
| REQ-179 | 结构渲染配置化:NoteStructureConfig(chapter_headings/glossary_block/glossary_max_terms)JSON 可校准(purify_config.json 先例) | 配置全关 = v0.7.5 输出逐字节一致(零回归护栏);JSON 缺失/损坏回退内置默认不阻断 | **已排期** |
97+
| REQ-180 | 结构元数据:StructureStats 并入 purify_stats + RULE_VERSION 递增 note-rules-0.7.6 | 统计与落库一致;旧笔记 NULL 诚实降级 | **已排期** |
98+
| REQ-181 | 黄金语料回归扩展:会话31 夹具 → 期望带结构笔记断言(TDD,先写失败测试) | 新增规则先失败测试再实现;全量回归一键跑;预览/落库双出口逐字节一致 | **已排期** |
99+
100+
## 四、测试与验证
101+
102+
- **Rust 单测**(TDD,AAA 模式):
103+
- 章节插入位置:边界在段前 / 段中 / 无段区域 / 首个边界前(合成会话样本)
104+
- 章节命名:outline 命中取标题 / 未命中占位 / 窗口跨边界归属正确
105+
- 词汇表:排序降序 / 上限截断 / 锚点首现 / 空术语不出块
106+
- 配置:全关输出与 v0.7.5 完全一致(零回归护栏);partial JSON 覆盖语义
107+
- 黄金语料:会话31 样本 → 期望带章节标题 + 词汇表断言(REQ-181)
108+
- 双出口一致:preview_session_note / session_to_note 结构输出逐字节一致
109+
- **前端**:`##` 标题与列表渲染已支持(Markdown 渲染器现有能力)——预计零改动或极小(统计卡加章节/术语计数)
110+
- **真机手动验证清单**(实施完成后执行):
111+
1. 网课会话(会话31)重转笔记:章节标题层级正确、章节名来自画面标题、词汇表块带锚点
112+
2. 口播会话转笔记:无章节标题、无词汇表(零变化)
113+
3. 旧笔记(rule_version NULL):正常展示不报错
114+
4. 回归底线:现有 1053+ 单测全绿 + clippy 新代码零警告 + 前端构建通过
115+
116+
## 五、文件清单(规划)
117+
118+
**Rust 新增**:`structure_note.rs`(纯函数:章节标题插入 + 词汇表块 + 配置 + stats)· `structure_note_tests.rs`(单测独立文件)
119+
120+
**Rust 修改**:`commands_session.rs`(convert_to_note / preview_session_note 接线:detail 装配 + analyze + outline + render)· `note_filter.rs`(RULE_VERSION 递增)· `purify_config.rs`(NoteStructureConfig 嵌套字段——REQ-179)· `types.rs`(StructureStats,如 purify_stats 需新字段——优先零迁移方案)
121+
122+
**前端**:`NotePreviewView.tsx`(统计卡加章节/术语计数,可选)· `types.ts`(FilterStats/StructureStats 新字段)
123+
124+
## 六、本版不做(明确排除)
125+
126+
- 摘要/结论、语义切段、要点/行动项、讲述↔画面时间对齐内联——语义层归 v0.8.0 REQ-141;其余为后续批次候选
127+
- TOC 折叠导航(V1.1 REQ-026 范畴)
128+
- 术语确认 UI(自动候选直入笔记,可手动删)
129+
- 章节速览/思维导图(V1.1 REQ-026)
130+
- 任何 AI 调用(本版纯本地,无密钥/授权/成本依赖)

0 commit comments

Comments
 (0)