fix(writer): 无锚点子章归并父章生成 + 注入后裸重复子节去重

- template_mapper: 按 design §6.5 仅 Heading level<=1 起章,H2/H3 归入
  父章 sub_headings(此前每个 heading 独立成章,无 {{section:id}} 锚点的
  6 个子章生成后被静默丢弃)
- models: ChapterSpec.sub_headings 字段;to_vars 暴露 sub_headings 变量
- writer_agent: prompt 新增【小节约束】(有子节时按小节顺序以 level=2
  heading 组织,不得遗漏或新增)
- docx_injector: 注入后删除同章内与已生成标题同名且完全无内容的模板裸
  H2/H3(保守策略:带内容的模板子节保留)
- 真实试运行验证:7 章 / 无静默丢弃告警 / 14 个 H2 无重复
This commit is contained in:
lhl
2026-08-24 12:23:35 +08:00
parent 80ccc324fc
commit 0a498e4f7a
10 changed files with 235 additions and 2 deletions
+29
View File
@@ -213,3 +213,32 @@ def test_impact_introduction_shows_all_elements():
report = ImpactReport(metadata={}, change_analysis=ca, summary={"new": 2})
impact = _ctx("introduction", "はじめに", source=None, report=report).to_vars()["impact"]
assert "T001" in impact and "F001" in impact
# ---------- 子节结构注入(design.md §6.5H2/H3 归入本章) ----------
def test_chapter_spec_sub_headings_default_empty():
s = ChapterSpec(chapter_id="x", title="X")
assert s.sub_headings == []
def test_to_vars_exposes_sub_headings():
spec = ChapterSpec(
chapter_id="function_list", title="2. 機能一覧",
section_placeholder="section:function_list",
sub_headings=["2.1 機能一覧表", "2.2 機能詳細"],
)
ctx = GenerationContext(
chapter_id=spec.chapter_id, title=spec.title,
template_marker=spec,
structured_source=None, write_rules=[], design_rules=[],
template_styles=set(),
)
v = ctx.to_vars()
assert "2.1 機能一覧表" in v["sub_headings"]
assert "2.2 機能詳細" in v["sub_headings"]
def test_to_vars_sub_headings_empty_when_none():
vars_ = _ctx("db_design", "DB設計").to_vars()
assert vars_["sub_headings"] == ""