EconomicHook实现:TTS char_count接线 #167

Merged
Yushu merged 1 commit from feat/157-economic-hook into main 2026-08-19 06:50:25 +00:00
Member

Closes #157

实现内容

ADR-0013 issue #108 grill Q7(2026-08-18 拍板"保留 port,把两种触发时机都写进 ADR"):

  • 新增 EconomicHook Protocol(ports.py,紧邻 ResourcePort):async def charge(self, chat_id: str, *, reason: str, amount: int) -> None,与 ADR-0013 原文逐字一致
  • ArisePorts.economic_hook: EconomicHook | None = None——同 resource port 的"存在与否即信号"模式,不新开 CapabilitySet 布尔位
  • TTS synthesize(#152)产出的 char_count 接线到 economic_hook.charge——_send_pending 里原本有一条声称"issue #157 范围,AC 明文排除"的过时注释,实际 AC 明确要求这条接线,已改正为真正调用 economic_hook.charge(chat_id, reason="tts_synthesize", amount=char_count)
  • economic_hookNonechar_countNone(host 未声明该统计)时静默不记账,不报错、不阻塞语音本身发出
  • 不建通用补偿/saga 引擎——charge 调用崩溃后不做任何回滚/补偿尝试,语义上等同 ADR-0013 副作用三层"已发射动作不可逆"那一层
  • 命令前置钩子路径:核实本仓当前没有任何命令挂经济动作,本票只保证 port 契约就位,不强求现在就有第一个命令消费方

两轴 review 修复

  • mediumCONTEXT.md 更新 port 状态说明("经济 hook port 已实现")时,与同文件里依赖该 port 状态的"资源态推送"(快情感态 energy 输入源)段落产生了自相矛盾——charge() 是单向调用(core→host 上报消耗),没有任何通道能让 host 把资源余量推 core,即便 port 已实现,这项输入依然恒为零。已澄清"port 已建成"与"资源态能推送进 energy 轴"是两个方向相反、互不满足的需求。
  • lowchar_count=0 是"host 声明了这项统计、这次合成确实 0 字符"的有效值,跟"host 没声明这项统计"(None)是两种不同情况——guard 用 is not None 而非真值判断,但缺少对应回归测试。补了一条测试,并用 mutation testing 确认它能捕获"guard 被误改成 if economic_hook and char_count"这类把 0 当 falsy 处理的退化写法。

测试

全部 1952 个测试通过(含 4 条新增的语音合成经济记账测试);ruff check/lint-imports/ty check 干净。新增逻辑(economic_hook 为 None、char_count 为 None、char_count=0 三种边界)均做过 mutation testing 确认能被现有测试捕获。

Closes #157 ## 实现内容 ADR-0013 issue #108 grill Q7(2026-08-18 拍板"保留 port,把两种触发时机都写进 ADR"): - 新增 `EconomicHook` Protocol(`ports.py`,紧邻 `ResourcePort`):`async def charge(self, chat_id: str, *, reason: str, amount: int) -> None`,与 ADR-0013 原文逐字一致 - `ArisePorts.economic_hook: EconomicHook | None = None`——同 `resource` port 的"存在与否即信号"模式,不新开 `CapabilitySet` 布尔位 - TTS `synthesize`(#152)产出的 `char_count` 接线到 `economic_hook.charge`——`_send_pending` 里原本有一条声称"issue #157 范围,AC 明文排除"的过时注释,实际 AC 明确要求这条接线,已改正为真正调用 `economic_hook.charge(chat_id, reason="tts_synthesize", amount=char_count)` - `economic_hook` 为 `None` 或 `char_count` 为 `None`(host 未声明该统计)时静默不记账,不报错、不阻塞语音本身发出 - 不建通用补偿/saga 引擎——`charge` 调用崩溃后不做任何回滚/补偿尝试,语义上等同 ADR-0013 副作用三层"已发射动作不可逆"那一层 - 命令前置钩子路径:核实本仓当前没有任何命令挂经济动作,本票只保证 port 契约就位,不强求现在就有第一个命令消费方 ## 两轴 review 修复 - **medium**:`CONTEXT.md` 更新 port 状态说明("经济 hook port 已实现")时,与同文件里依赖该 port 状态的"资源态推送"(快情感态 energy 输入源)段落产生了自相矛盾——`charge()` 是单向调用(core→host 上报消耗),没有任何通道能让 host 把资源余量推**回** core,即便 port 已实现,这项输入依然恒为零。已澄清"port 已建成"与"资源态能推送进 energy 轴"是两个方向相反、互不满足的需求。 - **low**:`char_count=0` 是"host 声明了这项统计、这次合成确实 0 字符"的有效值,跟"host 没声明这项统计"(`None`)是两种不同情况——guard 用 `is not None` 而非真值判断,但缺少对应回归测试。补了一条测试,并用 mutation testing 确认它能捕获"guard 被误改成 `if economic_hook and char_count`"这类把 0 当 falsy 处理的退化写法。 ## 测试 全部 1952 个测试通过(含 4 条新增的语音合成经济记账测试);`ruff check`/`lint-imports`/`ty check` 干净。新增逻辑(economic_hook 为 None、char_count 为 None、char_count=0 三种边界)均做过 mutation testing 确认能被现有测试捕获。
issue #157:ADR-0013 issue #108 grill Q7(2026-08-18 拍板"保留 port,把两种
触发时机都写进 ADR")——新增 EconomicHook Protocol(charge(chat_id, *,
reason, amount))+ ArisePorts.economic_hook: EconomicHook | None = None
(同 resource port"存在与否即信号"模式,不新开 CapabilitySet 布尔位)。

TTS synthesize(#152)产出的 char_count 接线到 economic_hook.charge——
之前 _send_pending 里有一条声称"AC 明文排除"的过时注释,实际 AC 明确要求
这条接线,已改正为真正调用。economic_hook 为 None 或 char_count 为 None
时静默不记账,不报错、不阻塞语音本身发出。不建通用补偿/saga 引擎——charge
调用崩溃后不做任何回滚(ADR-0013 副作用三层,同已发消息"接受半截效果")。

本仓当前没有任何命令挂经济动作,只保证 port 契约就位。

两轴 review 额外修复:CONTEXT.md"资源态推送"段落依赖经济 hook port 状态,
更新 port 状态说明时未同步——charge() 是单向调用(core→host),port 已
实现不代表这项 energy 输入就有数据,已澄清;补了 char_count=0(有效值,
不是"没有这项统计")的回归测试,防止 guard 被误改成真值判断。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yushu merged commit 45a6b47c2d into main 2026-08-19 06:50:25 +00:00
Yushu deleted branch feat/157-economic-hook 2026-08-19 06:50:26 +00:00
Sign in to join this conversation.
No description provided.