issue #136: 新增未获回应升级——情感态快层第四个delta输入源 #143

Merged
Yushu merged 1 commit from feat/136-unanswered-escalation-input into main 2026-08-17 04:09:27 +00:00
Member

Closes #136

实现范围

新增"未获回应升级"——ADR-0005 拍板但此前零实现的第四个情感态快层 delta 输入源。己方发出的有分量消息(expects_reply=true,issue #42 既有自报字段)迟迟未获对方真实回应时,按阶梯式时长门槛施加逐档加重的 valence/energy 负向 delta;一旦真的等到回应,清掉待升级记录,不再继续施加。

  • 只驱动 fast layer 的 valence/energy,不接 dominance、不接慢层update_fast_state 三轴无条件各跑一次 decay_towardoutcome=None 只让 delta 项归零、衰减本身不会跳过——落库前用 dataclasses.replace() 只截取 valence/energy 两轴写回,dominance 保留调用前原值(仿 issue #94 _apply_interaction_polarity 的既有截取先例)。慢层完全不碰:这个信号是"投递未获确认"的代理信号,不是对方真实情感倾向的证据。
  • 判定"是否已回应"复用已有状态,不新开追踪:新增只读函数 resolve_last_interaction_at(从 reflection.py 原有的内联重复分流逻辑收敛而来)——私聊读 ReconnectCooldownState,群聊读 ChatActivityState,两种 chat 类型都覆盖。
  • 触发落点:新增独立的 arise_unanswered_escalation 周期任务,扫描间隔单独配置(不与反思闭环共用)。零 LLM/embedding 调用,不需要熔断闸。
  • 阶梯累加_crossed_tier_deltas 从上次已应用档位往后扫,一次扫描若跨过多个档位,累加全部新跨过档位的 delta,不静默丢档。

两处刻意的 AC 字面偏离(已核实并留痕)

  1. "有分量的消息"判定标准:用 expects_reply==True 直接判定,没有另外新增一个独立的连续"重要性"数值字段——AC 同时写了"结合 expects_reply 标记"与"config 新增重要性门槛"两条,二元判定没有"门槛"可言。理由:仓库没有更好的现成连续信号(唯一的 importance 量表来自异步 Delta 压缩批处理,时效对不上小时级阶梯);本地文本长度/疑问句启发式已被 ADR-0025 明确否决。
  2. 群聊作用域扩大:ADR-0005 原文写"复用 Recall 冷却计时器"时群聊确实还没有对应的"是否已回应"信号,但 issue #133 已经填平这个缺口(chat_activity.py)。继续把本片限定在私聊没有依据——这是历史遗留的措辞,不是架构限制,经对抗式设计校验核实。

两轴 review 发现并已修复的一处范围收窄

初稿只在反应式回复路径(entry_reactive.py)接了写入点,Drive Tick 主动重连发送(entry_drive_tick.py)完全没接。但 ADR-0005 原文"己方主动发出的、有分量的消息"这个措辞、以及 apply_partial_relief 的唯一调用点,指的正是 Drive Tick 这条主动出口——已补上,两条"己方发出"的出口现在都会在 expects_reply=true 时记一条待升级记录。

验证

  • 新增单元测试覆盖:_crossed_tier_deltas 纯函数(含多档累加边界)、run_unanswered_escalation_cycle(dominance/慢层不受影响、已回应清记录、私聊/群聊分流、跨多档)、resolve_last_interaction_at、存储层往返(内存/持久化两套实现对称)、反应式与 Drive Tick 两条写入路径的 e2e 场景。
  • 变异测试:7 处新守卫逐一验证(阶梯累加改为只取末档、dominance 截取移除、"已回应"判定恒假、私聊/群聊分支翻转、entry_reactive 写入点移除、存储层 tier 重置移除、Drive Tick 写入点移除),全部被现有测试正确捕获,mutation 后均已用备份精确还原并核对哈希。
  • 全量测试 1864 个全绿,ruff check/ruff format 干净,ty 类型检查确认无新增诊断(仅命中仓库既有、与本次改动无关的历史问题)。
  • 两轴 review(Standards + Spec)+ 对抗式 Verify:Standards 轴零发现;Spec 轴 1 条 CONFIRMED(上述 Drive Tick 遗漏)已修复。

文档同步

docs 分支(本地已提交,不推送):ADR-0005 追加两个更新节——落地状态记录(群聊作用域裁定订正、AC 字面偏离留痕、阶梯累加设计修正)+ review 发现的 Drive Tick 遗漏补记。design.md 现有的"未获回应升级"描述本身已经是目标态,未改动。ADR-0018 边界划分文本不受影响,未改动。

🤖 Generated with Claude Code

Closes #136 ## 实现范围 新增"未获回应升级"——ADR-0005 拍板但此前零实现的第四个情感态快层 delta 输入源。己方发出的有分量消息(`expects_reply=true`,issue #42 既有自报字段)迟迟未获对方真实回应时,按阶梯式时长门槛施加逐档加重的 valence/energy 负向 delta;一旦真的等到回应,清掉待升级记录,不再继续施加。 - **只驱动 fast layer 的 valence/energy,不接 dominance、不接慢层**:`update_fast_state` 三轴无条件各跑一次 `decay_toward`,`outcome=None` 只让 delta 项归零、衰减本身不会跳过——落库前用 `dataclasses.replace()` 只截取 valence/energy 两轴写回,dominance 保留调用前原值(仿 issue #94 `_apply_interaction_polarity` 的既有截取先例)。慢层完全不碰:这个信号是"投递未获确认"的代理信号,不是对方真实情感倾向的证据。 - **判定"是否已回应"复用已有状态,不新开追踪**:新增只读函数 `resolve_last_interaction_at`(从 `reflection.py` 原有的内联重复分流逻辑收敛而来)——私聊读 `ReconnectCooldownState`,群聊读 `ChatActivityState`,两种 chat 类型都覆盖。 - **触发落点**:新增独立的 `arise_unanswered_escalation` 周期任务,扫描间隔单独配置(不与反思闭环共用)。零 LLM/embedding 调用,不需要熔断闸。 - **阶梯累加**:`_crossed_tier_deltas` 从上次已应用档位往后扫,一次扫描若跨过多个档位,累加全部新跨过档位的 delta,不静默丢档。 ## 两处刻意的 AC 字面偏离(已核实并留痕) 1. **"有分量的消息"判定标准**:用 `expects_reply==True` 直接判定,没有另外新增一个独立的连续"重要性"数值字段——AC 同时写了"结合 expects_reply 标记"与"config 新增重要性门槛"两条,二元判定没有"门槛"可言。理由:仓库没有更好的现成连续信号(唯一的 `importance` 量表来自异步 Delta 压缩批处理,时效对不上小时级阶梯);本地文本长度/疑问句启发式已被 ADR-0025 明确否决。 2. **群聊作用域扩大**:ADR-0005 原文写"复用 Recall 冷却计时器"时群聊确实还没有对应的"是否已回应"信号,但 issue #133 已经填平这个缺口(`chat_activity.py`)。继续把本片限定在私聊没有依据——这是历史遗留的措辞,不是架构限制,经对抗式设计校验核实。 ## 两轴 review 发现并已修复的一处范围收窄 初稿只在反应式回复路径(`entry_reactive.py`)接了写入点,Drive Tick 主动重连发送(`entry_drive_tick.py`)完全没接。但 ADR-0005 原文"己方主动发出的、有分量的消息"这个措辞、以及 `apply_partial_relief` 的唯一调用点,指的正是 Drive Tick 这条主动出口——已补上,两条"己方发出"的出口现在都会在 `expects_reply=true` 时记一条待升级记录。 ## 验证 - 新增单元测试覆盖:`_crossed_tier_deltas` 纯函数(含多档累加边界)、`run_unanswered_escalation_cycle`(dominance/慢层不受影响、已回应清记录、私聊/群聊分流、跨多档)、`resolve_last_interaction_at`、存储层往返(内存/持久化两套实现对称)、反应式与 Drive Tick 两条写入路径的 e2e 场景。 - 变异测试:7 处新守卫逐一验证(阶梯累加改为只取末档、dominance 截取移除、"已回应"判定恒假、私聊/群聊分支翻转、entry_reactive 写入点移除、存储层 tier 重置移除、Drive Tick 写入点移除),全部被现有测试正确捕获,mutation 后均已用备份精确还原并核对哈希。 - 全量测试 1864 个全绿,`ruff check`/`ruff format` 干净,`ty` 类型检查确认无新增诊断(仅命中仓库既有、与本次改动无关的历史问题)。 - 两轴 review(Standards + Spec)+ 对抗式 Verify:Standards 轴零发现;Spec 轴 1 条 CONFIRMED(上述 Drive Tick 遗漏)已修复。 ## 文档同步 docs 分支(本地已提交,不推送):ADR-0005 追加两个更新节——落地状态记录(群聊作用域裁定订正、AC 字面偏离留痕、阶梯累加设计修正)+ review 发现的 Drive Tick 遗漏补记。design.md 现有的"未获回应升级"描述本身已经是目标态,未改动。ADR-0018 边界划分文本不受影响,未改动。 🤖 Generated with [Claude Code](https://claude.com/claude-code)
己方发出的有分量消息(expects_reply=true)迟迟未获回应,按阶梯式时长门槛
施加逐档加重的valence/energy负向delta;一旦真的等到回应,清掉待升级记录。
只驱动fast layer的valence/energy,dominance/慢层均不接触(仿issue #94
_apply_interaction_polarity的replace()截取先例,避免dominance无端多挨
一次衰减)。

判定"是否已回应"复用issue #133已做成chat类型无关的双锚点分流(私聊读
ReconnectCooldownState,群聊读ChatActivityState),抽成共享函数
resolve_last_interaction_at,reflection.py的原内联重复逻辑一并收敛。

写入点覆盖反应式回复与Drive Tick主动重连两条"己方发出"出口(两轴review
抓到初稿遗漏Drive Tick通道,已补)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yushu merged commit d42a5728bd into main 2026-08-17 04:09:27 +00:00
Yushu deleted branch feat/136-unanswered-escalation-input 2026-08-17 04:09:28 +00:00
Sign in to join this conversation.
No description provided.