diff --git a/research-wiki/plans/2026-07-16-preflight-wp1-asset-migration.md b/research-wiki/plans/2026-07-16-preflight-wp1-asset-migration.md index 0e057f2..3b5672e 100644 --- a/research-wiki/plans/2026-07-16-preflight-wp1-asset-migration.md +++ b/research-wiki/plans/2026-07-16-preflight-wp1-asset-migration.md @@ -37,19 +37,7 @@ - Create: `prompts/evolve_skill.md`、`prompts/evolve_system.md`、`prompts/evolve_tool.md`、`prompts/evolve_rank.md`、`prompts/slow_momentum.md`(从 TRM4 拷贝) - Test: `tests/unit/test_evolve_prompts_present.py` -- [ ] **Step 1: 拷贝 5 个模板** - -Run: -```bash -cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_skill.md prompts/evolve_skill.md -cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_system.md prompts/evolve_system.md -cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_tool.md prompts/evolve_tool.md -cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_rank.md prompts/evolve_rank.md -cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/slow_momentum.md prompts/slow_momentum.md -``` -Expected: 5 文件存在于 `prompts/`。 - -- [ ] **Step 2: 写契约冒烟测试(先失败)** +- [ ] **Step 1: 写契约冒烟测试(先失败)** `tests/unit/test_evolve_prompts_present.py`: ```python @@ -80,17 +68,34 @@ def test_evolve_template_present_and_contract(name: str, required_tokens: list[s assert token in text, f"{name} 缺输出契约关键词 {token!r}(与解析代码不对齐)" ``` -- [ ] **Step 3: 运行确认通过(模板已在 Step 1 拷入)** +- [ ] **Step 2: 运行确认失败(模板尚未迁移)** + +Run: `conda run -n Video-Tree-TRM python -m pytest tests/unit/test_evolve_prompts_present.py -v` +Expected: 5 参数化用例全 FAIL(`AssertionError: 缺模板: prompts/evolve_skill.md` 等;TRM5 当前无这 5 个模板)。 + +- [ ] **Step 3: 拷贝 5 个模板** + +Run: +```bash +cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_skill.md prompts/evolve_skill.md +cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_system.md prompts/evolve_system.md +cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_tool.md prompts/evolve_tool.md +cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/evolve_rank.md prompts/evolve_rank.md +cp /home/iomgaa/Projects/Video-Tree-TRM4/prompts/slow_momentum.md prompts/slow_momentum.md +``` +Expected: 5 文件存在于 `prompts/`。 + +- [ ] **Step 4: 运行确认通过** Run: `conda run -n Video-Tree-TRM python -m pytest tests/unit/test_evolve_prompts_present.py -v` Expected: 5 参数化用例全 PASS。若 evolve_tool.md 缺 `edits_extract`/`edits_verify` 则契约不符——停止并逐行比对 TRM4 源。 -- [ ] **Step 4: 保真检查点** +- [ ] **Step 5: 保真检查点** Run: `conda run -n Video-Tree-TRM python -c "print('edits_extract' in open('prompts/evolve_tool.md').read() and 'edits_verify' in open('prompts/evolve_tool.md').read())"` Expected: `True`(对齐 `evolve.py:1433-1435` 的 `parsed["edits_extract"]`/`parsed["edits_verify"]`)。 -- [ ] **Step 5: 提交** +- [ ] **Step 6: 提交** ```bash git add prompts/evolve_skill.md prompts/evolve_system.md prompts/evolve_tool.md prompts/evolve_rank.md prompts/slow_momentum.md tests/unit/test_evolve_prompts_present.py @@ -126,14 +131,15 @@ git commit -m "feat: migrate 5 evolve/momentum templates from TRM4 (algo #8)" `app/harness/video_split_cli.py`: - `_load_diagnose_prompts` 删行 ` span_eval_user=_read("span_eval_user.md"),`(L374) -- [ ] **Step 3: 删测试 fixture 对死字段的赋值** +- [ ] **Step 3: 删测试 fixture 对死字段的赋值 + 更新 docstring** -- `tests/unit/test_evolve.py:682` 删行 ` consolidate_system="cons",` +- `tests/unit/test_evolve.py:684` 删行 ` consolidate_system="cons",` - `tests/unit/test_diagnose.py:753` 删行 ` span_eval_user="",` - `tests/unit/test_evolution_types.py:352` 删行 ` span_eval_user="p4",` - `tests/unit/test_evolution_types.py:370` 删行 ` consolidate_system="consolidate_tmpl",` +- `tests/unit/test_evolution_types.py:347` 的文档字符串"DiagnosePrompts 8 个模板字段"改为"7 个";`:364` 的"EvolvePrompts 5 个模板字段"改为"4 个"(删字段后数量变化)。 -注:`test_evolution_types.py` 可能有断言逐字段比对;若该测试断言字段数量或逐字段相等,同步移除对两个死字段的断言(读该测试确认,删净引用)。 +注:`test_evolution_types.py` 若有断言逐字段比对或字段计数,同步移除对两个死字段的断言(读该测试确认,删净引用)。上述行号以当前代码为准,实现前 `grep -n consolidate_system\|span_eval_user tests/unit/test_evolution_types.py` 复核。 - [ ] **Step 4: 运行相关测试确认通过** @@ -142,7 +148,7 @@ Expected: 全 PASS(无 `TypeError: unexpected keyword argument` / 无 `missing - [ ] **Step 5: 全库确认无残留引用** -Run: `conda run -n Video-Tree-TRM python -c "import subprocess,sys; r=subprocess.run(['grep','-rn','consolidate_system\|span_eval_user','core/','app/','tests/'],capture_output=True,text=True); print(r.stdout)"` +Run: `conda run -n Video-Tree-TRM python -c "import subprocess; r=subprocess.run(['grep','-rn','consolidate_system\|span_eval_user','core/','app/','adapters/','tests/'],capture_output=True,text=True); print(r.stdout)"` Expected: 空输出(`consolidate_appendix` 用内联 `_CONSOLIDATE_SYSTEM` 不算 `consolidate_system` 字段引用;若出现请确认非 dataclass 字段引用)。 - [ ] **Step 6: 提交** @@ -161,28 +167,39 @@ git commit -m "refactor: drop dead prompt fields consolidate_system/span_eval_us - Modify: `app/harness/video_split_cli.py:365-367` - Test: `tests/unit/test_evolve_prompts_present.py`(追加) -- [ ] **Step 1: 追加 fail-loud 测试(先失败)** +- [ ] **Step 1: 追加 fail-loud 测试(直接调真实加载器)** -在 `tests/unit/test_evolve_prompts_present.py` 追加: +在 `tests/unit/test_evolve_prompts_present.py` 追加——直接驱动真实 loader(不复制 _read 逻辑),在无模板的空 cwd 下断言 `FileNotFoundError`: ```python -def test_loader_fail_loud_on_missing_template(tmp_path, monkeypatch): - """加载器遇缺失模板必须抛 FileNotFoundError,不静默返回空串。""" - monkeypatch.chdir(tmp_path) # 空目录下无 prompts/,_read 应 fail-loud - (tmp_path / "prompts").mkdir() - from app.harness.runner import Runner - - # 直接测私有 _read 语义:借最小构造不便,改测行为——缺文件应 raise - def _read(name: str) -> str: - p = Path("prompts") / name - if not p.exists(): - raise FileNotFoundError(f"缺进化/诊断模板: {p}(请从 TRM4 迁移或检查 prompts/)") - return p.read_text(encoding="utf-8") +def test_video_split_loader_fail_loud_on_missing(tmp_path, monkeypatch): + """video_split_cli 的真实 diagnose 加载器缺模板必须 FileNotFoundError。""" + monkeypatch.chdir(tmp_path) # 空目录,无 prompts/*.md + from app.harness.video_split_cli import _load_diagnose_prompts with pytest.raises(FileNotFoundError, match="缺进化/诊断模板"): - _read("evolve_skill.md") -``` + _load_diagnose_prompts() -> 说明:`_read` 是嵌套闭包不易直接导入,此测试固化期望语义(缺文件 raise + 消息含"缺进化/诊断模板");Step 2 把三处闭包改成同款实现,集成层由 `test_harness_runner.py` 现有加载路径覆盖。 + +def test_runner_evolve_loader_fail_loud_on_missing(tmp_path, monkeypatch): + """runner 的真实 evolve 加载器缺模板必须 FileNotFoundError。""" + monkeypatch.chdir(tmp_path) + from app.harness.runner import Runner + + r = object.__new__(Runner) # 绕过 __init__,仅测无状态加载器方法 + with pytest.raises(FileNotFoundError, match="缺进化/诊断模板"): + r._load_evolve_prompts() + + +def test_runner_diagnose_loader_fail_loud_on_missing(tmp_path, monkeypatch): + """runner 的真实 diagnose 加载器缺模板必须 FileNotFoundError。""" + monkeypatch.chdir(tmp_path) + from app.harness.runner import Runner + + r = object.__new__(Runner) + with pytest.raises(FileNotFoundError, match="缺进化/诊断模板"): + r._load_diagnose_prompts() +``` +> 这三个测试直接调真实 loader(`_load_evolve_prompts`/`_load_diagnose_prompts` 无 self 状态依赖,`object.__new__` 可安全调用);修复前静默返回空串不抛,故 Step 2 前必 FAIL。 - [ ] **Step 2: 三处 `_read` 闭包改 fail-loud** @@ -207,10 +224,11 @@ def test_loader_fail_loud_on_missing_template(tmp_path, monkeypatch): Run: `conda run -n Video-Tree-TRM python -m pytest tests/unit/test_evolve_prompts_present.py -v` Expected: 全 PASS。 -- [ ] **Step 4: 运行 runner 加载路径回归** +- [ ] **Step 4: runner 其他行为回归(非 fail-loud 验证)** +fail-loud 已由 Step 3 的三个真实 loader 测试验证;此步仅确认模板迁移 + loader 改动未破坏 runner 其他行为。 Run: `conda run -n Video-Tree-TRM python -m pytest tests/unit/test_harness_runner.py -q` -Expected: 全 PASS(模板已迁移,真实加载不再命中缺失分支)。 +Expected: 全 PASS(模板已迁移,真实加载走成功分支)。 - [ ] **Step 5: 提交**