Parent epic: #11
Depends on: none for this issue, but integration must declare whether it is based on main or PR #10
Estimate: ~1 dev-day (~6h Opus-assisted)
范围 Scope
把当前硬编码 ICLR2026 的逻辑抽成可插拔 TemplateAdapter 接口;新建 VenueRouter 评分模块;用 venues.yaml 让 venue 列表可配置。
改动 Changes
新建文件
agents/manuscript_templates/__init__.py — TemplateAdapter 基类(抽象方法:copy_files / inject_preamble / normalize_source / bibstyle_name / max_pages)
agents/manuscript_templates/iclr2026.py — 搬现有 ICLR 逻辑
agents/manuscript_templates/arxiv_plain.py — 用 third_party/paperorchestra_arxiv2604/ 资产
agents/venue_router.py — 规则评分(仿 agenda_selector.py 结构)
db/schema_venue_routing.sql — manuscript_venue_selections 表
manuscript_venues/venues_v1.yaml — 含 ICLR + arXiv 2 venue 完整配置(schema_version、triggers、rejects、template_id、max_pages)
编辑文件
agents/paper_orchestra_pipeline.py — 4 处替换:
_copy_iclr2026_template_files → adapter.copy_files
_ensure_iclr2026_preamble → adapter.inject_preamble
normalize_latex_source(force_iclr2026=...) → adapter.normalize_source
assemble_main_tex 内的 venue 字段从 hardcoded → adapter.venue_label
db/database.py:init_db() — 自动 apply 新 schema
config.py — 新增 VENUES_CONFIG_PATH env / toml 入口
验收 Acceptance
AI 可验收证据包(必须)
PR 必须生成:
artifacts/d1_template_router_acceptance.json
字段至少包含:
{
"base_ref": "...",
"commit": "...",
"adapter_contract": ["copy_files", "inject_preamble", "normalize_source", "bibstyle_name", "max_pages"],
"registered_venues": ["iclr2026", "arxiv_plain"],
"router_fixture_results": [
{"fixture": "benchmark_state", "chosen": "iclr2026", "score": 0.0, "rejected": []},
{"fixture": "theory_only_state", "chosen": "arxiv_plain", "rejected": [{"venue": "iclr2026", "reason": "..."}]}
],
"legacy_main_tex_sha256_before": "...",
"legacy_main_tex_sha256_after": "...",
"legacy_diff_empty": true,
"schema_tables_created": ["manuscript_venue_selections"],
"test_command": "...",
"test_summary": "..."
}
防伪 / 防硬编码要求
- router 测试必须使用至少 2 个 fixture,不能只测试一个固定标题。
- selection artifact 必须能从 DB 查询出来,不能只存在内存。
venues_v1.yaml 临时增加一个测试 venue 的 case 必须证明“不改 Python 代码也能进入候选集合”。
- adapter 的
inject_preamble 必须是幂等的,重复执行不能重复插入 preamble。
范围外 Out of scope
Parent epic: #11
Depends on: none for this issue, but integration must declare whether it is based on
mainor PR #10Estimate: ~1 dev-day (~6h Opus-assisted)
范围 Scope
把当前硬编码 ICLR2026 的逻辑抽成可插拔
TemplateAdapter接口;新建VenueRouter评分模块;用venues.yaml让 venue 列表可配置。改动 Changes
新建文件
agents/manuscript_templates/__init__.py—TemplateAdapter基类(抽象方法:copy_files/inject_preamble/normalize_source/bibstyle_name/max_pages)agents/manuscript_templates/iclr2026.py— 搬现有 ICLR 逻辑agents/manuscript_templates/arxiv_plain.py— 用third_party/paperorchestra_arxiv2604/资产agents/venue_router.py— 规则评分(仿agenda_selector.py结构)db/schema_venue_routing.sql—manuscript_venue_selections表manuscript_venues/venues_v1.yaml— 含 ICLR + arXiv 2 venue 完整配置(schema_version、triggers、rejects、template_id、max_pages)编辑文件
agents/paper_orchestra_pipeline.py— 4 处替换:_copy_iclr2026_template_files→adapter.copy_files_ensure_iclr2026_preamble→adapter.inject_preamblenormalize_latex_source(force_iclr2026=...)→adapter.normalize_sourceassemble_main_tex内的 venue 字段从 hardcoded →adapter.venue_labeldb/database.py:init_db()— 自动 apply 新 schemaconfig.py— 新增VENUES_CONFIG_PATHenv / toml 入口验收 Acceptance
bundle_format=conference路径产出的main.tex字节级一致;PR 必须提供 diff 命令和输出摘要tests/test_template_adapter.py≥ 4 case:tests/test_venue_router.py≥ 4 case:manuscript_venue_selections表from agents.manuscript_templates import get_adapter可独立 REPL 调用venues_v1.yaml不改代码加 venue 即被 router 命中AI 可验收证据包(必须)
PR 必须生成:
字段至少包含:
{ "base_ref": "...", "commit": "...", "adapter_contract": ["copy_files", "inject_preamble", "normalize_source", "bibstyle_name", "max_pages"], "registered_venues": ["iclr2026", "arxiv_plain"], "router_fixture_results": [ {"fixture": "benchmark_state", "chosen": "iclr2026", "score": 0.0, "rejected": []}, {"fixture": "theory_only_state", "chosen": "arxiv_plain", "rejected": [{"venue": "iclr2026", "reason": "..."}]} ], "legacy_main_tex_sha256_before": "...", "legacy_main_tex_sha256_after": "...", "legacy_diff_empty": true, "schema_tables_created": ["manuscript_venue_selections"], "test_command": "...", "test_summary": "..." }防伪 / 防硬编码要求
venues_v1.yaml临时增加一个测试 venue 的 case 必须证明“不改 Python 代码也能进入候选集合”。inject_preamble必须是幂等的,重复执行不能重复插入 preamble。范围外 Out of scope