Skip to content

fix(reward-memory): reconcile live configuration and guide requalification - #4866

Merged
huangruiteng merged 3 commits into
mainfrom
codex/reward-memory-requalification-20260921
Sep 22, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/reward-memory-requalification-20260921

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Changing a private Reward Memory configuration invalidates its enablement receipt, but the settings catalog could still show cached verification and the recall CLI called the failure disabled. Operators and agents received no actionable recovery plan.

This change keeps the drift guard, makes the catalog reuse runtime admission validation, and separates desired automation/historical verification from effective availability. Stale or unverified bindings expose a shared configure-goal preview/apply/verify plan that retains the existing configuration pointer and complete Agent allowlist. Each command template requires an explicit invocation-registry binding, so copying it cannot silently fall back to the default registry. Applying still performs provider write/exact-readback qualification and registry synchronization; it does not automatically trust a changed configuration.

User entry points: CLI recall, quota/managed-Turn projection, status/Markdown, and the existing frontend capability configuration summary share these results. The existing editor already supports preview/reapply with the retained pointer and Agent list. No new frontend controls or bundle changes are needed: the existing summary renders the updated current projection. Lark continues to consume shared status; no new chat state owner is introduced.

Changes since the previous review

The previous review blocked only on repository integrity: 97ff03aa3 was an unsigned merge commit that deterministically fails the DCO gate. That commit no longer exists — the two feature commits were rebased onto current origin/main, so every commit in the PR range now carries Signed-off-by.

That rebase also surfaced two real regressions from the first head, both now fixed in the head under review:

  • tests/architecture/test_control_plane_import_boundaries.py and the maintainability ratchet both rejected a function-local import from loopx/control_plane/reward_memory.py into loopx/capabilities/reward_memory/experiment.py. The reconciled projection now lives in its owning capability (reward_memory_goal_configuration_summary in loopx/capabilities/reward_memory/configuration.py, which already owns goal configuration and may depend on the control plane). The control plane keeps only the provider-neutral policy projection, so there is no new outward dependency edge and no duplicate receipt rule.
  • The maintainability ratchet failure had the same single root cause and is resolved by the same move.

Validation:

  • 79 focused tests passed across Reward Memory experiment, control-plane import boundaries, the maintainability ratchet and project lifecycle goal channel.
  • Wider local run of tests/capabilities tests/presentation tests/cli_commands: 1710 passed, 21 skipped, 1 pre-existing failure on main (test_reward_memory_feedback_hint.py::test_generated_command_previews_reviewed_event_and_rejects_scope_expansion, reproducible on the base commit and unrelated to this diff).
  • CI-scoped python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation, python -m mypy and git diff --check passed.
  • Negative cases cover drift, unverified/disabled bindings, missing configuration, and mismatched Goal/Agent/provider/isolation receipts. Reading recovery guidance performs no provider writes or registry mutation.
  • Separately qualified local recovery through the existing owner, followed by one reviewed experience write, exact readback and an independent business recall. Private configuration, memories and receipts are excluded from this PR.
  • No browser visual acceptance was run for the unchanged frontend renderer; no claim of improved decision quality is made from successful storage alone.

中文:私有配置变化后旧启用回执失效,但设置页仍可能误报已验证,召回 CLI 又将故障统一标为 disabled。本修改保留漂移保护,设置页复用运行时准入校验,区分期望配置、历史回执与当前可用性;失配时提供沿用原指针及完整 Agent 名单的共享 owner 恢复计划。CLI、managed Turn、状态与现有设置页共用投影,不引入新配置权威。

上次评审唯一的阻塞项是仓库完整性:97ff03aa3 是未签署的 merge commit,必然触发 DCO 门禁;该提交已通过把两个 feature commit rebase 到当前 origin/main 而消失,PR 范围内每个提交都带有 Signed-off-by。rebase 同时暴露并修复了两个真实回归:control plane 越界导入 capability(tests/architecture/test_control_plane_import_boundaries.py)以及由此引起的 maintainability ratchet 未审阅依赖债——现在由 capability 自己持有 reconcile 投影(reward_memory_goal_configuration_summary),control plane 只保留 provider-neutral policy。79 项 focused 测试、Ruff、mypy、git diff --check 通过;本机已完成现有 owner 恢复、真实经验写入、精确读回和独立业务召回,私有材料不进入仓库。代码提交审阅,尚未宣称已部署。

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

审阅 exact head:606105d0174c10ba378faaaf9af3ea2bde4089fd

动机

这个 PR 修复的是一个容易误导操作者的状态分裂:私有 Reward Memory config 一旦被编辑,runtime admission 已会因 digest/receipt 不匹配而拒绝使用;但 settings catalog 仍可能把历史 receipt 显示成“已验证”,显式 recall 又把所有 unavailable 情况统一叫作 disabled。结果是运行时在正确 fail-closed,操作面却看不出 drift 的真实原因和安全恢复方式。

我重点验证了两个反例:缓存 receipt 是否还能让 automatic recall/ingest 看起来有效;repair command 是否可能漏掉 invoked registry、泄漏私有 pointer,或在只读查看时产生 provider/registry effect。两者在当前 head 都被正确封住。

改动思路

resolve_goal_reward_memory_experiment 是共享的只读 admission owner:catalog 不再复制一套简化 receipt 规则,而是复用与 runtime 相同的 config digest、Goal/Agent、provider、isolation、writability 和 exact-readback 校验。投影明确分开 desired/historical 与 effective/current:配置意图可以继续显示,但 drift/unverified 时 effective availability 和 effective automation 必须为 false。

恢复不新增 authority。_enablement_repair 只生成 configure-goal 的 preview/apply/verify 模板,保留完整 Agent allowlist,且每条命令都把 --registry <invoked-registry> 放在 command 前并声明 required binding。真正的 provider canary write、exact readback 与 registry synchronization 仍只在既有 configure-goal --execute owner 中发生。

具体改动

  • experiment resolver 增加 already-loaded Goal 入口,使 runtime 与 catalog 共用完整 admission 规则;stale/unverified 返回 typed reason 与 public-safe repair plan。
  • repair payload 明确 commands_are_templates=trueautomatic_apply=false,不包含 registry 实际路径、config pointer、provider URI 或 credential;disabled 状态不返回 repair。
  • reward_memory_goal_policy_summary 增加 binding_statuseffective_availabledesired_automation 与历史/有效 verified Agent 的区分。只有当前至少一个 Agent 真正 available 时 effective automatic flags 才能为 true。
  • agent-turn-recall 保留真实 unavailable status/reason;quota boundary、status projection 与 Markdown 传递同一 repair plan。现有 configuration catalog/frontend summary 消费新增 current fields,不引入新的 editor 或配置权威。
  • exact head 上运行了 89 项相关测试(experiment、turn recall、outcome lifecycle、capability UI、chat configuration),全部通过;Ruff、git diff --check 与当前 origin/main merge-tree 通过。测试覆盖逐项篡改 Goal、Agent、provider、isolation、digest、receipt,以及 missing/disabled config 和 explicit registry template parsing。

对主干的风险

我没有发现 blocking finding。default-off 边界仍成立:未同时满足 enabled + experimental + exact Agent 时不会触碰 provider;explicit disabled 不提供 repair;只读取 catalog/status/repair 不会写 registry、花 quota 或产生 external effect。配置存在、历史 receipt 存在或 repair template 可见都不等于 capability 已启用。

剩余风险主要是我没有在本地对真实外部 OpenViking 服务重新做一次 qualification;独立证据覆盖了生产 CLI、真实本地文件 binding、test provider、exact readback contract 与 no-effect branches。该分支同样处于 BEHIND;虽然与当前 main(包括较新的 Reward Memory 改动)merge-tree 无冲突,批准不替代更新基线后的 exact-head readiness。

我的整体评价

这不是单纯换文案,而是把“期望配置 / 历史证明 / 当前可用性”重新对齐到一个 admission owner,并把恢复留在原有配置 owner。新增字段都是 derived projection,没有第二份可编辑状态,也没有让 guidance 冒充授权。代码量与故障成本匹配;未来向前看的最佳简化——移除 catalog 的缓存 receipt 真值——已经在本 PR 内完成,不需要再建新的 provider 或 recovery framework。

结论:对 exact head 606105d0174c10ba378faaaf9af3ea2bde4089fd 无阻塞问题,批准;合并前仍需更新 head 并重新走 readiness。

English verdict: APPROVE - The exact head makes live config and receipt admission authoritative across recall, catalog, and status while keeping recovery template-only and explicitly registry-bound; focused negative evidence passed, with live external-provider qualification and post-rebase readiness left as residual risks.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

已将分支同步到当前 origin/main,exact head 更新为 97ff03aa3183f1737255e4ef0c09d72b081de1cf。相关 Reward Memory 改动与主干最近合入的 application/recall receipt 改动无冲突。

本地重新验证:

  • 目标验证集:89 passed
  • 改动 Python 文件 Ruff:通过
  • git diff --check origin/main...HEAD:通过
  • 出站提交 author/committer:均为已验证 GitHub noreply 身份

PR 保持未合并,等待 exact-head review 与 CI。

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
+
+Exact head reviewed: 97ff03aa3183f1737255e4ef0c09d72b081de1cf
+
+## 动机
+
+这个 PR 处理的是一个真实且容易误导操作者的状态分裂:私有 Reward Memory 配置发生变化后,runtime admission 已经会因 digest 或 qualification receipt 不匹配而 fail closed;但 configuration catalog 仍可能把历史回执显示为“已验证”,显式 recall 又把所有 unavailable 情况统一写成 disabled。因此,运行面虽然安全拒绝,设置页、Agent 和操作者却无法区分“明确停用”“配置漂移”“回执未验证”,也得不到一条保留既有 scope 的恢复路径。
+
+我用同一个合成 Goal/配置夹具分别执行了当前 origin/main 与本 exact head 的公开 CLI。仅改变私有配置字节时,基线 catalog 仍给出 automatic_recall=true 和缓存的 verified Agent,而 runtime 已返回 enablement_stale;当前 head 则保留 desired automation 和 recorded receipt,同时将 binding_status 置为 driftedeffective_available=false、有效自动化关闭,并附带只读的恢复模板。两边 registry 都保持字节不变。
+
+从目标边界看,这是一个完整而非碎片化的切片:只改 recall 文案会留下 catalog 的第二套真值,只加 catalog digest 检查又会漏掉 Goal/Agent/provider/isolation/write-readback 等完整 admission。当前做法复用现有 runtime resolver 与 configure-goal owner,没有引入新的配置权威、provider 权限或自动修复。
+
+## 改动思路
+
+权威关系收敛得合理:
+
+- Goal policy 与 repo-relative 私有配置仍是输入,resolve_goal_reward_memory_experiment 复用完整 runtime admission,校验注册 Agent、配置 schema/scope、当前 digest 和完整 enablement receipt;
+- reward_memory_goal_policy_summary 不再直接把历史 receipt 当作当前可用性,而是分离 desired/historical 与 effective/current,并让有效自动化依赖实时 admission;
+- stale/unverified 只生成 reward_memory_enablement_repair_v0 guidance:命令明确是 template、必须绑定本次 invoked registry、保留完整 Agent allowlist、automatic_apply=false
+- 真正的 provider write、exact readback、receipt replacement 与 registry mutation 仍只发生在显式执行的 configure-goal --execute
+- recall、quota/status 与 Markdown 只是消费者。配置存在、历史 receipt、repair 可见或 provider 可发现,都不会激活 capability。
+
+最强的“不应该合入”反例不是功能架构本身,而是当前 head 的仓库完整性:它通过一个未签署的 merge commit 同步 main。这个提交会被仓库自己的 DCO gate 拒绝,功能测试全绿也不能替代该门禁。
+
+## 具体改动
+
+### 关键代码讲解
+
+1. loopx/capabilities/reward_memory/experiment.py::_enablement_repair
+

  • 从 canonical Goal id、完整 enabled-Agent 列表和当前 Agent 构造 preview/apply/verify 模板。模板不携带真实 registry 路径、私有 config pointer、provider URI 或凭据;每条命令都显式要求 <invoked-registry> 绑定,且不会自动执行。

+2. loopx/capabilities/reward_memory/experiment.py::resolve_goal_reward_memory_experiment
+

  • 把原来“先读 registry 再做校验”的逻辑拆成可接收已加载 Goal 的共享只读 owner。disabled、agent-not-enabled、config missing/invalid、digest drift、receipt unverified 与 available 仍是精确分支;只有 digest、Goal/Agent/provider/isolation、writability 和 exact-readback 全部对齐才返回 available。

+3. loopx/control_plane/reward_memory.py::reward_memory_goal_policy_summary
+

  • 增加 binding_statuseffective_availabledesired_automationrecorded_verified_agents,并逐个通过共享 resolver 得到 effective Agent。这样 cached receipt 仍可作为历史事实展示,但不再直接打开 automatic_recallautomatic_ingest

+4. loopx/capabilities/agent_turn_recall/cli.py::handle_agent_turn_recall_command
+

  • unavailable 分支保留 resolver 的真实 statusreason_code,同时继续保证 provider 调用数为 0、不花 quota、不授予新 action authority、无外部写入。

+其余改动把 reason_code/repair 透传到 Goal boundary、status 与 Markdown,把 live-derived 字段放进现有 configuration catalog;英文/中文文档说明 inspect → preview → authorized apply → verify 的恢复流程。完整 diff 为 10 个文件、+399/-11,其中 213 行是回归测试、46 行是双语文档;没有新增持久状态或命令。
+
+## 对主干的风险
+
+### [P1] 当前 exact head 的 merge commit 缺少 DCO 签署
+
+97ff03aa3183f1737255e4ef0c09d72b081de1cf 的 commit body 没有有效的 Signed-off-by trailer。仓库 .github/workflows/dco.yml 会枚举 origin/main..HEAD 的每个提交并逐一校验;我在当前 head 运行同一条本地规则,明确得到:
+
+MISSING 97ff03aa3183f1737255e4ef0c09d72b081de1cf,退出码 1。
+
+这不是可忽略的远端 CI 波动,而是当前 head 确定违反仓库提交策略。最小修复是重新创建或 amend 该 merge commit 并加入合法签署(也可以把两个已签署 feature commit rebase 到当前 main),推送新 head 后重新做 exact-head review。请不要只重跑检查;head 改变后本结论不会继承。
+
+除这个 blocker 外,没有发现新的功能性 blocking finding。验证结果:
+
+- Reward Memory experiment、turn recall、outcome lifecycle、capability UI contract 与 chat configuration API:89 passed
+- 改动 Python 文件 Ruff:passed;
+- git diff --check origin/main...HEAD:passed;
+- 相同 drifted fixture 的 base/head 公开 CLI 对比:基线误报 cached effective automation;head 正确关闭 effective automation、保留 desired/historical 状态并给出 registry-bound template,且两边 registry 均无变化;
+- 当前 Goal 的 source CLI default-off 读回:status=disabledavailable=false、automatic recall/ingest false、无 external write;
+- 当前 head 的 feature runtime 文件与上一 reviewed feature commit 一致;合入的新 main 没有产生文本冲突,相关 application/recall receipt 语义仍由现有 owner 保持。
+
+### 语义与 CI 对齐
+
+这个 PR 是对既有 Reward Memory vocabulary 的扩展:enablement_stale / enablement_unverified 没有改写成新的权威,新增 repair schema 与 catalog 字段都是 derived projection。代码、双语文档和 focused tests 对 desired/historical/effective、guidance/obligation、availability/activation 的区分是一致的。按本 Goal 配置,本轮没有读取或等待远端 CI;但本地 required DCO gate 已经失败,足以阻塞当前 exact head。
+
+剩余非阻塞风险是本轮没有重复真实外部 provider requalification,也没有做浏览器视觉验收;它们分别属于部署 qualification 与未改 renderer 的 UX 读回,不改变当前功能路径判断。修复 DCO 后仍需重新跑 89 项 focused suite、DCO rule、result gate 和 remote head freshness。
+
+## 我的整体评价
+
+功能设计本身是扎实且比例合理的:它删除 catalog 的缓存 receipt 真值,复用 runtime admission,并把恢复留给已有 configure-goal owner;没有复制 provider logic、自动接受私有配置变化或增加新的前端/Lark state owner。paired base/head CLI 也证明它修复了实际 operator-visible drift,而不只是让新单测变绿。
+
+但仓库门禁对每个 PR-only commit 的签署是明确的,当前 merge commit 未满足这一点,因此我不能批准这个 exact head。请先修复提交历史并推送新 head;届时需要完整 fresh exact-head review,而不是沿用旧 approval。
+
+English verdict: REQUEST_CHANGES - head 97ff03a functionally reconciles live Reward Memory state and passes 89 focused tests, Ruff, diff hygiene, paired base/head CLI and default-off readback, but its unsigned merge commit deterministically fails the repository DCO gate; sign or replace that commit and request a fresh review.
+

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

Exact head reviewed: 97ff03aa3183f1737255e4ef0c09d72b081de1cf

动机

这个 PR 处理的是一个真实且容易误导操作者的状态分裂:私有 Reward Memory 配置发生变化后,runtime admission 已经会因 digest 或 qualification receipt 不匹配而 fail closed;但 configuration catalog 仍可能把历史回执显示为“已验证”,显式 recall 又把所有 unavailable 情况统一写成 disabled。因此,运行面虽然安全拒绝,设置页、Agent 和操作者却无法区分“明确停用”“配置漂移”“回执未验证”,也得不到一条保留既有 scope 的恢复路径。

我用同一个合成 Goal/配置夹具分别执行了当前 origin/main 与本 exact head 的公开 CLI。仅改变私有配置字节时,基线 catalog 仍给出 automatic_recall=true 和缓存的 verified Agent,而 runtime 已返回 enablement_stale;当前 head 则保留 desired automation 和 recorded receipt,同时将 binding_status 置为 driftedeffective_available=false、有效自动化关闭,并附带只读的恢复模板。两边 registry 都保持字节不变。

从目标边界看,这是一个完整而非碎片化的切片:只改 recall 文案会留下 catalog 的第二套真值,只加 catalog digest 检查又会漏掉 Goal/Agent/provider/isolation/write-readback 等完整 admission。当前做法复用现有 runtime resolver 与 configure-goal owner,没有引入新的配置权威、provider 权限或自动修复。

改动思路

权威关系收敛得合理:

  • Goal policy 与 repo-relative 私有配置仍是输入,resolve_goal_reward_memory_experiment 复用完整 runtime admission,校验注册 Agent、配置 schema/scope、当前 digest 和完整 enablement receipt;
  • reward_memory_goal_policy_summary 不再直接把历史 receipt 当作当前可用性,而是分离 desired/historical 与 effective/current,并让有效自动化依赖实时 admission;
  • stale/unverified 只生成 reward_memory_enablement_repair_v0 guidance:命令明确是 template、必须绑定本次 invoked registry、保留完整 Agent allowlist、automatic_apply=false
  • 真正的 provider write、exact readback、receipt replacement 与 registry mutation 仍只发生在显式执行的 configure-goal --execute
  • recall、quota/status 与 Markdown 只是消费者。配置存在、历史 receipt、repair 可见或 provider 可发现,都不会激活 capability。

最强的“不应该合入”反例不是功能架构本身,而是当前 head 的仓库完整性:它通过一个未签署的 merge commit 同步 main。这个提交会被仓库自己的 DCO gate 拒绝,功能测试全绿也不能替代该门禁。

具体改动

关键代码讲解

  1. loopx/capabilities/reward_memory/experiment.py::_enablement_repair

    从 canonical Goal id、完整 enabled-Agent 列表和当前 Agent 构造 preview/apply/verify 模板。模板不携带真实 registry 路径、私有 config pointer、provider URI 或凭据;每条命令都显式要求 <invoked-registry> 绑定,且不会自动执行。

  2. loopx/capabilities/reward_memory/experiment.py::resolve_goal_reward_memory_experiment

    把原来“先读 registry 再做校验”的逻辑拆成可接收已加载 Goal 的共享只读 owner。disabled、agent-not-enabled、config missing/invalid、digest drift、receipt unverified 与 available 仍是精确分支;只有 digest、Goal/Agent/provider/isolation、writability 和 exact-readback 全部对齐才返回 available。

  3. loopx/control_plane/reward_memory.py::reward_memory_goal_policy_summary

    增加 binding_statuseffective_availabledesired_automationrecorded_verified_agents,并逐个通过共享 resolver 得到 effective Agent。这样 cached receipt 仍可作为历史事实展示,但不再直接打开 automatic_recallautomatic_ingest

  4. loopx/capabilities/agent_turn_recall/cli.py::handle_agent_turn_recall_command

    unavailable 分支保留 resolver 的真实 statusreason_code,同时继续保证 provider 调用数为 0、不花 quota、不授予新 action authority、无外部写入。

其余改动把 reason_code/repair 透传到 Goal boundary、status 与 Markdown,把 live-derived 字段放进现有 configuration catalog;英文/中文文档说明 inspect → preview → authorized apply → verify 的恢复流程。完整 diff 为 10 个文件、+399/-11,其中 213 行是回归测试、46 行是双语文档;没有新增持久状态或命令。

对主干的风险

[P1] 当前 exact head 的 merge commit 缺少 DCO 签署

97ff03aa3183f1737255e4ef0c09d72b081de1cf 的 commit body 没有有效的 Signed-off-by trailer。仓库 .github/workflows/dco.yml 会枚举 origin/main..HEAD 的每个提交并逐一校验;我在当前 head 运行同一条本地规则,明确得到:

MISSING 97ff03aa3183f1737255e4ef0c09d72b081de1cf,退出码 1。

这不是可忽略的远端 CI 波动,而是当前 head 确定违反仓库提交策略。最小修复是重新创建或 amend 该 merge commit 并加入合法签署(也可以把两个已签署 feature commit rebase 到当前 main),推送新 head 后重新做 exact-head review。请不要只重跑检查;head 改变后本结论不会继承。

除这个 blocker 外,没有发现新的功能性 blocking finding。验证结果:

  • Reward Memory experiment、turn recall、outcome lifecycle、capability UI contract 与 chat configuration API:89 passed
  • 改动 Python 文件 Ruff:passed;
  • git diff --check origin/main...HEAD:passed;
  • 相同 drifted fixture 的 base/head 公开 CLI 对比:基线误报 cached effective automation;head 正确关闭 effective automation、保留 desired/historical 状态并给出 registry-bound template,且两边 registry 均无变化;
  • 当前 Goal 的 source CLI default-off 读回:status=disabledavailable=false、automatic recall/ingest false、无 external write;
  • 当前 head 的 feature runtime 文件与上一 reviewed feature commit 一致;合入的新 main 没有产生文本冲突,相关 application/recall receipt 语义仍由现有 owner 保持。

语义与 CI 对齐

这个 PR 是对既有 Reward Memory vocabulary 的扩展:enablement_stale / enablement_unverified 没有改写成新的权威,新增 repair schema 与 catalog 字段都是 derived projection。代码、双语文档和 focused tests 对 desired/historical/effective、guidance/obligation、availability/activation 的区分是一致的。按本 Goal 配置,本轮没有读取或等待远端 CI;但本地 required DCO gate 已经失败,足以阻塞当前 exact head。

剩余非阻塞风险是本轮没有重复真实外部 provider requalification,也没有做浏览器视觉验收;它们分别属于部署 qualification 与未改 renderer 的 UX 读回,不改变当前功能路径判断。修复 DCO 后仍需重新跑 89 项 focused suite、DCO rule、result gate 和 remote head freshness。

我的整体评价

功能设计本身是扎实且比例合理的:它删除 catalog 的缓存 receipt 真值,复用 runtime admission,并把恢复留给已有 configure-goal owner;没有复制 provider logic、自动接受私有配置变化或增加新的前端/Lark state owner。paired base/head CLI 也证明它修复了实际 operator-visible drift,而不只是让新单测变绿。

但仓库门禁对每个 PR-only commit 的签署是明确的,当前 merge commit 未满足这一点,因此我不能批准这个 exact head。请先修复提交历史并推送新 head;届时需要完整 fresh exact-head review,而不是沿用旧 approval。

English verdict: REQUEST_CHANGES - head 97ff03a functionally reconciles live Reward Memory state and passes 89 focused tests, Ruff, diff hygiene, paired base/head CLI and default-off readback, but its unsigned merge commit deterministically fails the repository DCO gate; sign or replace that commit and request a fresh review.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…the capability

The configuration catalog projection reused runtime admission to stop showing a
cached receipt as current verification, but it did so with a function-local
import from the control plane into the capability layer. That edge is rejected
by the control-plane import boundary and reported as unreviewed dependency debt
by the maintainability ratchet.

Move the reconciled summary to the reward-memory capability, which already owns
goal configuration and may depend on the control plane. The control plane keeps
the provider-neutral policy projection only. Behavior is unchanged: the catalog
and settings summary still separate desired automation and historical receipts
from the effective binding.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
@huangruiteng
huangruiteng force-pushed the codex/reward-memory-requalification-20260921 branch from 97ff03a to adea926 Compare September 22, 2026 03:09

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Exact head reviewed: adea926c0cba3c3f5b3125ad62e9e605e283ddd3

动机

这个 PR 处理的是一个真实且容易误导操作者的状态分裂:私有 Reward Memory 配置发生变化后,runtime admission 已经因 digest 或 qualification receipt 不匹配而 fail closed;但 configuration catalog 仍把历史回执当作“当前已验证”展示,显式 recall 又把所有 unavailable 情况统一写成 disabled。运行面虽然安全拒绝,设置页、Agent 和操作者却无法区分“明确停用”“配置漂移”“回执未验证”,也得不到一条保留既有 scope 的恢复路径。

我用同一套合成 Goal/配置夹具分别在 pre-PR 基线(3a419abdf,其全部相关模块与 origin/main@8f5675101 逐字节一致)和本 exact head 上运行了真实投影函数与真实 CLI。仅追加一个字节修改私有配置时:基线 summary 仍返回 automatic_recall: true,基线 CLI 返回 status: "disabled" 且没有 reason code;head 则返回 binding_status: "drifted"effective_available: falseautomatic_recall: false,同时保留 desired_automation.automatic_recall: truerecorded_verified_agents: ["pilot"],CLI 给出 status: "enablement_stale"reason_code: "config_digest_missing_or_drifted" 与带 registry 绑定的恢复模板。两边 registry 字节与 provider 调用数都没有变化。

从目标边界看这是完整的切片而不是碎片:只改 recall 文案会留下 catalog 的第二套真值,只在 catalog 里加 digest 检查又会漏掉 Goal/Agent/provider/isolation/receipt 的完整 admission。当前做法复用既有 runtime resolver 与 configure-goal owner,没有引入新的配置权威、provider 权限或自动修复。

这也是对上一次评审的收口。上次唯一的 blocker 是 97ff03aa3 是未签署的 merge commit,必然触发 DCO 门禁;该提交已通过把两个 feature commit rebase 到当前 origin/main 而消失,本 head 每个 commit 都带 Signed-off-by,远端 Sign-off 检查已 pass。

改动思路

权威关系收敛得合理:

  • Goal policy 与 repo-relative 私有配置仍是输入;resolve_goal_reward_memory_experiment 复用完整 runtime admission,校验注册 Agent、配置 schema/scope、当前 digest 和完整 enablement receipt;
  • 新增的 reward_memory_goal_configuration_summary 把 desired/historical 与 effective/current 分开,并让有效自动化依赖实时 admission;
  • stale/unverified 只生成 reward_memory_enablement_repair_v0 guidance:命令明确是 template、必须绑定本次 invoked registry、保留完整 Agent allowlist、automatic_apply=false
  • 真正的 provider write、exact readback、receipt replacement 与 registry mutation 仍只发生在显式执行的 configure-goal --execute
  • recall、quota/status 与 Markdown 只是消费者。配置存在、历史 receipt、repair 可见或 provider 可发现,都不会激活 capability。

rebase 同时暴露了两个真实回归,都在本 head 修复:control plane 通过函数内 import 越界依赖 capability(tests/architecture/test_control_plane_import_boundaries.pyunexpected edges: [('loopx.control_plane.reward_memory', 'loopx.capabilities.reward_memory.experiment')]),以及同一根因导致的 maintainability ratchet 未审阅依赖债。修法是把 reconcile 投影移到它本该归属的 capability(loopx/capabilities/reward_memory/configuration.py,该模块本就拥有 goal configuration,且 configure_goal.py 已有导入同一 capability 其他函数的先例),control plane 只保留 provider-neutral 的 reward_memory_goal_policy。这不是新增抽象:reward_memory_goal_policy_summary 在 control plane 被整体删除,仓库内唯一调用方 configure_goal.py 已改为导入 capability 版本。

具体改动

12 个文件、+447/-41:生产代码 +76/-40(含 control plane 的 32 行删除)、双语文档 +46、测试 +222。没有新增持久状态、命令或 schema 版本。

关键代码讲解

  1. loopx/capabilities/reward_memory/configuration.py::reward_memory_goal_configuration_summary(新增,第 24 行)

    这是 catalog 与设置页共用的唯一 reconcile 投影。automatic_ingest/automatic_recall 只有在 effective_available 为真时才为真,而 binding_statusdesired_automationrecorded_verified_agents 始终上报,使历史事实仍然可见。逐个 agent 调用共享 resolver,单个 agent 的 ValueError 只跳过该 agent,不会清空整个投影。

  2. loopx/capabilities/reward_memory/experiment.py::resolve_goal_reward_memory_experiment(第 867 行)

    把原来“先读 registry 再做校验”的逻辑拆成可接收已加载 Goal 的共享只读 owner。disabled、agent-not-enabled、config missing/invalid、digest drift、receipt unverified 与 available 仍是精确分支;只有 digest、Goal/Agent/provider/isolation、writability 与 exact-readback 全部对齐才返回 available。catalog 因此不需要第二套 receipt 规则。

  3. loopx/capabilities/reward_memory/experiment.py::_enablement_repair(第 791 行)

    从 canonical Goal id、完整 enabled-Agent 列表与当前 Agent 构造 preview/apply/verify 模板。模板不携带真实 registry 路径、私有 config pointer、provider URI 或凭据;每条命令显式要求 <invoked-registry> 绑定,registry_context=reuse_invoked_registryautomatic_apply=false,且不会自动执行。

  4. loopx/capabilities/agent_turn_recall/cli.py::handle_agent_turn_recall_command(第 196 行)

    unavailable 分支保留 resolver 的真实 status(缺省 not_available)与 reason_code,同时继续保证 provider 调用数为 0、不花 quota、不授予新 action authority、suppress_external_sinks 为 true。这是本 PR 唯一对外可见的显示语义变化,已在 PR 正文与双语文档中披露。

其余改动把 reason_code/repair 透传到 Goal boundary、status 与 Markdown,把 live-derived 字段放进现有 configuration catalog,并在英文/中文 README 说明 inspect → preview → authorized apply → verify 的恢复流程。

对主干的风险

loopx canary premerge --from-git-diff --git-diff-base origin/mainpassed(19 checks,0 failures,含 maintainability ratchet smoke、semantic-vocabulary drift smoke 与 public-boundary smoke)。

  • 79 passed:tests/capabilities/test_reward_memory_experiment.pytests/architecture/test_control_plane_import_boundaries.pytests/canary/test_maintainability_ratchet.pytests/cli_commands/test_project_lifecycle_goal_channel.py
  • 更宽的本地运行 pytest tests/capabilities tests/presentation tests/cli_commands:1710 passed、21 skipped,1 个失败(test_reward_memory_feedback_hint.py::test_generated_command_previews_reviewed_event_and_rejects_scope_expansion)在基线 commit 上同样复现,与本 diff 无关,已如实列出而未隐藏;
  • python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation:passed;python -m mypySuccess: no issues found in 22 source filesgit diff --check origin/main...HEAD:clean;
  • 修复提交的行为保持性:同一夹具在上一 head(97ff03aa3,control plane owner)与本 head(capability owner)上的 CLEAN/DRIFT 投影 JSON 逐字节一致,diff 只差 owner 名称与 checkout 路径;
  • 独立 CLI 探针:default-off 情况在基线与 head 均为 disabledavailable: false、无 repair、无写入;drifted 情况 head 返回 enablement_stale + registry 绑定模板,provider_call_count: 0external_writes_performed: false、registry 字节不变;
  • 负例覆盖 drift、unverified/disabled、缺配置与 receipt 的 Goal/Agent/provider/isolation 字段错配;读取恢复指引不产生任何 provider 写入或 registry mutation。

语义与 CI 对齐

本 PR 扩展的是既有 Reward Memory vocabulary:enablement_stale / enablement_unverified 未被改写成新的权威,新增的 reward_memory_enablement_repair_v0 是派生 guidance,catalog 新字段都是 derived projection。代码、双语文档与 focused tests 对 desired/historical/effective、guidance/obligation、availability/activation 的区分一致;automatic_apply=falsecommands_are_templates=true 使“指引”与“机器强制”在契约里显式可辨。

剩余非阻塞风险:(1)外部若按字面 status == "disabled" 分支消费 recall CLI,现在需要处理 enablement_stale/enablement_unverified/not_available;envelope 仍保留稳定的 available 与内嵌 experimentloopx turn/quota 使用的进程内 API 未受影响。(2)本机未重复真实外部 provider 的 requalification,apply 路径仍是既有 configure-goal --execute 的 provider write/exact-readback 流程,本 PR 未宣称部署。(3)上述 1 个 main 既有失败与本 diff 无关。(4)examples/semantic-vocabulary-drift-smoke.py 需要 worktree 内有 node_modules,缺失时它以 TypeScript parser 失败退出;建立符号链接后通过,这不是本 diff 引入的问题。

我的整体评价

功能设计本身扎实且比例合理:它删除 catalog 的缓存 receipt 真值,复用 runtime admission,把恢复留给已有 configure-goal owner,并把 reconcile 投影放回它的正确所有者;没有复制 provider logic、自动接受私有配置变化或增加新的前端/Lark state owner。paired base/head 投影与 CLI 探针证明它修复了实际 operator-visible drift,而不只是让新单测变绿;修复提交的迁移被证明是行为保持的。

上一次评审唯一的阻塞项是仓库完整性(未签署的 merge commit),它已通过 rebase 消失并且远端 Sign-off 已通过;由此暴露的 import-boundary 与 ratchet 回归也已按所有权修正。因此我对本 exact head 给出通过结论,并据此执行 owner 授权的自合并。

English verdict: APPROVE - head adea926 reconciles live Reward Memory configuration with the settings catalog and recall CLI, deletes the control-plane copy of the projection to remove an outward capability dependency, and carries a registry-bound requalification template; the previous DCO blocker is gone (rebased, all commits signed), and validation passed (79 focused tests, 1710 passed wider run with 1 pre-existing main failure named, Ruff, mypy, git diff --check, canary premerge 19/19, byte-identical base/head projection payloads, default-off parity via real CLI probes).

@huangruiteng
huangruiteng merged commit 2fff805 into main Sep 22, 2026
28 checks passed
@huangruiteng
huangruiteng deleted the codex/reward-memory-requalification-20260921 branch September 22, 2026 03:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant