Просмотр исходного кода

docs: align all V2 docs with implemented code, DB and JSON state

- 06 计划:M3-M6 标注已完成(commit 哈希);附录 B/第 1 节历史框定;
  第 12 节验收进度;新增 12.5 节"V2 临时选择与后续处理"(10 项,带代码证据)
- 总索引+5 模块索引:实施状态行;脏文件边界历史前提结清说明
  (api/dashboard/web 已于 6ee0079/c6c5e39 提交,M6C 起主线维护)
- 18 篇子 brief:状态行追加已实施;"当前事实"段统一历史基线标注;
  定点修正(M6C/M5B tag_query→hashtag_to_query、M5D has_more_present→has_more、
  M4A helper 实际签名、M6B event_id 实际形态与补跑位置)
- 三份 M3-M6 报告头部加历史快照标注(内文零改动)
- 配置侧:Excel effect_status_mapping sheet 重写为与 JSON 5 条 1:1
  (原 6 行旧 id 为假同步);rule_package_meta 描述更新;registry 的
  decode/category-match 条目 access_mode→read + current_code_refs 填实;
  schema registry run_events purpose 补 M6 事件说明

build --check/config gate/schema registry 全 pass;299 passed 不变;
双岗交叉验证通过(36 条新陈述逐条验真,零新引入错误)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sam Lee 3 дней назад
Родитель
Сommit
af46aadab3
31 измененных файлов с 138 добавлено и 57 удалено
  1. 35 8
      tech_documents/工程落地/06_V2阶段开发计划.md
  2. 5 9
      tech_documents/工程落地/v2_implementation_briefs/00_V2_Brief_Index.md
  3. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M2/00_M2_Brief_Index.md
  4. 2 0
      tech_documents/工程落地/v2_implementation_briefs/M3-M6_Audit_Summary.md
  5. 2 0
      tech_documents/工程落地/v2_implementation_briefs/M3-M6_Brief_Repair_Summary.md
  6. 2 0
      tech_documents/工程落地/v2_implementation_briefs/M3-M6_Brief_Verification_Report.md
  7. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/00_M3_Brief_Index.md
  8. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/M3A_Dispatch_By_Entity.md
  9. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/M3B_Policy_Bundle_By_Entity.md
  10. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/M3C_Excel_Driven_Portrait_Rules.md
  11. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/M3D_Scorecard_Missing_Dimensions.md
  12. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M3/M3E_Tests_And_Gates.md
  13. 4 2
      tech_documents/工程落地/v2_implementation_briefs/M4/00_M4_Brief_Index.md
  14. 4 2
      tech_documents/工程落地/v2_implementation_briefs/M4/M4A_Query_Next_Page_Gate.md
  15. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M4/M4B_Decision_Filtered_Author_Tag.md
  16. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M4/M4C_Edge_Binding_And_Rule_Pack_Record.md
  17. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M4/M4D_Source_Path_Records.md
  18. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M4/M4E_Tests_And_Replay.md
  19. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M5/00_M5_Brief_Index.md
  20. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M5/M5A_Blogger_Author_Works.md
  21. 4 2
      tech_documents/工程落地/v2_implementation_briefs/M5/M5B_Rate_Limit_And_Platform_Errors.md
  22. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M5/M5C_Category_Match_V2.md
  23. 5 3
      tech_documents/工程落地/v2_implementation_briefs/M5/M5D_Tests_And_Smoke.md
  24. 5 3
      tech_documents/工程落地/v2_implementation_briefs/M6/00_M6_Brief_Index.md
  25. 3 1
      tech_documents/工程落地/v2_implementation_briefs/M6/M6A_Run_Events_Duration.md
  26. 4 2
      tech_documents/工程落地/v2_implementation_briefs/M6/M6B_Decode_Event_Sink.md
  27. 5 3
      tech_documents/工程落地/v2_implementation_briefs/M6/M6C_Timeline_Summary.md
  28. 5 3
      tech_documents/工程落地/v2_implementation_briefs/M6/M6D_Tests_And_Gates.md
  29. 1 1
      tech_documents/数据库字段总览/content_agent_schema_registry.json
  30. 10 4
      tech_documents/数据接口与来源/external_data_sources_registry.json
  31. BIN
      tech_documents/规则包映射/规则包映射配置表.xlsx

+ 35 - 8
tech_documents/工程落地/06_V2阶段开发计划.md

@@ -1,8 +1,8 @@
 # V2 阶段开发计划
 
-状态:V2 迭代输入文档(技术架构版)。
+状态:V2 迭代输入文档(技术架构版)。**V2 M0-M6 已全部实施完成(2026-06-10,详见各模块实施状态行与 12.5 节临时选择清单)。**
 
-更新时间:2026-06-09
+更新时间:2026-06-10
 
 本文取代并合并 `v1.1 迭代落地/真实E2E问题整理.md`。本文正文面向技术团队,重点讲清 V2 的架构关系、实现路线、数据流、业务影响和验收方式;函数级代码证据、DB 明细和命令清单保留在附录与 implementation briefs 中。
 
@@ -14,7 +14,7 @@ V1 已经打通单线闭环:
 Pattern 证据 -> 搜索词 -> 抖音搜索 -> 内容发现 -> Pattern 回扣 -> 规则判断 -> 游走 -> 结果沉淀 -> 策略复盘
 ```
 
-真实 E2E `demand_content.id=45` / `run_id=v1_run_faaf9a1d0ad6` 证明这条链路可以跑完,但也暴露出一个核心问题:**配置、规则、游走和可观测的“位置”已经建好,运行时接线还没有完全接上**。
+(以下为 V2 立项时的问题盘点,所列问题已由 M2-M6 逐一解决。)真实 E2E `demand_content.id=45` / `run_id=v1_run_faaf9a1d0ad6` 证明这条链路可以跑完,但也暴露出一个核心问题:**配置、规则、游走和可观测的“位置”已经建好,运行时接线还没有完全接上**。
 
 | 问题 | 现象 | 业务影响 | 技术根因 | 证据 |
 |---|---|---|---|---|
@@ -217,7 +217,9 @@ query_prompts.v1.json
 - `douyin/V1` profile 已落地,默认零回归。
 - 后续业务主动改 profile 时,结果变化作为受控实验处理。
 
-## 8. M3 判断规则与策略版本模块
+## 8. M3 判断规则与策略版本模块(已完成)
+
+实施状态:已完成(commit 42d0802,2026-06-10;dispatch 参数化 + rule_pack_by_entity + 画像止血配置驱动 + scorecard 缺维度)。
 
 ### 架构关系
 
@@ -281,7 +283,9 @@ V1 当前实际只跑 Content 包。V2 要把“未来包配置存在”变成
 - Content dispatch 继续作为兼容入口。
 - M3 完成前画像缺失仍按现行 Excel / JSON 规则 REJECT;M3 实施时如要止血,先改 Excel / JSON 规则,再由代码执行。
 
-## 9. M4 游走策略模块
+## 9. M4 游走策略模块(已完成)
+
+实施状态:已完成(commit 410cd72,2026-06-10;翻页 success 闸 + decision 过滤作者/tag + edge binding 归属/执行分离,binding 增至 8 条)。
 
 ### 架构关系
 
@@ -336,7 +340,9 @@ RuleDecision
 - M4 触发过滤可先于 binding 写回交付,先止血分页 / 作者 / tag 的错误扩展。
 - `rule_pack_id` 写回依赖 M3 dispatch 参数化。
 
-## 10. M5 平台接入模块
+## 10. M5 平台接入模块(已完成)
+
+实施状态:已完成(commit 7e86c9a,2026-06-10;blogger 接口合同 + RateLimiter 双 bucket + PLATFORM_RATE_LIMITED + 分类树 v2 解析)。
 
 ### 架构关系
 
@@ -393,7 +399,9 @@ V2 不扩平台,而是先把现有抖音入口跑稳。
 - keyword 搜索继续可用。
 - 作者边在 M5 修好前可能为空或异常,但 M4 会先按规则决策过滤,减少无效触发。
 
-## 11. M6 运行记录与可观测性模块
+## 11. M6 运行记录与可观测性模块(已完成)
+
+实施状态:已完成(commit ed13f10,2026-06-10;stage 计时事件 + decode 五类事件与最小补跑 + timeline summary 七字段)。
 
 ### 架构关系
 
@@ -454,6 +462,8 @@ V2 只增强后端事件和 API,不做前端组件。
 
 ## 12. 端到端验收
 
+验收进度(2026-06-10):配置与 schema 闸、全量单测(299 passed)、离线真实 case 回放、config x case 矩阵均已随各里程碑完成;**live smoke(blogger)与真实 DB run(端到端首条)待执行**。
+
 端到端验收是补齐验收,不是首测。各模块仍要在本模块实施时交付自己的单测和契约测试。
 
 | 验收类型 | 目的 | 关键观察点 |
@@ -466,6 +476,23 @@ V2 只增强后端事件和 API,不做前端组件。
 
 详细命令见附录 D。
 
+## 12.5 V2 临时选择与后续处理
+
+以下是 V2 阶段为控制范围做出的临时搭建/临时选择,均有代码证据,后续阶段按注明方式处理:
+
+| # | 临时选择 | 代码证据 | 后续阶段处理 |
+|---|---|---|---|
+| 1 | 限流 business code 白名单为空集,识别仅靠 HTTP 429 + message token | `content_agent/integrations/douyin.py` RATE_LIMIT_BUSINESS_CODES | 真实运行/live smoke 撞到限流 code 后补入常量并加用例 |
+| 2 | 回放环境 decode/分类匹配用恒成功 Fake 客户端 → real_id45 回放口径为 4×KEEP(画像闸),与 DB 收割口径(1 画像 + 3 解码回扣)不同 | `tests/replay_harness.py`、`tests/test_case_replay.py` docstring | M6 已具备 decode 事件能力,后续造"解码超时"标本对齐两本账 |
+| 3 | syn 合成案例无 has_more/next_cursor(不覆盖"入池→翻页"正向回放断言) | `tests/test_case_replay.py _synthetic_item()` | 需要回放级翻页正向断言时给 syn_pool 补分页字段 |
+| 4 | LocalRuntimeFileStore.append_run_event_records 为 no-op → 本地 runtime 无 lifecycle 行,timeline total_duration_ms 走 stage 求和回退 | `content_agent/integrations/runtime_files.py` | 本地 store 如需 lifecycle 行时补实现;DB 链路不受影响 |
+| 5 | variants_per_seed>1 暂不支持,配置大于 1 直接抛 QUERY_GENERATION_FAILED | `content_agent/business_modules/search_intent.py` | 需要多变体时定义 query 编号合同后放开(M2 遗留拍板) |
+| 6 | walk_engine/walk_strategy 以默认 root(`.`) 加载 WalkStrategyStore,要求从仓库根运行 | `content_agent/business_modules/walk_engine.py`、`walk_strategy.py` | 需要任意工作目录部署时参数化 root |
+| 7 | stage_failed 事件对普通异常只记类型名(error_code=None),仅 ContentAgentError 有结构化 error_code | `content_agent/graph.py _instrumented` | 上游(如 policy_version)改抛 ContentAgentError 后自然结构化,V3 可选 |
+| 8 | Author/Hashtag/Path/Budget 四个 dispatch 配置为 future 未启用(dispatch_enabled=false) | `product_documents/规则包/douyin_rule_packs.v1.json` dispatch 段 | 启用对应游走边的判断时打开 dispatch 并补该包规则 |
+| 9 | "卡住"的业务阈值未定义,M6 只记录耗时/失败/限流/decode 中间态等事实 | M6 已拍板口径 | 积累真实 run 数据后由产品拍卡点标准 |
+| 10 | 测试基线 299 passed(2026-06-10),回放标本为 real_id45 + syn_pool/syn_review | `uv run pytest -q` | 每个后续里程碑更新基线;真实 DB run 后收割新标本 |
+
 ## 13. 明确不做(V3 留白)
 
 1. 数据源 / 平台宽度扩展,包括 Case、历史搜索、热点、小红书等。
@@ -569,7 +596,7 @@ Path      路径停止判断
 Budget    预算待观察判断
 ```
 
-当前生产运行事实:
+当前生产运行事实(M4 实施前的历史基线,M4=410cd72 已修复——现状:binding 已被 walk_engine/walk_strategy 完整消费,walk action 全部带归属包与执行事实,path_stop 归 Path 包)
 
 - `content_agent_rule_decisions` 和 `content_agent_policy_runs` 只实际用过 Content 包。
 - `walk_rule_pack_binding` 已配置 edge 到规则包的归属关系,但当前运行时没有完整消费。

+ 5 - 9
tech_documents/工程落地/v2_implementation_briefs/00_V2_Brief_Index.md

@@ -1,6 +1,6 @@
 # V2 Implementation Brief Index
 
-状态:本目录是 V2 各模块正式实施前的短实施简报集合。它不是新的架构权威源,也不是产品计划;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`(V2 计划权威源)、`tech_documents/数据库字段总览/content_agent_schema_registry.json`、`sql/content_agent_schema.sql` 和当前代码为准。V1 的同类简报在同级 `v1_implementation_briefs/`。
+状态:**V2 M2-M6 已全部实施完成**(M2=992c8c6 / M3=42d0802 / M4=410cd72 / M5=7e86c9a / M6=ed13f10,2026-06-10),本目录转为施工合同存档与维护参照。本目录原为 V2 各模块正式实施前的短实施简报集合。它不是新的架构权威源,也不是产品计划;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`(V2 计划权威源)、`tech_documents/数据库字段总览/content_agent_schema_registry.json`、`sql/content_agent_schema.sql` 和当前代码为准。V1 的同类简报在同级 `v1_implementation_briefs/`。
 
 ## 目标
 
@@ -46,18 +46,14 @@ V2 模块本轮统一编号为 M0–M6(M0 测试地基为旧 Mt / M-test)。
 - **M5**:作者作品接口合同已由真实 smoke 固定:`POST /crawler/dou_yin/blogger`,`account_id=author.platform_author_id`,`sort_type=最新` 或配置默认值,`cursor=""`;实测 HTTP 200、`business_code=0`、`result_count=23`、`has_more=true`、`next_cursor` 存在。
 - **M6**:先记录运行事实和失败计数,不预设卡点阈值;“卡住”的业务判断留到后续基于真实运行数据再定义。
 
-## 当前脏文件边界
+## 当前脏文件边界(历史前提,已结清)
 
-执行 M3-M6 时必须先区分“本轮改动”和“既有用户改动”。当前工作区已有与 M3-M6 brief 修复无关的脏文件 / 未跟踪目录,后续代码实现不得覆盖或回滚:
-
-- `content_agent/api.py`
-- `content_agent/schemas.py`
-- `tests/test_api.py`
-- `content_agent/dashboard_service.py`
-- `web/`
+M3-M6 施工期间,工作区曾有与 brief 无关的未提交用户改动(dashboard API 与 web 前端)。该前提已结清:`content_agent/api.py`、`content_agent/schemas.py`、`tests/test_api.py`、`content_agent/dashboard_service.py` 已在 commit 6ee0079 提交,`web/` 已在 c6c5e39 提交,均为正式工程产物;其中 `dashboard_service.py`、`schemas.py`、`tests/test_api.py` 自 M6C(ed13f10)起由主线一并维护。当前工作区无遗留脏文件。
 
 ## 现有证据(V2 改造的代码锚点)
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/integrations/policy_json.py`、`walk_strategy_json.py`:runtime 只读 JSON + sha256(M1 / M3 改造锚点)。
 - `content_agent/business_modules/rule_judgment/evaluator.py`:scorecard / hard gate(M3)。
 - `content_agent/business_modules/walk_engine.py`、`walk_strategy.py`:游走触发与 `rule_pack_id` 双 writer(M4)。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M2/00_M2_Brief_Index.md

@@ -1,6 +1,6 @@
 # M2 Implementation Brief Index(搜索意图 / query prompt 配置化)
 
-状态:本目录是 V2-M2 正式实施前的短实施简报集合。它不是新的架构权威源,也不是产品计划;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`(第 6 节 V2-M2)、`content_agent/business_modules/search_intent.py`、`content_agent/integrations/query_variant.py`、当前代码与真实 DB 为准。
+状态:**已实施完成(commit 992c8c6,2026-06-10)**。本目录原为 V2-M2 正式实施前的短实施简报集合。它不是新的架构权威源,也不是产品计划;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`(第 6 节 V2-M2)、`content_agent/business_modules/search_intent.py`、`content_agent/integrations/query_variant.py`、当前代码与真实 DB 为准。
 
 ## 目标
 
@@ -24,6 +24,8 @@
 
 ## 现有证据
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 硬编码点(M2 配置化目标):
 
 - `content_agent/integrations/query_variant.py:150-165` `_messages()`:system + user prompt 英文原文;user 模板把 `evidence_context` 以 **dict `repr`** 内嵌(非 JSON)。

+ 2 - 0
tech_documents/工程落地/v2_implementation_briefs/M3-M6_Audit_Summary.md

@@ -1,5 +1,7 @@
 # M3-M6 Implementation Brief Audit Summary
 
+> 历史快照:本文件是 M3-M6 briefs 定稿过程记录(2026-06-10)。文中“当前/尚未/待”类表述为当时状态;实施已全部完成(M3=42d0802 / M4=410cd72 / M5=7e86c9a / M6=ed13f10),现状以代码与各 brief 状态行为准。
+
 状态:本文件是本轮 M3-M6 brief 编写后的审计摘要。它不替代各模块 brief;施工时仍以 `M3/`、`M4/`、`M5/`、`M6/` 子目录为准。
 
 ## 本轮 subagent 分工

+ 2 - 0
tech_documents/工程落地/v2_implementation_briefs/M3-M6_Brief_Repair_Summary.md

@@ -1,5 +1,7 @@
 # M3-M6 Implementation Brief Repair Summary
 
+> 历史快照:本文件是 M3-M6 briefs 定稿过程记录(2026-06-10)。文中“当前/尚未/待”类表述为当时状态;实施已全部完成(M3=42d0802 / M4=410cd72 / M5=7e86c9a / M6=ed13f10),现状以代码与各 brief 状态行为准。
+
 状态:本文件记录本轮 M3-M6 brief 修复结果。它不替代 `M3/`、`M4/`、`M5/`、`M6/` 子目录;真正施工仍以各子 brief 为准。
 
 ## 修复目标

+ 2 - 0
tech_documents/工程落地/v2_implementation_briefs/M3-M6_Brief_Verification_Report.md

@@ -1,5 +1,7 @@
 # M3-M6 Implementation Brief Verification Report
 
+> 历史快照:本文件是 M3-M6 briefs 定稿过程记录(2026-06-10)。文中“当前/尚未/待”类表述为当时状态;实施已全部完成(M3=42d0802 / M4=410cd72 / M5=7e86c9a / M6=ed13f10),现状以代码与各 brief 状态行为准。
+
 状态:本报告是只读验证结果。验证过程中没有修改 M3-M6 brief、代码、JSON、Excel 或 DB。
 
 验证日期:2026-06-10

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/00_M3_Brief_Index.md

@@ -1,6 +1,6 @@
 # M3 Implementation Brief Index(判断规则与策略版本)
 
-状态:本目录是 V2-M3 正式实施前的短实施简报集合。它不是新的架构权威源;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`、当前代码、规则包 Excel/JSON、真实 DB/fixture 为准。本文是索引;M3A-M3E 才是施工单位。
+状态:**已实施完成(commit 42d0802,2026-06-10)**。本目录原为 V2-M3 正式实施前的短实施简报集合。它不是新的架构权威源;长期事实仍以 `tech_documents/工程落地/06_V2阶段开发计划.md`、当前代码、规则包 Excel/JSON、真实 DB/fixture 为准。本文是索引;M3A-M3E 才是施工单位。
 
 ## 目标
 
@@ -18,6 +18,8 @@ M3 的红线是:**不得在代码里硬写 `missing` / `weak` 的业务判断*
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/integrations/policy_json.py:79-92` 的 `_select_dispatch()` 只选择 `target_entity=="Content"`,且要求 exactly one Content dispatch。
 - `policy_json.py:27-42` 的 `load_policy_bundle()` 只返回一个 `rule_pack` / `rule_pack_id`,没有 `rule_pack_by_entity`。
 - `product_documents/规则包/douyin_rule_packs.v1.json:21-91` 有 Content / Author / Hashtag / Path / Budget 五类 dispatch,但当前只有 Content `dispatch_enabled=true`。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/M3A_Dispatch_By_Entity.md

@@ -1,6 +1,6 @@
 # M3A Dispatch By Entity Implementation Brief
 
-状态:本 brief 只覆盖 `policy_json.py` dispatch 参数化和冲突护栏。不改规则业务口径,不改 evaluator。
+状态:本 brief 只覆盖 `policy_json.py` dispatch 参数化和冲突护栏。不改规则业务口径,不改 evaluator。**已实施(commit 42d0802,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `policy_json.py:79-92` 硬编码 `target_entity=="Content"`。
 - `douyin_rule_packs.v1.json:21-91` 已有五类 dispatch;当前仅 Content 启用,future 包为 disabled。
 - `scripts/validate_rule_pack_config.py:38-42` 只校验 dispatch 引用的 `rule_pack_id` 是否存在,没有校验同一 entity 多个 enabled 冲突。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/M3B_Policy_Bundle_By_Entity.md

@@ -1,6 +1,6 @@
 # M3B Policy Bundle By Entity Implementation Brief
 
-状态:本 brief 覆盖 `load_policy_bundle()` 增加 `rule_pack_by_entity`,并保留顶层 Content shim。
+状态:本 brief 覆盖 `load_policy_bundle()` 增加 `rule_pack_by_entity`,并保留顶层 Content shim。**已实施(commit 42d0802,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `policy_json.py:27-42` 只返回一个 `rule_pack`、`rule_pack_id`、`dispatch`。
 - `rule_judgment.run()` 当前只接收单个 `policy_bundle` 并读取 `policy_bundle["rule_pack"]`。
 - `walk_rule_pack_binding` 在 `douyin_walk_strategy.v1.json:284-345` 已声明 edge 到 rule pack 的归属,但 policy bundle 当前没有 entity 映射可用。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/M3C_Excel_Driven_Portrait_Rules.md

@@ -1,6 +1,6 @@
 # M3C Excel Driven Portrait Rules Implementation Brief
 
-状态:本 brief 覆盖画像缺失止血的唯一 Excel / JSON 配置合同。不允许代码硬写 `missing` / `weak` 业务判断。
+状态:本 brief 覆盖画像缺失止血的唯一 Excel / JSON 配置合同。不允许代码硬写 `missing` / `weak` 业务判断。**已实施(commit 42d0802,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@ M3C 把“画像缺失直接淘汰”改成“画像缺失进入待复看”。
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - Excel `tech_documents/规则包映射/规则包映射配置表.xlsx` 的 `hard_gate_rules` 中:
   - `missing_content_portrait` 当前 `REJECT_CONTENT`、`fatal`、`stop_scoring=true`。
   - `age_50_plus_weak` 当前 `expected_value=["weak","missing"]`、`REJECT_CONTENT`、`fatal`、`stop_scoring=true`。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/M3D_Scorecard_Missing_Dimensions.md

@@ -1,6 +1,6 @@
 # M3D Scorecard Missing Dimensions Implementation Brief
 
-状态:本 brief 覆盖 evaluator 对“单维度缺失”和“全 scorecard 缺失”的区分。
+状态:本 brief 覆盖 evaluator 对“单维度缺失”和“全 scorecard 缺失”的区分。**已实施(commit 42d0802,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `evaluator.py:255-285` 每个 active dimension 都会输出一行 score。
 - `_score_dimension()` 在没有匹配 scoring rule 时返回 `(0, None)`。
 - `decide()` 在 `score is None or not matched_scoring_rules` 时走 `_missing_score_decision()`。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M3/M3E_Tests_And_Gates.md

@@ -1,6 +1,6 @@
 # M3E Tests And Gates Implementation Brief
 
-状态:本 brief 收口 M3 测试、配置闸、真实 case 回放验收。
+状态:本 brief 收口 M3 测试、配置闸、真实 case 回放验收。**已实施(commit 42d0802,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - 当前已有 `tests/test_policy_dispatch.py`、`tests/test_rule_pack_reading.py`、`tests/test_rule_judgment_hard_gates.py`、`tests/test_rule_judgment_scorecard.py`、`tests/test_config_case_matrix.py`。
 - M3 测试统一使用当前仓库已存在的 policy / rule judgment 测试文件,不再引用旧的合并测试名。
 - `real_id45` 是 M3 受控变化回放锚点。

+ 4 - 2
tech_documents/工程落地/v2_implementation_briefs/M4/00_M4_Brief_Index.md

@@ -1,6 +1,6 @@
 # M4 Implementation Brief Index(游走策略)
 
-状态:本目录是 V2-M4 正式实施前的短实施简报集合。M4 只做规则结果与游走接线,不新增无关边,不做无限扩展。本文是索引;M4A-M4E 才是施工单位。
+状态:**已实施完成(commit 410cd72,2026-06-10)**。本目录原为 V2-M4 正式实施前的短实施简报集合。M4 只做规则结果与游走接线,不新增无关边,不做无限扩展。本文是索引;M4A-M4E 才是施工单位。
 
 ## 目标
 
@@ -21,11 +21,13 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `walk_engine.py:317-350` `_pagination_queries()` 只看 `has_more` 和 `next_cursor`,没有看 query effect status。
 - `walk_engine.py:211-279` `_execute_author_edges()` 从 discovered items 去重作者后直接拉作品,没有按 RuleDecision 过滤。
 - `_tag_queries()` 已看 `search_query_effect_status in {"success","pending"}`,但还没有用 `decision_action` 做 ADD / KEEP / REJECT 分层。
 - `douyin_walk_strategy.v1.json:240-248` 已声明 `query_next_page` cursor trigger,`272-281` 已声明 `rule_blocked` 停止。
-- `douyin_walk_strategy.v1.json:284-345` 已声明 edge 到 rule pack 的 binding(当前 6 条边,`path_stop`、`decision_to_asset` 由 M4C 增补)。
+- `douyin_walk_strategy.v1.json:284-345` 已声明 edge 到 rule pack 的 binding(实施前 6 条边;`path_stop`、`decision_to_asset` 已由 M4C 增补,实施后共 8 条)。
 - 真实 DB run `v1_run_faaf9a1d0ad6`:`query_next_page=2` success、`author_to_works=2` failed、二者 `rule_pack_id=NULL`;`path_stop=4` 错挂 Content 包。
 
 ## 已拍板 / 默认推进

+ 4 - 2
tech_documents/工程落地/v2_implementation_briefs/M4/M4A_Query_Next_Page_Gate.md

@@ -1,6 +1,6 @@
 # M4A Query Next Page Gate Implementation Brief
 
-状态:本 brief 覆盖 `_pagination_queries()` 增加 query success 闸。M4A 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 `_pagination_queries()` 增加 query success 闸。M4A 是施工单位,不再需要额外拍板。**已实施(commit 410cd72,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/business_modules/walk_engine.py` 的 `_pagination_queries()` 当前只检查 `item.has_more`、`next_cursor` 和 query 去重。
 - `product_documents/抖音游走策略/douyin_walk_strategy.v1.json` 已写 rule_blocked 停止闸:trigger `tr_rule_blocked_stop`(`content_effect_status=="rule_blocked"`,edge=`path_stop`)+ stop policy `stop_rule_blocked`(`stop_action="stop_path"`),但当前游走执行没有完整消费该闸。
 - DB run `v1_run_faaf9a1d0ad6` 中 4 条 `search_clue` 全是 `rule_blocked`,仍有 `q_001_page_002`、`q_002_page_002` 两条翻页 query。
@@ -30,7 +32,7 @@
 
 - `run_bounded_walk(...)`:把当前内存中的 `rule_decisions` 继续传给翻页逻辑。
 - `_pagination_queries(...)`:新增 `rule_decisions` 参数,依据 query effect 决定是否翻页。
-- 新增 helper:`_query_effect_by_search_query_id(rule_decisions)`。
+- 新增 helper:`_query_effect_by_search_query_id(discovered_content_items, rule_decisions)`。(实施修正:decision 记录无 search_query_id 字段,经 discovered items 的 content→query 关联聚合。)
 - 新增 helper:`_can_fetch_next_page(search_query_id, query_effect_by_id)`。
 
 ## 数据合同

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M4/M4B_Decision_Filtered_Author_Tag.md

@@ -1,6 +1,6 @@
 # M4B Decision Filtered Author Tag Implementation Brief
 
-状态:本 brief 覆盖作者和 tag 扩展按 RuleDecision 过滤。M4B 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖作者和 tag 扩展按 RuleDecision 过滤。M4B 是施工单位,不再需要额外拍板。**已实施(commit 410cd72,2026-06-10)。**
 
 ## 目标
 
@@ -12,6 +12,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `_execute_author_edges()` 当前只用 `_unique_authors(discovered_content_items)[:2]`,不看 decision。
 - `_tag_queries()` 看 query effect,但没有按 `decision_action` 区分 ADD / KEEP / REJECT。
 - DB run `v1_run_faaf9a1d0ad6` 中 4 条 rule decision 全是 `REJECT_CONTENT`,仍有 2 条 `author_to_works` failed。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M4/M4C_Edge_Binding_And_Rule_Pack_Record.md

@@ -1,6 +1,6 @@
 # M4C Edge Binding And Rule Pack Record Implementation Brief
 
-状态:本 brief 覆盖 `walk_rule_pack_binding` 解析,以及 walk action 记录归属包 / 实际执行包。M4C 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 `walk_rule_pack_binding` 解析,以及 walk action 记录归属包 / 实际执行包。M4C 是施工单位,不再需要额外拍板。**已实施(commit 410cd72,2026-06-10)。**
 
 ## 目标
 
@@ -13,6 +13,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `product_documents/抖音游走策略/douyin_walk_strategy.v1.json` 有 edge -> rule pack binding。
 - binding 来源是 `WalkStrategyStore.load_walk_strategy()["walk_rule_pack_binding"]`,不是 policy bundle 主体。
 - `walk_rule_pack_binding` 当前只有 6 条边(video_to_author、author_to_works、video_to_hashtag、hashtag_to_query、query_next_page、budget_downgrade),没有 `path_stop`、`decision_to_asset` 条目。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M4/M4D_Source_Path_Records.md

@@ -1,6 +1,6 @@
 # M4D Source Path Records Implementation Brief
 
-状态:本 brief 覆盖 M4 对 `source_path_records` 和 walk action 归属的补齐。M4D 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 M4 对 `source_path_records` 和 walk action 归属的补齐。M4D 是施工单位,不再需要额外拍板。**已实施(commit 410cd72,2026-06-10)。**
 
 ## 目标
 
@@ -17,6 +17,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/integrations/runtime_files.py` 的 `RUNTIME_FILENAMES` 已包含 `source_path_records.jsonl` 和 `walk_actions.jsonl`。
 - `path_stop`、`decision_to_asset` 的 binding 条目由 M4C 施工步骤 1 在 `walk_rule_pack_binding` 中增补;M4D 只消费,不再改配置。
 - DB run `v1_run_faaf9a1d0ad6` 中 `source_path_records=8`、`walk_actions=8`。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M4/M4E_Tests_And_Replay.md

@@ -1,6 +1,6 @@
 # M4E Tests And Replay Implementation Brief
 
-状态:本 brief 收口 M4 测试和真实 case 回放。M4E 是施工单位,不再需要额外拍板。
+状态:本 brief 收口 M4 测试和真实 case 回放。M4E 是施工单位,不再需要额外拍板。**已实施(commit 410cd72,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - DB run `v1_run_faaf9a1d0ad6` 中 4 条 `search_clue` 全是 `rule_blocked`。
 - 同一 run 仍出现 `query_next_page=2`、`author_to_works=2`。
 - `query_next_page` / `author_to_works` 缺少清晰 rule pack binding。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M5/00_M5_Brief_Index.md

@@ -1,6 +1,6 @@
 # M5 Implementation Brief Index(平台接入)
 
-状态:本目录是 V2-M5 正式实施前的短实施简报集合。00 index 只做导航,M5A-M5D 才是施工单位。M5 只稳定抖音平台合同,不扩小红书 / 多平台。
+状态:**已实施完成(commit 7e86c9a,2026-06-10)**。本目录原为 V2-M5 正式实施前的短实施简报集合。00 index 只做导航,M5A-M5D 才是施工单位。M5 只稳定抖音平台合同,不扩小红书 / 多平台。
 
 ## 目标
 
@@ -32,6 +32,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/integrations/douyin.py` 当前 `fetch_author_works()` 仍调用 `self.keyword_path`。
 - `CrawapiDouyinClient.__init__()` / `from_env()` 没有 `blogger_path` 参数。
 - 本地 `.env` 已有 `CONTENTFIND_DOUYIN_BLOGGER_PATH`,但 `.env.example` 只有 keyword / portrait。

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M5/M5A_Blogger_Author_Works.md

@@ -1,6 +1,6 @@
 # M5A Blogger Author Works Implementation Brief
 
-状态:本 brief 覆盖 blogger path/env/config 与 `fetch_author_works()` 修复。M5A 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 blogger path/env/config 与 `fetch_author_works()` 修复。M5A 是施工单位,不再需要额外拍板。**已实施(commit 7e86c9a,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `content_agent/integrations/douyin.py` 当前 `fetch_author_works()` payload 用 `sec_uid`,请求打 `self.keyword_path`。
 - `.env` 已有 `CONTENTFIND_DOUYIN_BLOGGER_PATH` 和 `CONTENTFIND_DOUYIN_ACCOUNT_WORKS_DEFAULT_SORT_TYPE`。
 - `.env.example` 仅列 keyword / portrait / defaults,缺 blogger path。

+ 4 - 2
tech_documents/工程落地/v2_implementation_briefs/M5/M5B_Rate_Limit_And_Platform_Errors.md

@@ -1,6 +1,6 @@
 # M5B Rate Limit And Platform Errors Implementation Brief
 
-状态:本 brief 覆盖搜索链 12 秒限流和 `PLATFORM_RATE_LIMITED`。M5B 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖搜索链 12 秒限流和 `PLATFORM_RATE_LIMITED`。M5B 是施工单位,不再需要额外拍板。**已实施(commit 7e86c9a,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `douyin.py:_post_json()` 当前 HTTP/network/bad_json/business_error 都转 `RuntimeError`。
 - `platform_access._query_failure()` 对普通异常统一输出 `PLATFORM_REQUEST_FAILED`;其 `ContentAgentError` error code 透传分支已存在(platform_access.py:80-88),施工步骤 10 是验证保持,不是新写。
 - `content_agent/errors.py` 当前没有 `PLATFORM_RATE_LIMITED`。
@@ -45,7 +47,7 @@
 ```json
 {
   "bucket": "douyin_search",
-  "operations": ["keyword_search", "query_next_page", "tag_query"],
+  "operations": ["keyword_search", "query_next_page", "tag_query"],  // tag_query 对应游走边 hashtag_to_query,三类操作统一经 search() 进入
   "min_interval_seconds": 12.0
 }
 ```

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M5/M5C_Category_Match_V2.md

@@ -1,6 +1,6 @@
 # M5C Category Match V2 Implementation Brief
 
-状态:本 brief 覆盖分类树 match-paths v2 parser 补测。M5C 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖分类树 match-paths v2 parser 补测。M5C 是施工单位,不再需要额外拍板。**已实施(commit 7e86c9a,2026-06-10)。**
 
 ## 目标
 
@@ -12,6 +12,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `CategoryMatchClient` 默认 `DEFAULT_MATCH_PATH="/api/search/categories/match-paths/v2"`。
 - `tests/test_pattern_recall_category_match.py` 已覆盖 `matched_paths` 字符串形态。
 - parser 已较容错,但 v2 主结构还没有被写成明确施工验收。

+ 5 - 3
tech_documents/工程落地/v2_implementation_briefs/M5/M5D_Tests_And_Smoke.md

@@ -1,6 +1,6 @@
 # M5D Tests And Smoke Implementation Brief
 
-状态:本 brief 收口 M5 测试与 smoke。M5D 是施工单位,不再需要额外拍板。
+状态:本 brief 收口 M5 测试与 smoke。M5D 是施工单位,不再需要额外拍板。**已实施(commit 7e86c9a,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - M5A 的真实 smoke 已证明 `/crawler/dou_yin/blogger` 合同可用。
 - DB run `v1_run_faaf9a1d0ad6` 只能证明作者作品失败类型过粗,不能替代 live smoke 成功证据。
 - 默认 CI 不能依赖外部 Crawapi。
@@ -46,7 +48,7 @@ endpoint=/crawler/dou_yin/blogger
 http_status=200
 business_code=0
 result_count>0
-has_more_present=true
+has_more=true
 next_cursor_present=true
 ```
 
@@ -101,7 +103,7 @@ uv run python scripts/smoke_douyin_blogger.py --author-id '<known_author_id>'
 - `http_status`
 - `business_code`
 - `result_count`
-- `has_more_present`
+- `has_more`
 - `next_cursor_present`
 
 ## 禁止改动检查

+ 5 - 3
tech_documents/工程落地/v2_implementation_briefs/M6/00_M6_Brief_Index.md

@@ -1,6 +1,6 @@
 # M6 Implementation Brief Index(运行记录与可观测性)
 
-状态:本目录是 V2-M6 正式实施前的短实施简报集合。00 index 只做导航,M6A-M6D 才是施工单位。M6 只增强后端事件和 API,不做前端、不告警、不新增表。
+状态:**已实施完成(commit ed13f10,2026-06-10)**。本目录原为 V2-M6 正式实施前的短实施简报集合。00 index 只做导航,M6A-M6D 才是施工单位。M6 只增强后端事件和 API,不做前端、不告警、不新增表。
 
 ## 目标
 
@@ -33,14 +33,16 @@ M6 先记录运行事实和失败计数,不预设卡点阈值:
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `run_events.jsonl` 当前是 13 个 runtime 文件之一。
 - `content_agent/integrations/database_runtime.py` 将 `run_events.jsonl` 映射到 `content_agent_run_events`。
 - DB schema 已有 `event_id`、`event_type`、`status`、`input_ref`、`output_ref`、`error_code`、`message`、`raw_payload`、`created_at`。
 - DB run `v1_run_faaf9a1d0ad6` 有 9 条 run_events;事件覆盖 source/search/platform/evidence/rule/walk/record/succeeded,但缺 per-stage duration。
 - `run_service.py` 只在平台 query failure 时追加 failure records。
-- `dashboard_service.py` 的 timeline 当前只是拼 `run_events`、`walk_actions`、`source_path_records`,没有 summary 聚合;该文件当前有未提交脏改,M6 实施前必须先核对
+- `dashboard_service.py` 的 timeline 实施前只拼 `run_events`、`walk_actions`、`source_path_records` 无 summary 聚合;M6C 已新增 `_timeline_summary()` 七字段聚合。该文件施工时曾为未提交用户改动,已在 6ee0079 提交,M6C(ed13f10)按提交版本追加
 - `decode.py` 只返回最终 decode 状态,没有中间事件 sink。
-- `schemas.py` 和 `tests/test_api.py` 当前有未提交脏改,M6 实施前必须先核对,不可覆盖
+- `schemas.py` 和 `tests/test_api.py` 施工时曾为未提交用户改动,已在 6ee0079 提交;M6C 只追加 `TimelineResponse.summary` 与一个新测试,未覆盖既有内容
 - dashboard 存在字段口径风险:rule decision 写 `search_query_effect_status`,部分 dashboard 代码读 `content_effect_status`。
 
 ## 数据合同

+ 3 - 1
tech_documents/工程落地/v2_implementation_briefs/M6/M6A_Run_Events_Duration.md

@@ -1,6 +1,6 @@
 # M6A Run Events Duration Implementation Brief
 
-状态:本 brief 覆盖阶段事件的耗时、attempt、错误计数事实记录。M6A 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖阶段事件的耗时、attempt、错误计数事实记录。M6A 是施工单位,不再需要额外拍板。**已实施(commit ed13f10,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - graph 主链路在 `content_agent/graph.py` 中按节点串联。
 - `run_record._build_run_events()` 当前生成阶段级事件,但没有 duration / attempt。
 - `content_agent_run_events` 已有 `raw_payload`,可承载新增事实。

+ 4 - 2
tech_documents/工程落地/v2_implementation_briefs/M6/M6B_Decode_Event_Sink.md

@@ -1,6 +1,6 @@
 # M6B Decode Event Sink Implementation Brief
 
-状态:本 brief 覆盖 decode submitted / polling / succeeded / failed / timeout 中间事件、最小补跑与 `.env.example` 短等待档。M6B 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 decode submitted / polling / succeeded / failed / timeout 中间事件、最小补跑与 `.env.example` 短等待档。M6B 是施工单位,不再需要额外拍板。**已实施(commit ed13f10,2026-06-10)。**
 
 ## 目标
 
@@ -8,6 +8,8 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `decode_content()` 调 `submit_decode()` 后循环 `get_decode_result()`,最终返回一个 dict。
 - 超时返回 `pending_reason="decode_timeout_20m"`。
 - `recall_decision.run()` 调用 `decode_content()` 时没有 event_sink。
@@ -78,7 +80,7 @@ event sink 接收 dict:
 - `elapsed_ms`
 - `failure_reason`
 
-事件写入 `run_events.jsonl` / `content_agent_run_events` 时,`event_id` 固定为 `evt_decode_{platform_content_id}_{event_type}_{attempt}`(submitted 首发 attempt=1,polling 按轮次递增,succeeded / failed / timeout 取终止时的 attempt 值),与 M6A 的 `evt_stage_*` 命名空间不冲突。
+事件写入 `run_events.jsonl` / `content_agent_run_events` 时,`event_id` 固定为 `evt_decode_{platform_content_id}_{event_type}_{attempt}`(event_type 自带 decode_ 前缀,实际形如 `evt_decode_aweme_001_decode_submitted_1`;生成于 `run_record.recorder.decode_event_row()`,补跑实现于 `recall_decision._rerun_pending_decode()`,attempt 续增依赖 decode 返回的内部字段 `decode_poll_attempts`)(submitted 首发 attempt=1,polling 按轮次递增,succeeded / failed / timeout 取终止时的 attempt 值),与 M6A 的 `evt_stage_*` 命名空间不冲突。
 
 ## 施工步骤
 

+ 5 - 3
tech_documents/工程落地/v2_implementation_briefs/M6/M6C_Timeline_Summary.md

@@ -1,6 +1,6 @@
 # M6C Timeline Summary Implementation Brief
 
-状态:本 brief 覆盖 dashboard timeline summary 聚合。M6C 是施工单位,不再需要额外拍板。
+状态:本 brief 覆盖 dashboard timeline summary 聚合。M6C 是施工单位,不再需要额外拍板。**已实施(commit ed13f10,2026-06-10)。**
 
 ## 目标
 
@@ -8,10 +8,12 @@ timeline 返回运行事实摘要,不自动判断“卡住”。
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `DashboardService.timeline()` 当前返回 `items` 和 `total`。
 - timeline 当前不读 `pattern_recall_evidence.jsonl`。
 - dashboard 部分函数读 `content_effect_status`,但 rule decision 实际字段是 `search_query_effect_status`。
-- `content_agent/dashboard_service.py`、`content_agent/schemas.py`、`tests/test_api.py` 当前有未提交脏改,M6 实施前必须逐行核对,不可覆盖用户改动
+- `content_agent/dashboard_service.py`、`content_agent/schemas.py`、`tests/test_api.py` 施工时曾为未提交用户改动;已按 6ee0079 提交版本追加实施(ed13f10 只追加未覆盖),自 M6C 起由主线一并维护
 
 ## 修改范围
 
@@ -83,7 +85,7 @@ decision.get("search_query_effect_status") or decision.get("content_effect_statu
 2. 新增 `_timeline_summary(events, walk_actions, source_paths, recalls)`。
 3. `total_duration_ms` 固定算法:优先取 run started / completed 事件差值;任一缺失时回退为 `stage_duration_ms` 求和;两者都缺时为 `null`,不估算。
 4. `stage_duration_ms` 读取 `run_events.raw_payload.stage` 和 `duration_ms`。
-5. `query_failure_count` 唯一来源:`walk_actions` 中 query 链动作(`query_next_page`、`tag_query`)且 `status=="failed"` 的条数;不读取 run_events 失败事件,不求并集、不双计。首轮 keyword 搜索失败属于 stage 失败,计入 `error_counts` 而非本字段。
+5. `query_failure_count` 唯一来源:`walk_actions` 中 query 链动作(`query_next_page`、`hashtag_to_query`)且 `status=="failed"` 的条数;不读取 run_events 失败事件,不求并集、不双计。首轮 keyword 搜索失败属于 stage 失败,计入 `error_counts` 而非本字段。
 6. `platform_rate_limited_count` 统计 `error_code=="PLATFORM_RATE_LIMITED"`。
 7. `decode_status_counts` 只统计 M6B decode events;仅当该 run 没有任何 decode event(M6 前旧数据)时,整体回退为统计 recalls 的最终 decode status;两种来源不混合、不双计。
 8. `error_counts` 按 `error_code` 聚合。

+ 5 - 3
tech_documents/工程落地/v2_implementation_briefs/M6/M6D_Tests_And_Gates.md

@@ -1,6 +1,6 @@
 # M6D Tests And Gates Implementation Brief
 
-状态:本 brief 收口 M6 测试和 gate。M6D 是施工单位,不再需要额外拍板。
+状态:本 brief 收口 M6 测试和 gate。M6D 是施工单位,不再需要额外拍板。**已实施(commit ed13f10,2026-06-10)。**
 
 ## 目标
 
@@ -8,9 +8,11 @@
 
 ## 当前事实
 
+(以下为实施前基线事实;本模块已实施完成,现状以当前代码为准。)
+
 - `tests/test_run_timeline_observability.py` 当前不存在,是 M6 需要新建的测试文件。
 - `tests/test_decode_events.py` 当前是 M6 需要新增的测试文件。
-- `tests/test_api.py` 当前有未提交脏改;M6 实施前必须先读 diff,再在不覆盖用户改动的前提下补 timeline schema/API 断言
+- `tests/test_api.py` 施工时曾为未提交用户改动;已按 6ee0079 提交版本只追加 `test_api_timeline_includes_summary`,未改动既有用例
 - schema registry 当前维持 21 表 / 13 runtime 文件。
 
 ## 修改范围
@@ -44,7 +46,7 @@
 
 1. 新建 `tests/test_run_timeline_observability.py`。
 2. 新建 `tests/test_decode_events.py`。
-3. 读取当前 `tests/test_api.py` diff,确认用户改动后再补 timeline response 断言。
+3. 读取 `tests/test_api.py`(6ee0079 已提交版本)后只追加 timeline response 断言,不改既有用例。(已按此执行。)
 4. 跑 M6A-M6C 单元测试。
 5. 跑 replay,确认业务结果不因 M6 改变。
 6. 跑 schema gate,确认无 schema 漂移。

+ 1 - 1
tech_documents/数据库字段总览/content_agent_schema_registry.json

@@ -4758,7 +4758,7 @@
       "business_label": "content_agent_run_events",
       "business_module": "run_record",
       "business_module_label": "运行记录模块",
-      "purpose": "保存运行事件,记录每一步发生了什么。",
+      "purpose": "保存运行事件,记录每一步发生了什么。V2-M6 起新增阶段事件(evt_stage_*,raw_payload 带 stage/started_at/ended_at/duration_ms/attempt)与 decode 中间事件(evt_decode_*,五类),均经 raw_payload 承载,不新增列。",
       "runtime_files": [
         "run_events.jsonl"
       ],

+ 10 - 4
tech_documents/数据接口与来源/external_data_sources_registry.json

@@ -320,10 +320,13 @@
       "status": ["source_only"],
       "system": "Aiddit AIGC Decode",
       "table_or_endpoint": "https://aigc-api.aiddit.com/aigc/api/task/decode, https://aigc-api.aiddit.com/aigc/api/task/decode/result",
-      "access_mode": "planned_read",
+      "access_mode": "read",
       "usage_stages": ["pattern_recall", "rule_judgment"],
       "owner_module": "发现内容与证据模块",
-      "current_code_refs": [],
+      "current_code_refs": [
+        "content_agent/integrations/decode_api.py::AigcDecodeClient",
+        "content_agent/business_modules/content_discovery/pattern_recall/decode.py::decode_content"
+      ],
       "required_env_vars": [],
       "input_fields": ["platform_content_id", "platform_content_url", "configId"],
       "output_fields": ["decode_status", "purpose_points", "key_points", "inspiration_points", "topic_fusion_result"],
@@ -336,10 +339,13 @@
       "status": ["verified", "source_only"],
       "system": "Aiddit Library",
       "table_or_endpoint": "https://library.aiddit.com/api/search/categories/match-paths/v2",
-      "access_mode": "planned_read",
+      "access_mode": "read",
       "usage_stages": ["pattern_recall", "rule_judgment"],
       "owner_module": "发现内容与证据模块",
-      "current_code_refs": [],
+      "current_code_refs": [
+        "content_agent/integrations/category_match.py::CategoryMatchClient.match_paths",
+        "content_agent/business_modules/content_discovery/pattern_recall/category_match.py::match_decode_terms"
+      ],
       "required_env_vars": [],
       "input_fields": ["source_type", "top_k", "min_score", "items.term", "items.description"],
       "output_fields": ["matched_category_paths", "score", "matched_terms"],

BIN
tech_documents/规则包映射/规则包映射配置表.xlsx