docs: Phase3 spec 工程审阅修正(做成说明书 ref→write、列表双通道、显式角色参数)
This commit is contained in:
@@ -60,3 +60,4 @@
|
||||
| 2026-08-09 | 测试验证 | 新增 api §7 ↔ 异常树 error_code 一致性门禁测试(防文档漂移)。新建 tests/test_api_design_consistency.py(4 用例:树→文档 / 文档→树双向断言 + 行数护栏 / 空解析护栏);首次运行 RED(行数护栏 ==5 与事实 4 冲突,文档与异常各为 4 条/4 个子类,双向一致)→ 修正护栏为 4 → GREEN(聚焦 4 passed);pytest 全量 132 passed 覆盖 100.00%(803 stmts/188 br),fail_under=99 达标;提交见 git log | tests/test_api_design_consistency.py, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-09 | 测试验证 | 一致性门禁最终评审收尾修复(Important x1 + Minor x3):① plan 文档 Interfaces 段 L311-314「五行 LLM 行」→「四行」(与 ==4 护栏一致);② 测试文件补尾随换行(末字节 " → \n);③ 断言消息改「异常类存在文档未登记或来源类名失配的 error_code」(覆盖双失败场景);④ _LLM_ROW_RE 加正则隐式限域注释。覆盖测试 4 passed;pytest 全量 132 passed 覆盖 100.00%,fail_under=99 达标 | docs/superpowers/plans/2026-08-09-error-code-consistency-test.md, tests/test_api_design_consistency.py, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-09 | 架构设计 | Phase3 Word 解析优先设计(brainstorming):范围澄清(Word 解析优先=3.1/3.2/3.6/3.7,PPT/现有系统探索后续;规则分类按来源映射零LLM;SourceAggregator 全量整合 StructuredSource;样式名级提取;方案A 三模块门面聚合);输出设计文档 docs/superpowers/specs/2026-08-09-phase3-word-parser-design.md | docs/superpowers/specs/2026-08-09-phase3-word-parser-design.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
| 2026-08-09 | 架构设计 | Phase3 spec 工程完备性审阅(用户审阅关卡):实测 samples 3 个 docx(模板7H1+占位符+1书签、记入规则全 H1+・列表、说明书纯文本+H1);修正 P0-1 做成说明书分类 ref→write(对齐 api-design §2.2 write_instruction RAG 归类 Type A 写入规则);P1-1 列表检测双通道(・前缀+List Bullet 样式);P1-2 SourceParser 显式角色参数对齐 file_type 枚举;P1-3 fail_under=99 覆盖路径;统一占位符正则;新增 docx_helpers.py 测试基建 | docs/superpowers/specs/2026-08-09-phase3-word-parser-design.md, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
|
||||
|
||||
@@ -52,12 +52,14 @@ parsers/
|
||||
**输入:** docx 路径(`str | Path`)
|
||||
**输出:** `ParsedTemplate{file_name, sections, placeholders, styles}`(复用 data_models 类型)
|
||||
|
||||
**占位符统一正则(§3.2 与 §3.6 共用同一契约):** `{{([a-z][a-z0-9_]*)(?::([a-z][a-z0-9_]*))?}}`——匹配两种形态:带章节名 `{{section:introduction}}`(组1=section,组2=章节名)与封面型 `{{doc_title}}`(仅组1=键名)。不匹配该正则的 `{{...}}` 视为普通正文。
|
||||
|
||||
提取逻辑(`python-docx`):
|
||||
|
||||
| 产物 | 提取方式 | 说明 |
|
||||
|------|---------|------|
|
||||
| `sections` | 遍历文档段落,识别 Heading 样式的段落 → `ChapterMarker(type="heading", name=段落文本, level=大纲级别)`;遍历书签(`bookmarkStart`)→ `type="bookmark"`;遍历占位符 → `type="placeholder"` | `ChapterMarker.type` 取值 `"heading" | "bookmark" | "placeholder"` |
|
||||
| `placeholders` | 正则识别 `{{section:xxx}}` 与封面型 `{{doc_title}}` / `{{version}}` / `{{created_at}}` → `{占位符名: 出现位置或上下文}` | 占位符名去重 |
|
||||
| `placeholders` | 用统一正则识别上述两种占位符 → `{占位符名: 出现位置或上下文}` | 占位符名去重(`section:introduction` / `doc_title` 等) |
|
||||
| `styles` | 收集文档命名样式 + 各段落实际使用的样式名 → 去重集合 | **样式名级**(不提取字号/颜色/字体明细) |
|
||||
|
||||
### 3.3 RuleDocParser
|
||||
@@ -72,47 +74,56 @@ Markdown 化规则:
|
||||
| Heading 1/2/3 | `#` / `##` / `###` 标题行 |
|
||||
| 普通段落 | 文本行 |
|
||||
| 表格 | GFM 表格(表头 + 分隔行 + 数据行) |
|
||||
| 列表(List Bullet/Number) | `- ` 项 / 编号项 |
|
||||
| 列表项 | `- ` 项(检测双通道:样式名含 List Bullet/List Number **或** 文本以 `・`/`-`/`•` 前缀开头——真实样本列表项为 `Normal` 样式 + `・` 前缀,样式名通道不足以命中) |
|
||||
| 空段 | 空行 |
|
||||
|
||||
- `hash` = 文件内容 sha256 hex(供阶段 4 规则版本管理)
|
||||
- `hash` = 文件内容 sha256 hex(供阶段 4 规则版本管理,即 rag-layer §5 文档级增量更新比对键)
|
||||
- `file_type` 固定 `"word"`
|
||||
|
||||
**来源映射(分类策略,零 LLM):**
|
||||
|
||||
| 输入文件 | category |
|
||||
|---------|----------|
|
||||
| `記入規則.docx` | `write` |
|
||||
| `概要設計做成説明書.docx` | `ref` |
|
||||
| 输入文件 | category | 依据 |
|
||||
|---------|----------|------|
|
||||
| `記入規則.docx` | `write` | 写入规则(Type A) |
|
||||
| `概要設計做成説明書.docx` | `write` | 做成说明书 = 各章作成指引,规范明确归类 **Type A 写入规则**(api-design §2.2 `write_instruction`、rag-layer §1.1) |
|
||||
|
||||
**明确的策略:** `rule_paths` 仅接受 `.docx` 规则文档;类别由门面按文件名映射(`記入規則*` → `write`,`*説明書*` → `ref`,其余文件名 → `write` 兜底)。Excel 图表规则(`図表規則.xlsx`)本轮**不纳入** `rule_docs`(Excel 规则解析留给后续迭代)。
|
||||
**类别语义(对齐 design §5.3 / rag-layer §1.1):**
|
||||
- `write` — 写入规则(记入规则、图表规则、字体/格式规范)→ Writer Agent 每章生成时检索(Type A)
|
||||
- `design` — 设计规则(架构约束、安全要求、设计方针)→ Impact Agent 关联推理时参考(Type B)
|
||||
- `ref` — 参考设计文档(过往概要设计书、设计决策记录),**可选增强**(Type C)
|
||||
|
||||
本轮样本三类 docx 全部为 `write`;`design`/`ref` 类别暂由其它输入类型(后续 Excel 图表规则/现系统设计书)填充。
|
||||
|
||||
**明确的策略:** `rule_paths` 仅接受 `.docx` 规则文档;类别由门面按来源映射(`記入規則*` → `write`,`write_instruction`(做成说明书)→ `write`,其余文件名 → `write` 兜底)。Excel 图表规则(`図表規則.xlsx`)本轮**不纳入** `rule_docs`(Excel 规则解析留给后续迭代)。
|
||||
|
||||
### 3.4 SourceParser 门面(3.6 SourceAggregator)
|
||||
|
||||
**输入:**
|
||||
- `requirement_paths: list[str | Path]` — 要件定义 Excel 列表
|
||||
- `template_path: str | Path | None` — 概要设计模板 docx
|
||||
- `rule_paths: list[str | Path]` — 规则文档列表(**仅 docx**)
|
||||
- `requirement_paths: list[str | Path]` — 要件定义 Excel 列表(api-design `requirements`)
|
||||
- `template_path: str | Path | None` — 概要设计模板 docx(api-design `template`)
|
||||
- `write_instruction_paths: list[str | Path]` — 做成说明书列表(api-design `write_instruction`,均为 `.docx`)
|
||||
- `rule_paths: list[str | Path]` — 记入规则等规则文档列表(api-design `rules`,**仅 docx**)
|
||||
|
||||
**类别映射(内置于门面,零 LLM):** `rule_paths` 中文件名含 `記入規則` → `write`;含 `説明書` → `ref`;其它 → `write` 兜底。
|
||||
**类别映射(显式角色,零 LLM):** `write_instruction_paths` 中的文档固定 `category="write"`(对齐 api-design §2.2「write_instruction RAG 归类 Type A 写入规则」);`rule_paths` 中文件名含 `記入規則` → `write`,其它 → `write` 兜底。**不做基于内容/名字的隐式猜测**——角色由调用方按 api-design file_type 语义显式传入。
|
||||
|
||||
**路由:**
|
||||
|
||||
| 扩展名/角色 | 解析器 | 产物 |
|
||||
|------------|--------|------|
|
||||
| `.xlsx` | 现有 `ExcelParser` | `tables` + `comments` |
|
||||
| `.xlsx`(requirement_paths) | 现有 `ExcelParser` | `tables` + `comments` |
|
||||
| 模板 docx(template_path) | `WordTemplateParser` | `template: ParsedTemplate` |
|
||||
| 规则 docx(rule_paths) | `RuleDocParser` | `rule_docs: list[RuleDocument]` |
|
||||
| 做成说明书 docx(write_instruction_paths) | `RuleDocParser`(category=write) | `rule_docs: list[RuleDocument]` |
|
||||
| 规则 docx(rule_paths) | `RuleDocParser`(category=write) | `rule_docs: list[RuleDocument]` |
|
||||
|
||||
**输出:** `StructuredSource{tables, template, rule_docs, image_analyses=[], existing_system=None, comments}`(`image_analyses`/`existing_system` 本轮恒为空/None,类型字段保留)。
|
||||
|
||||
### 3.5 数据流
|
||||
|
||||
```
|
||||
samples/*.xlsx ─────────────► ExcelParser ─────► tables / comments
|
||||
samples/テンプレート.docx ──► WordTemplateParser ─► template: ParsedTemplate ─┐
|
||||
samples/記入規則.docx ──────► RuleDocParser ────► rule_docs: [RuleDocument] ──┼─► StructuredSource
|
||||
┘
|
||||
samples/*.xlsx ────────────────► ExcelParser ───────► tables / comments
|
||||
samples/テンプレート.docx ─────► WordTemplateParser ─► template: ParsedTemplate ─┐
|
||||
samples/記入規則.docx ─────────► RuleDocParser ─────► rule_docs(write) ───────────┼─► StructuredSource
|
||||
samples/概要設計做成説明書.docx ─► RuleDocParser ─────► rule_docs(write) ───────────┘
|
||||
```
|
||||
|
||||
### 3.6 错误处理
|
||||
@@ -120,35 +131,36 @@ samples/記入規則.docx ──────► RuleDocParser ────► ru
|
||||
| 场景 | 行为 |
|
||||
|------|------|
|
||||
| 文件不存在 | 抛出 `FileNotFoundError`(消息含路径,便于定位) |
|
||||
| 模板无 Heading / 空文档 | 返回空 `sections`/`placeholders`,不崩溃(与 ExcelParser 的 skipped 哲学一致) |
|
||||
| 非法占位符格式(非 `{{section:xxx}}` / `{{doc_*}}`) | 不识别为占位符,正文文本原样保留 |
|
||||
| 模板无 Heading / 空文档 | WordTemplateParser 返回空 `sections`/`placeholders`;RuleDocParser 返回空 `markdown_content`。均不崩溃(与 ExcelParser 的 skipped 哲学一致) |
|
||||
| 非法占位符格式(不匹配统一正则的 `{{...}}`) | 不识别为占位符,正文文本原样保留 |
|
||||
| 未知扩展名(如 `.txt`/`.md`) | `SourceParser` 路由阶段报错:`ValueError("不支持的文件类型: ...")` |
|
||||
| docx 损坏 | 透出 python-docx 异常(PackageNotFoundError),测试不吞 |
|
||||
|
||||
### 3.7 与现有代码的关系
|
||||
|
||||
- **不改** `excel_parser.py`、`data_models.py`、`pyproject.toml`、任何现有测试
|
||||
- 只新增 `src` 3 个生产模块 + 3 个测试文件 + 扩展 `test_real_samples.py`
|
||||
- 只新增 `src` 3 个生产模块 + 4 个测试文件(含 docx_helpers.py)+ 扩展 `test_real_samples.py`
|
||||
- 提交消息前缀:`feat:`(生产实现)/ `test:`(门禁测试)/ `docs:`(本文档与 AI 日志)
|
||||
|
||||
## 4. 文件定位与测试先例
|
||||
|
||||
- 单元测试沿用 `tests/test_real_samples.py:7` 的定位方式:`Path(__file__).resolve().parents[1] / "samples"`,样本缺失 `pytest.skip`
|
||||
- 临时 docx 构造(单元测试):用 `python-docx` 在 `tmp_path` 生成内存文档(Heading/表格/占位符/书签),不依赖真实样本
|
||||
- 全量回归命令:`python -m pytest -q`(保持 ≥ 132 passed / 100.00%)
|
||||
- 新建 `tests/docx_helpers.py` 测试基建(与现有 `tests/excel_helpers.py` 对称):`new_document()` 内存构造 / `save_document(tmp_path, doc)` 落盘,供 3 个 Word 测试文件复用;覆盖 Heading/表格/列表(`・` 前缀 + List Bullet 样式双通道)/占位符/书签/空文档等模板
|
||||
- 新模块覆盖路径(P1-3,fail_under=99 达成路径):WordTemplateParser 空文档护栏、非模板 docx(无 Heading)、占位符边界(非法格式原样保留);RuleDocParser 列表双通道命中/未命中、空文档、hash 稳定性;SourceParser 未知扩展名报错、template_path=None、write_instruction/rule 双通道合并、Excel+Word 全量组装
|
||||
- 全量回归命令:`python -m pytest -q`(保持 ≥ 132 passed / 100.00% 覆盖 / fail_under=99 红线不破)
|
||||
|
||||
## 5. 验收标准
|
||||
|
||||
1. `python -m pytest tests/test_word_template_parser.py tests/test_rule_doc_parser.py tests/test_source_aggregator.py tests/test_real_samples.py -v` 全绿
|
||||
2. 全量回归 `python -m pytest -q` ≥ 132 passed(新增用例后 ≥ 现有基线 + 新增数)/ 100.00% 覆盖
|
||||
3. 真实样本:模板 docx 解析出 7 个 H1 章(はじめに…バッチ一覧)+ 占位符;记入规则 docx 产出 category="write" 的 markdown
|
||||
4. 门面全量组装:`StructuredSource.tables` 非空、`template` 非 None、`rule_docs` 含 write/ref 两类
|
||||
2. 全量回归 `python -m pytest -q` ≥ 132 passed(新增用例后 ≥ 现有基线 + 新增数)/ 100.00% 覆盖 / fail_under=99 达标
|
||||
3. 真实样本:模板 docx 解析出 7 个 H1 章(はじめに…バッチ一覧)+ 占位符(section:* 与 doc_title)+ 1 个书签;记入规则 docx 产出 category="write" 的 markdown(Heading→`#`、`・` 列表→`- `)
|
||||
4. 门面全量组装:`StructuredSource.tables` 非空、`template` 非 None、`rule_docs` 全部 `category="write"` 且 ≥2 条(记入规则 + 做成说明书)
|
||||
5. 手工破坏验证(可选):删除模板占位符段落 → 占位符断言变红;恢复正常
|
||||
|
||||
## 6. 影响面
|
||||
|
||||
- 新增生产文件 3 个:`src/genesis/parsers/word_template_parser.py`、`rule_doc_parser.py`、`source_aggregator.py`
|
||||
- 新增测试文件 3 个:`tests/test_word_template_parser.py`、`tests/test_rule_doc_parser.py`、`tests/test_source_aggregator.py`
|
||||
- 新增测试文件 4 个:`tests/docx_helpers.py`(基建)、`tests/test_word_template_parser.py`、`tests/test_rule_doc_parser.py`、`tests/test_source_aggregator.py`
|
||||
- 修改文件:`tests/test_real_samples.py`(追加 3 个 Word 样本用例)、`_AI_USAGE_LOG.md`(追加日志行)
|
||||
- 提交纪律:分任务提交(feat/test/docs/chore 各自独立 commit)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user