@grape_bot 处理issue


@grape_bot 处理issue
[VOD Agent] 已接手 Issue #41 并完成审视。
审视结论:需求清晰,达到可开发标准(无需澄清)。
对照四要素核查:
- 目标:明确——修复
scripts/comparator.py::_diff_shapes同名形状交叉配对问题,消除自比较产生的双向虚假填充色差异 - 现状:明确——上游 main
db6c758可复现,含完整复现脚本与三组对照实验数据 - 期望行为:明确——先建立一对一配对、保留 shape_id 作为候选依据、处理跨文件重新编号、无法唯一配对时明确标记歧义
- 验收标准:可验证——三个自比较控制组(同名不同色不得产生双向差异)+ 单对象修改只报告一次真实变化
重复性核查:与 #16(整页 moved 误报)、#10(位置漏检/拒绝未生效)、#35(三种模式判定不一致)均不重叠,本 Issue 聚焦同名形状配对层,为独立新问题。
已将 Issue body 收敛为结构化模板(目标/现状/期望行为/验收标准/优先级 P1/来源),标签与分配交由 Issue Agent 处理,并已 A2A 交办进入开发流程。


[issue agent] ✅ 该 Issue 已通过深度可开发性分析,评级:ready
分析结论:
- 需求完整性:complete — Bug 类,复现脚本(同文件自比较)与实际输出齐全,含预期 vs 实际对照与三组控制组数据,验收标准可验证
- 技术可行性:feasible — 已核对目标基准 main(db6c758)上
scripts/comparator.py::_diff_shapes(161-170 行)仍为同名双重循环且无已用标记,缺陷在位、未实现;涉及模块:comparator.py、ppt_parser.py - 依赖就绪性:ready — 仅依赖项目既有 python-pptx 与标准库,无新增外部依赖
- 范围确定性:clear — 预估改动:comparator.py(一对一配对逻辑)+ ppt_parser.py(ShapeInfo 保留 shape_id)+ 新增回归测试,复杂度 medium,无架构变更
关联说明:与 #72(同名形状 font_changes 翻倍)同属 _diff_shapes 配对层根因,但本 Issue 范围更完整(自比较双向虚假填充色差异 + shape_id 候选依据 + 歧义标记),建议在同一轮配对层改造中统一处理。与 #16/#10/#35 已确认不重叠。
已生成 Spec 文档并发布在下方,负责人已分配给机器人,将自动启动开发实现(当前 Issue 未绑定专属场景,按默认路由交办 coding agent)。


[issue agent] 📋 Spec Document
Spec: Issue #41 — 同名形状被交叉配对:同一个 PPTX 自比较也报告两条不存在的填充色修改
Generated by Issue Agent | Developability: ready | 2026-10-20 | 目标分支:main(基准 db6c758)
Objective
- 要构建什么:修复
scripts/comparator.py::_diff_shapes的同名形状交叉配对缺陷——同一 PPTX 自比较时不再产生两条互为反向的虚假填充色差异;同时为形状配对建立一对一机制,处理跨文件 shape_id 重新编号与同名退化情况。 - 为什么:误报直接污染三模式(A/B/C)的差异报告与审阅流程,用户会被不存在的"双向颜色修改"误导去核对;自比较(同文件)本应是 0 差异的兜底场景却报 modified=1。
- 用户是谁:使用 PPT 修改前后对比工具(三模式)的所有用户。
- 成功标准:
- 三个自比较控制组结果符合验收标准(同名不同色不再产生双向差异)
- 单对象真实修改只报告一次
- 全部现有测试通过,新增回归测试覆盖控制组
Scope
In Scope
comparator.py::_diff_shapes:从名字笛卡尔积改为一对一配对(候选优先级:shape_id → name → 内容相似度),配对后标记已用;无法唯一配对时降级为有限候选集比较并标记歧义,而非全量交叉ppt_parser.py::ShapeInfo:新增shape_id字段并纳入to_dict(),作为配对候选依据(解析层保留,不改变现有字段语义)- 回归测试:三个自比较控制组 + 单对象修改只报一次
- 与 #72 的协调:#72(同名 font_changes 翻倍)与本 Issue 同根因同函数,本 Spec 的一对一配对改造应同时消除 #72 的重复 FontChange;实现时以本 Spec 为准做配对层统一修复
Out of Scope
- #16 的整页 moved 状态误报(独立缺陷,另案处理)
- #10 的对象位置漏检/Reject 未生效、#35 的三模式覆盖差异
- #82 的主题色(schemeClr)解析缺失——本 Spec 不改颜色解析层,仅改配对层
- 三模式(A/B/C)输出层展示逻辑调整
Technical Approach
方案概述
在 _diff_shapes 中以"候选键 → 一对一贪心/最优配对 → 已用标记"替换现有双重循环,候选键优先级为 shape_id 精确匹配、name 匹配(同名多个时进入歧义处理)、位置+几何相似度兜底。
实现路径
ppt_parser.py:ShapeInfo增加shape_id字段(解析shape.shape_id),to_dict()一并输出;确认SlideContent.to_dict()等价性结论不被破坏(控制组已验证解析前后 to_dict 完全相等,新增字段后需保持同名同色控制组 modified=0)comparator.py:重写_diff_shapes——构建候选集(shape_id → name → 相似度),执行一对一配对(每个 old shape 至多配一个 new shape),已配对标记防重;唯一配对走现有_diff_font_runs/_diff_shape_styles- 歧义处理:同名候选多于一时,按几何/内容确定最优配对;无法消歧时将 shape_name 标注歧义(如
SharedName(歧义)),仅对唯一配对报告样式差异 - 新增回归测试
test_issue_41.py(或并入现有测试目录):覆盖三个控制组与单对象修改场景
关键设计决策
| 决策 | 选项 | 选择 | 理由 |
|---|---|---|---|
| 配对键优先级 | A. 仅 name;B. shape_id→name→相似度 | B | shape_id 是 OOXML 稳定标识;name 常重复(如 SharedName);跨文件重编号需相似度兜底 |
| 自比较场景处理 | A. 文件级哈希短路;B. 配对层修复 | B | 根因在配对层,文件级短路治标且不解决同名交叉的普遍场景 |
| 无法唯一配对 | A. 静默跳过;B. 标记歧义 | B | Issue 明确要求"无法唯一配对时明确标记歧义",静默会引入新漏检 |
| #72 联动 | A. 仅修 #41 场景;B. 配对层统一修复 | B | 同根因同函数,统一修复避免二次返工 |
Affected Modules
| 模块 | 改动类型 | 说明 |
|---|---|---|
scripts/comparator.py |
修改 | _diff_shapes 一对一配对重写 + 歧义标记 |
scripts/ppt_parser.py |
修改 | ShapeInfo 新增 shape_id 字段 |
测试(新增 tests/test_issue_41.py 或对齐现有测试布局) |
新增 | 三控制组 + 单对象修改回归 |
依赖关系
ppt_parser.parse_pptx→comparator.compare_pptx(现有调用链不变);ShapeInfo结构变更向下兼容(新增可选字段)- 三模式(
pptx_annotator.py/ppt_review.py/main.py)经compare_pptx消费配对结果,自动受益,无需改动
Acceptance Criteria
Risks & Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| 相似度兜底配对引入新误配(跨文件重编号场景) | Med | 相似度阈值保守设定;无法唯一配对必须落歧义标记而非猜测 |
ShapeInfo 字段变更影响依赖 to_dict() 的既有比较逻辑 |
Med | 新增可选字段向后兼容;回归测试覆盖三控制组 to_dict 等价性 |
| #72 并行开发冲突(同函数改动) | Med | 以本 Spec 配对层统一修复为准;#72 验收由本 Spec 一并覆盖 |
| 配对层重写影响三模式输出一致性 | Low | 三模式共用 compare_pptx,无模式侧改动;现有测试 + 新增回归兜底 |
Open Questions
- 无


[Coding Agent] 已完成需求文档与方案设计,进入编码(TDD:先写失败回归测试再实现):
- 需求文档:
docs/issue-41/spec.md(问题/根因/验收标准/非目标) - 方案设计:
docs/issue-41/plan.md(配对算法:shape_id → name → 几何相似度,一对一贪心配对 + 已用标记;无法消歧落歧义标记;#72 同根因一并修复) - 任务拆解:
docs/issue-41/task.md
按 Issue Agent 已评审的 Spec 执行,复杂度中等,无新增外部依赖。


[Coding Agent] ✅ 已完成实现,请审查 PR #27(base=main,head=feat/issue-41,2 个原子提交:881d4b4 解析层 shape_id / 22d4aea 一对一配对重写)。
修复内容:
ppt_parser.py:ShapeInfo新增shape_id并纳入to_dict()comparator.py::_diff_shapes:一对一配对((name, shape_id) 精确匹配 → 唯一名直配 → 重名几何相似度贪心 + 并列即歧义),无法唯一配对落(歧义)标记,禁止笛卡尔积;同根因一并修复 #72 的 font_changes 翻倍
验证结果:
- 新增
tests/test_issue_41.py12 用例全部通过(三控制组 / 单对象只报一次 / #72 / 重编号 / 歧义 / to_dict 等价性) - Issue 原始复现脚本核验:自比较 modified=0、style_changes=0(修复前 modified=1 + 2 条反向填充色差异)
- 三模式经
compare_pptx自动受益,模式 C(HTML 报告)冒烟通过
请审查后合入;后续将 A2A 交 QA 审查。


目标
修复形状级比较中同名形状被交叉配对的问题:同一个 PPTX 自比较也会报告两条不存在的填充色修改,消除由此产生的虚假样式差异。
现状
上游 main:
db6c75892650854abf663c91b66ead486fde1299。在核验形状级差异时发现一个可独立复现的配对问题,使用的全是合成矩形,没有业务 PPT 或个人资料。scripts/comparator.py::_diff_shapes对 old_shapes 和 new_shapes 双重循环,仅以os_.name == ns_.name为条件,且匹配后不标记已使用。因此相同名字的两个对象会产生四个配对;old-A/new-B 与 old-B/new-A 造成虚假样式差异。当前解析模型没有保留 shape_id,不能仅在输出端隐藏这两条来解决。复现步骤
下面代码放在仓库根目录运行,使用项目已有的 python-pptx 依赖即可。重点是最后两次 parse 读取同一个文件,并没有修改后版本。
import sys from pathlib import Path from pptx import Presentation from pptx.enum.shapes import MSO_SHAPE from pptx.dml.color import RGBColor from pptx.util import Inches sys.path.insert(0, str(Path('scripts').resolve())) from ppt_parser import parse_pptx from comparator import compare_pptx, generate_summary p = Presentation() s = p.slides.add_slide(p.slide_layouts[6]) for i, color in enumerate(((0, 100, 200), (200, 100, 0))): box = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, Inches(1 + 3*i), Inches(1), Inches(2), Inches(1)) box.name = 'SharedName' box.text = 'Unchanged sample' box.fill.solid() box.fill.fore_color.rgb = RGBColor(*color) print(box.shape_id, box.name) p.save('same.pptx') result = compare_pptx(parse_pptx('same.pptx'), parse_pptx('same.pptx')) print(generate_summary(result)) for c in result[0].style_changes: print(c.shape_name, c.attribute, c.old_value, c.new_value)实际两个形状的 shape_id 分别为 2 和 3;显示名都为 SharedName。自比较却得到:
控制组
三组解析前后的
SlideContent.to_dict()都完全相等。控制组仍有既有 #16 的 moved 状态问题,本报告没有把它作为新问题;本次新增证据是共享形状比较层生成了不存在的双向颜色差异。也不同于 #10 的对象位置漏检和 #35 的三种输出模式覆盖差异。期望行为
验收标准
优先级
P1(重要)
来源:Issue #41 原始报告(hh11211sa 实测诊断与建议,尚未声称已修复)
VOD 审视结构化