反思闭环家族的事务分段:漂移守护+未获回应升级+Recall冷却 #200

Open
opened 2026-08-21 06:13:56 +00:00 by KumaAgent · 0 comments
Member

Parent

#151(ADR-0013 ①层单一事务边界落地——请求级事务,issue #108 Q1)。事务边界方向已确认为分段
事务只包住连续无外部 I/O 打断的一段纯 DB 读写,下一步要发起任何外部调用前当前段必须先提交/关闭
(见 #151 comments"拆片前的事务边界设计方向已与用户确认")。

本片负责反思闭环家族reflection.py(含 _apply_outcome/_commit_lessonrun_reflection_cycle
驱动)、drift_veto.py(人设漂移守护,judge_and_maybe_veto)、unanswered_escalation.py(未获回应
升级)、proactive_reconnect.py(Recall 冷却计时)。这几个模块是反思/背景处理这条路径上的相邻环节。

Acceptance criteria

一、_apply_outcomereflection.py):单一段,无内部外部 I/O 打断

核实现状发现这个函数内部的写入序列(get_slow_affective_state 读 → update_fast_affective_state
写 → 条件性 update_slow_affective_state 写 → get_proactivity_offset 读 → update_proactivity_offset
写)之间没有任何外部调用——design-verify 阶段原文点名的"update_fast_affective_state/
update_slow_affective_state 之后 get_proactivity_offset(读) 再写"这个"写后读"序列,本身不构成
外部 I/O 打断(读操作不碰外部服务),可以合并成一整段,不需要在函数内部切段。

  • _apply_outcome 整个函数体的全部读写合并为一段,在调用方(run_reflection_cycle 的 attempt
    循环)进入下一个 attempt 前提交/关闭

原文(design-verify HIGH 发现,issue #151 comments,本片核实后订正其严重度判断——不是"打断"而是
"安全合并",因为读操作本身无外部 I/O):

reflection.py::_apply_outcomeupdate_fast_affective_state/update_slow_affective_state 之后
get_proactivity_offset(读) 再写——同样会被打断。

二、_commit_lessonreflection.py):画像/技能两个候选分支,各自独立一段

  • 画像候选分支:judge_and_maybe_veto(...)(外部 LLM 调用,candidate_kind="profile")→
    若通过,新开一段 → write_tentative_facts([candidate]) → 提交/关闭
  • 技能候选分支:judge_and_maybe_veto(...)(外部 LLM 调用,candidate_kind="skill")→
    若通过,embedding_client.embed(skill_candidate.content)又一次外部 I/O,在写入之前)→
    新开一段 → write_skill(...) → 提交/关闭——技能分支比画像分支多一次外部调用(embed),落地时
    不要把两个分支按同一个模板处理
  • 两个分支各自独立、互不共享段(一个候选的判断/写入失败不影响另一个)——这是函数现有 docstring
    已经声明的既有语义("各自独立过一次判断,通过才落库,判否/调用失败都直接丢弃,不影响另一个候选
    的判断结果"),分段改造不能破坏这条既有保证

三、judge_and_maybe_vetodrift_veto.py)内部留痕写入的提交方式——与「Delta压缩周期」姊妹片
协调,不重复设计

judge_and_maybe_veto 是本片与「Delta压缩周期」片共用的函数,record_veto_if_needed(否决/失败时
的留痕写入)该独立提交还是并入调用方的段,两片需要用同一个答案。若「Delta压缩周期」片先落地,
本片直接复用其决定,不重新设计
;若本片先落地,按同样的推荐方案(judge_and_maybe_veto 内部
独立提交留痕写入)实现,并在票内留言告知「Delta压缩周期」片可以直接复用。

  • 与「Delta压缩周期」片确认 judge_and_maybe_veto/record_veto_if_needed 的提交方式后,
    确保本片调用点行为一致,不各自实现出两套不兼容的处理方式

四、unanswered_escalation.py(未获回应升级)

  • 核实该模块的存储写入点(本片起草时未逐行核实,实现期须先读一遍 unanswered_escalation.py
    确认具体函数与写入序列,按"无外部 I/O 打断即合并、有外部调用则切段"的统一规则分段)
  • 若该模块的写入序列内部不含外部调用(预期如此,因为它是机械的阈值判定+情感态 delta 计算,
    不涉及 LLM/embedding),整个写入序列可合并为一段

五、proactive_reconnect.py(Recall 冷却计时)

  • apply_partial_relief/apply_full_reset 两个状态转移各自是单一写入(ReconnectCooldownState
    只有一个字段 last_interaction_at),天然不存在"写后读打断"问题——本片只需要给这两个函数(及
    调用它们的存储方法)接上"一"节地基片交付的 session 参数,不需要额外的分段设计

六、测试

  • _commit_lesson 两个分支各补一条防空转测试:画像分支验证"判断通过但写入前崩溃,候选未落库";
    技能分支同理,且要覆盖 embed() 与 write_skill 之间的崩溃场景(两次外部 I/O 中的第二次之后)
  • _apply_outcome 补一条测试验证整个函数体确实作为一段提交(构造函数体中途崩溃,断言此前
    所有写入均未落库——因为是单一段,不存在"部分回滚")
  • 全量测试通过

Not in scope

  • judge_and_maybe_veto/record_veto_if_needed 的具体代码改动——本片与「Delta压缩周期」片协调后
    由先动手的一片落地,见"三"节
  • run_reflection_cycle(调度驱动层)本身的 session 隔离——是否属于「APScheduler 定时作业」片
    范围需要那一片确认

Blocked by

  • #197(存储层分段事务基建:session 传递契约与 SAVEPOINT 修复)——需要它交付的 session/事务传递 API
## Parent #151(ADR-0013 ①层单一事务边界落地——请求级事务,issue #108 Q1)。事务边界方向已确认为**分段**: 事务只包住连续无外部 I/O 打断的一段纯 DB 读写,下一步要发起任何外部调用前当前段必须先提交/关闭 (见 #151 comments"拆片前的事务边界设计方向已与用户确认")。 本片负责**反思闭环家族**:`reflection.py`(含 `_apply_outcome`/`_commit_lesson`,`run_reflection_cycle` 驱动)、`drift_veto.py`(人设漂移守护,`judge_and_maybe_veto`)、`unanswered_escalation.py`(未获回应 升级)、`proactive_reconnect.py`(Recall 冷却计时)。这几个模块是反思/背景处理这条路径上的相邻环节。 ## Acceptance criteria **一、`_apply_outcome`(`reflection.py`):单一段,无内部外部 I/O 打断** 核实现状发现这个函数内部的写入序列(`get_slow_affective_state` 读 → `update_fast_affective_state` 写 → 条件性 `update_slow_affective_state` 写 → `get_proactivity_offset` 读 → `update_proactivity_offset` 写)**之间没有任何外部调用**——design-verify 阶段原文点名的"`update_fast_affective_state`/ `update_slow_affective_state` 之后 `get_proactivity_offset`(读) 再写"这个"写后读"序列,本身不构成 外部 I/O 打断(读操作不碰外部服务),可以合并成**一整段**,不需要在函数内部切段。 - [ ] `_apply_outcome` 整个函数体的全部读写合并为一段,在调用方(`run_reflection_cycle` 的 attempt 循环)进入下一个 attempt 前提交/关闭 原文(design-verify HIGH 发现,issue #151 comments,本片核实后订正其严重度判断——不是"打断"而是 "安全合并",因为读操作本身无外部 I/O): > `reflection.py::_apply_outcome`:`update_fast_affective_state`/`update_slow_affective_state` 之后 > `get_proactivity_offset`(读) 再写——同样会被打断。 **二、`_commit_lesson`(`reflection.py`):画像/技能两个候选分支,各自独立一段** - [ ] 画像候选分支:`judge_and_maybe_veto(...)`(外部 LLM 调用,`candidate_kind="profile"`)→ 若通过,新开一段 → `write_tentative_facts([candidate])` → 提交/关闭 - [ ] 技能候选分支:`judge_and_maybe_veto(...)`(外部 LLM 调用,`candidate_kind="skill"`)→ 若通过,`embedding_client.embed(skill_candidate.content)`(**又一次外部 I/O**,在写入之前)→ 新开一段 → `write_skill(...)` → 提交/关闭——技能分支比画像分支多一次外部调用(embed),落地时 不要把两个分支按同一个模板处理 - [ ] 两个分支各自独立、互不共享段(一个候选的判断/写入失败不影响另一个)——这是函数现有 docstring 已经声明的既有语义("各自独立过一次判断,通过才落库,判否/调用失败都直接丢弃,不影响另一个候选 的判断结果"),分段改造不能破坏这条既有保证 **三、`judge_and_maybe_veto`(`drift_veto.py`)内部留痕写入的提交方式——与「Delta压缩周期」姊妹片 协调,不重复设计** `judge_and_maybe_veto` 是本片与「Delta压缩周期」片共用的函数,`record_veto_if_needed`(否决/失败时 的留痕写入)该独立提交还是并入调用方的段,两片需要用同一个答案。**若「Delta压缩周期」片先落地, 本片直接复用其决定,不重新设计**;若本片先落地,按同样的推荐方案(`judge_and_maybe_veto` 内部 独立提交留痕写入)实现,并在票内留言告知「Delta压缩周期」片可以直接复用。 - [ ] 与「Delta压缩周期」片确认 `judge_and_maybe_veto`/`record_veto_if_needed` 的提交方式后, 确保本片调用点行为一致,不各自实现出两套不兼容的处理方式 **四、`unanswered_escalation.py`(未获回应升级)** - [ ] 核实该模块的存储写入点(本片起草时未逐行核实,实现期须先读一遍 `unanswered_escalation.py` 确认具体函数与写入序列,按"无外部 I/O 打断即合并、有外部调用则切段"的统一规则分段) - [ ] 若该模块的写入序列内部不含外部调用(预期如此,因为它是机械的阈值判定+情感态 delta 计算, 不涉及 LLM/embedding),整个写入序列可合并为一段 **五、`proactive_reconnect.py`(Recall 冷却计时)** - [ ] `apply_partial_relief`/`apply_full_reset` 两个状态转移各自是单一写入(`ReconnectCooldownState` 只有一个字段 `last_interaction_at`),天然不存在"写后读打断"问题——本片只需要给这两个函数(及 调用它们的存储方法)接上"一"节地基片交付的 session 参数,不需要额外的分段设计 **六、测试** - [ ] `_commit_lesson` 两个分支各补一条防空转测试:画像分支验证"判断通过但写入前崩溃,候选未落库"; 技能分支同理,且要覆盖 embed() 与 write_skill 之间的崩溃场景(两次外部 I/O 中的第二次之后) - [ ] `_apply_outcome` 补一条测试验证整个函数体确实作为一段提交(构造函数体中途崩溃,断言此前 所有写入均未落库——因为是单一段,不存在"部分回滚") - [ ] 全量测试通过 ## Not in scope - `judge_and_maybe_veto`/`record_veto_if_needed` 的具体代码改动——本片与「Delta压缩周期」片协调后 由先动手的一片落地,见"三"节 - `run_reflection_cycle`(调度驱动层)本身的 session 隔离——是否属于「APScheduler 定时作业」片 范围需要那一片确认 ## Blocked by - #197(存储层分段事务基建:session 传递契约与 SAVEPOINT 修复)——需要它交付的 session/事务传递 API
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#200
No description provided.