feat(reward-memory): implement utility attribution Stage 2 - #3829
feat(reward-memory): implement utility attribution Stage 2#3829yuefengw wants to merge 4 commits into
Conversation
Signed-off-by: yuefengw <60574042+yuefengw@users.noreply.github.com>
Signed-off-by: yuefengw <60574042+yuefengw@users.noreply.github.com>
Signed-off-by: yuefengw <60574042+yuefengw@users.noreply.github.com>
33e960b to
1bae7b9
Compare
Signed-off-by: yuefengw <60574042+yuefengw@users.noreply.github.com>
1bae7b9 to
e278d1c
Compare
|
Follow-up: rebased onto latest |
There was a problem hiding this comment.
Findings
[P1] 截断后的 readback validator 丢失 label 与 evidence tier 的关联,可把强 harmful 篡改成 helpful 后继续通过
_bound_history 在超过 256 条时只保证每个 subject 的最新 entry 被保留;较早但证据更强的 observation 可以被丢弃。此后 _validate_aggregate_subject_semantics 只分别检查 evidence_strength[strongest_basis] > 0 和 support[effective_label] > 0,没有任何 joint fact 证明这个 label 真的来自 strongest tier。触发场景:同一 item 先有 1 条 owner_correction=harmful(confidence 0.8),再有 256 条较新的 evaluator_inference=helpful。Reducer 正确输出 harmful,但旧的 owner correction 不在 bounded history 中;把 subject 改为 effective_utility_label=helpful、utility_estimate=+0.8、清掉 attenuation review 后,validate_reward_memory_utility_projection 仍接受,并保留 projection_ready=true。
这违反协议“最高 evidence tier 决定 effective direction”和“history 截断后仍 fail-closed”的核心保证。最小修复是让 projection 保留可验证的 label×evidence-basis 联合计数/最强层摘要(或保证并验证所有决定 effective state 的 observation 都在 bounded history 中),再从该联合事实验证 effective label、basis、confidence 与 review。请加 257 条同-subject 的回归测试:旧强 harmful + 新弱 helpful,篡改为 helpful 必须被拒绝。
[P2] reason code 通过异常字符串二次分类,字段名可以改变 typed taxonomy
utility_reducer.py:257-269 用 "scope" in str(exc) 等 substring 从异常文本推导状态;_validate_observation_batch 又先把内部异常转成 code 文本,外层 reducer 对这段文本再次调用 _reason_code。因此一个未知字段名 scope_hint 会把普通 unknown-field 错报为 observation_malformed_scope;而真实的 observation_write_boundary_violation 在第二次分类时又可能退化成 observation_malformed。拒绝本身仍 fail-closed,所以这是诊断/typed-state 的 P2,但它违反本仓库“分类规则由 typed enum/exception 拥有、不能解析 prose”的约束。建议用携带稳定 reason_code 的 typed exception/validation result 贯穿两层,并为 unknown field 与 write-boundary violation 各补一条精确 code 测试。
动机
Issue #3824 要补齐 Reward Memory utility attribution Stage 2:Stage 1 已能从可信 application receipt、verified outcome 与 evaluator proposal 生成 scope-bound observation,但尚没有可重放、可检查、不会改变主工作流的 utility read model。没有 reducer 时,同一 observation 的 retry、冲突 delivery、item/set/none attribution、强弱 evidence 冲突都只能留在原始流里,调用方无法得到 bounded utility、uncertainty、review proposal 与 lineage coverage。最近更小的方案如果只累计一个分数,会错误地把 set credit 分摊到 item,也无法在 owner correction 覆盖弱 inference 时保留审计历史,因此一个显式 versioned reducer 是合理的最小产品 seam;ranking、provider writeback、memory deletion、quota/scheduler/todo authority 继续是非目标。
改动思路
新 CLI loopx reward-memory utility-project 显式读取完整 observation stream、scope、retrieval/policy snapshot 与可选 previous projection。Reducer 先复用 Stage 1 validator,严格比对 scope/snapshot,再按 canonical observation id 折叠 semantic replay、隔离同 id 不同 payload 的 delivery;随后按 item/set/none subject 分组,以 owner_correction > controlled_replay > deterministic_effect > evaluator_inference > insufficient 计算有效方向、confidence、uncertainty 和 review proposal。输出经第二个 readback validator 复核 identity、边界布尔值、计数、history、subject 与 proposal 的交叉一致性。
正向路径是“显式 CLI/API 输入 -> Stage 1 normalization -> replay/conflict grouping -> subject reduction -> bounded history -> readback validation -> read-only projection”。负向路径中,malformed observation 或 scope/snapshot/version mismatch 返回 status=rejected 且没有 subjects;同 observation id 的不同 delivery 不参与 utility,只形成 quarantine proposal;harmful 只形成 attenuation proposal,不会执行删除或外部写。当前 P1 发生在 history 已截断后的 readback 路径:决定性强证据被丢弃后,aggregate marginals 不足以重新证明 reducer 的联合语义。
具体改动
Exact head e278d1c6724b850ad5967977fb764dbe3968be37 相对 PR base 共 17 个文件、+3150/-53:runtime/API +1854/-11,tests/examples +945/-0,docs/README +351/-42。生产面新增 reducer、独立 readback validation、CLI command、public exports、architecture/catalog registration,并只对 Stage 1 confidence overflow 做兼容性加固;测试与 smoke 覆盖 label、replay、conflict、precedence、set/none、mismatch、tampering、history budget 和 no-write boundary;中英文 protocol/RFC/README 同步描述 Stage 2 与非目标。
关键代码讲解
reduce_reward_memory_utility_observations:公共 reduction owner;校验 context/previous identity,调用 batch normalization,生成 subject/history/rejections,最后强制经过 readback validator。没有 provider、ranking 或 lifecycle side effect,CLI 是真实 production caller。_validate_observation_batch:以observation_id + semantic fingerprint区分 replay 与 conflicting delivery;冲突 identity 整体不进入 accepted subject,并生成 bounded rejection facts。_reduce_subject:实现 evidence precedence、same-tier conflict、strong unknown、confidence 合并以及 harmful/none review proposal,是 utility 方向的核心语义 owner。_bound_history:保证最多 256 条且每个 subject 至少保留 latest;它没有保留“决定 effective state 的最强 evidence”,与后续 aggregate validator 组合后产生本次 P1。validate_reward_memory_utility_projection/_validate_aggregate_subject_semantics:复核公共 projection。未截断时可以从完整 history 重算 subject;截断时退化到边际计数,当前无法验证 label 与 strongest basis 的对应关系。
对主干的风险
最强风险不是 reducer 首次计算错误,而是一个已持久化/传输的 truncated projection 被错误或恶意修改后仍被公共 validator 视为 canonical。因为 harmful 可以被翻成 helpful 且 projection_ready 保持 true,未来任何把这个 read model 接入人工 review、attenuation 或 ranking 实验的 consumer 都可能收到反向信号;当前虽无 action authority,协议完整性已经是 Stage 2 的 shipped contract,不能推迟到 provider integration 再修。回滚很简单(该 command 是新增且无写 side effect),但最低修复需要补足联合 aggregate 事实,而不是只增加一条 history 示例。
Default-off/隔离方面,现有主工作 lane、retrieval、provider、quota、scheduler 与 Todo 路径没有调用 reducer;只有显式 CLI/API 会执行,architecture/catalog 的变化是加法式 discoverability。Authority semantics 也基本对齐:read_only=true,所有 action/provider/external-write grant 均为 false,conflict/attenuation/quarantine 都明确是 proposal。Item、set 与 none 使用不同 subject identity,domain wording 保持 Reward Memory capability 内部,没有把它提升为通用 control-plane obligation。
独立验证:Reward Memory focused Python suite 150 passed;architecture 与 utility reducer 两个 smoke 通过;targeted mypy 通过;Ruff lint 与 git diff --check 通过;premerge gate 17/17 通过;public-boundary scan 17 files clean;GitHub 11 个 checks 全部成功。ruff format --check 对 catalog_entry.py 仍报告 whole-file drift,但相同 drift 在 PR base 已存在,未作为本 PR blocker。上述绿色验证没有覆盖 P1 的 label×tier tampering counterexample。
我的整体评价
方向、placement 与 no-write boundary 是对的,17-file 变更也围绕 Issue #3824 的单一 Stage 2 seam;大量代码主要来自严格 projection validation 和系统性负向测试,修复 joint aggregate 后 scope 可以保持在本 PR 内。当前却在最需要 readback proof 的 truncation 分支丢失了 evidence precedence 的决定性关联,导致协议宣称的 fail-closed validation 不成立;typed reason taxonomy 也还依赖 prose substring。结论为 Request changes:先补充可验证的 label×evidence 联合事实和 257-entry tamper regression,并把 reason code 改为 typed propagation;无需在本 PR 引入 ranking、provider writeback 或自动 attenuation。
English verdict: REQUEST_CHANGES on exact head e278d1c6724b850ad5967977fb764dbe3968be37. The reducer is well-scoped, deterministic on its normal path, and independently passes focused tests, smokes, mypy, premerge, and all GitHub checks. However, once history is truncated, the readback validator loses the label-to-evidence-tier relationship and accepts a tampered helpful result even when the only strongest-tier observation was harmful. Preserve and validate joint label×tier evidence, add the 257-observation tamper regression, and replace prose-substring reason classification with a typed code path before re-review.
LIHUA919
left a comment
There was a problem hiding this comment.
动机
Issue #3824 要把 Stage 1 的观察流收敛为确定性、幂等、只读的 utility projection。当前 PR 的能力边界总体正确:显式 CLI/API 才触发归约,item、set、none 分开,强证据覆盖弱推断,冲突只形成 review/quarantine proposal,不改变检索、排名、provider、记忆生命周期、配额或主工作流。只做分数累积无法保持 attribution 与 evidence precedence,因此独立 reducer 和 readback validator 是合理的最小产品边界。
改动思路
Exact head e278d1c 的正向路径是完整观察流进入 Stage 1 validator,按 observation identity 折叠 replay 和冲突 delivery,再按 subject 与 evidence tier 归约,生成 bounded history,最后由 readback validator 复核 projection。负向路径对格式、scope、snapshot、version 和冲突 fail-closed,但保持主工作 lane 不受影响。
当前仍有两个必须修复的语义缺口。第一,history 超过 256 条后,subject 只保留 label 与 evidence tier 的边际计数,无法证明 effective label 来自 strongest tier;旧的 owner_correction harmful 被截断后,可以把结果改成 helpful 并继续通过 readback。第二,reason code 通过异常字符串 substring 二次分类,未知字段 scope_hint 会误报 scope 错误,真实 provider write boundary 违规又可能退化为普通 malformed。
具体改动
PR 共 17 个文件,覆盖 utility_reducer.py、utility_projection_validation.py、Stage 1 numeric boundary、CLI/public exports、architecture/catalog、中英文协议、测试与 smoke。关键行为符号包括:reduce_reward_memory_utility_observations 负责完整流和无副作用结果;_validate_observation_batch 负责 replay、conflict 与 context fencing;_reduce_subject 负责 typed precedence、confidence 和 review proposal;_bound_history 负责 256 条预算;validate_reward_memory_utility_projection 负责公共 readback。
我已基于该 exact head 准备 stacked fix:yuefengw#1 ,提交 972dba2。补丁增加稀疏 evidence-label 联合摘要,让截断后的 validator 能重建 strongest tier、effective label、confidence 与 review,同时校验联合计数和两组边际计数一致;Stage 1 validation failure 改为携带稳定 reason_code 的 typed exception,外层不再解析错误文案;另加入 257 条同 subject 的 harmful-to-helpful tamper 回归和 scope_hint/write-boundary 精确分类测试,并同步中英文协议。
对主干的风险
当前最大风险是 readback 完整性,而不是默认运行路径:一个被持久化或传输的 truncated projection 可以把强 harmful 改成 weaker helpful,并仍保持 projection_ready=true。未来 consumer 即使只有人工 review 或 attenuation,也会接收到反向信号。reason taxonomy 的 substring 依赖则会让诊断状态随字段名和异常措辞漂移。两者都应在 Stage 2 合并前解决。
独立验证结果:完整 Reward Memory 目标集 142 passed;architecture 与 utility-reducer smokes 通过;Ruff lint/format、targeted mypy 通过;LoopX standard premerge 17/17 通过且无 manual hold;公共边界扫描通过。沙箱内一次 Effect runtime 启动受限,沙箱外同一用例与完整测试集均通过。补丁不增加 ranking、provider writeback、自动 attenuation、权限或外部写入。
我的整体评价
PR 的方向、placement、显式 opt-in 和 no-write boundary 值得保留,测试与文档覆盖也较完整;代码量虽然较大,但集中在一个 Stage 2 协议和验证边界。当前 exact head 仍包含两个已复现 blocker,因此结论保持 Request changes。原作者合入 stacked fix #1 后,应在新的 exact head 重跑 focused tests、smokes、premerge 和完整 readback tamper 用例,再做复审。相关的 future-facing pass 已落在现有 Stage 1 validator 与 Stage 2 aggregate boundary,没有引入新的 capability 或 provider abstraction。
English verdict: Request changes on exact head e278d1c. The PR is well-scoped and default-off, but truncated readback loses the label-to-evidence-tier relationship and reason classification parses exception prose. A validated stacked fix is available at yuefengw#1 with commit 972dba2; merge it, rerun the focused validation, and request re-review on the new exact head.
huangruiteng
left a comment
There was a problem hiding this comment.
Findings
[P1] 截断后的 readback validator 丢失 label 与 evidence tier 的关联,可把强 harmful 篡改成 helpful 后继续通过
_bound_history 在超过 256 条时只保证每个 subject 的最新 entry 被保留;较早但证据更强的 observation 可以被丢弃。此后 _validate_aggregate_subject_semantics 只分别检查 evidence_strength[strongest_basis] > 0 和 support[effective_label] > 0,没有任何 joint fact 证明这个 label 真的来自 strongest tier。触发场景:同一 item 先有 1 条 owner_correction=harmful(confidence 0.8),再有 256 条较新的 evaluator_inference=helpful。Reducer 正确输出 harmful,但旧的 owner correction 不在 bounded history 中;把 subject 改为 effective_utility_label=helpful、utility_estimate=+0.8、清掉 attenuation review 后,validate_reward_memory_utility_projection 仍接受,并保留 projection_ready=true。
这违反协议“最高 evidence tier 决定 effective direction”和“history 截断后仍 fail-closed”的核心保证。最小修复是让 projection 保留可验证的 label×evidence-basis 联合计数/最强层摘要(或保证并验证所有决定 effective state 的 observation 都在 bounded history 中),再从该联合事实验证 effective label、basis、confidence 与 review。请加 257 条同-subject 的回归测试:旧强 harmful + 新弱 helpful,篡改为 helpful 必须被拒绝。
[P2] reason code 通过异常字符串二次分类,字段名可以改变 typed taxonomy
utility_reducer.py:257-269 用 "scope" in str(exc) 等 substring 从异常文本推导状态;_validate_observation_batch 又先把内部异常转成 code 文本,外层 reducer 对这段文本再次调用 _reason_code。因此一个未知字段名 scope_hint 会把普通 unknown-field 错报为 observation_malformed_scope;而真实的 observation_write_boundary_violation 在第二次分类时又可能退化成 observation_malformed。拒绝本身仍 fail-closed,所以这是诊断/typed-state 的 P2,但它违反本仓库“分类规则由 typed enum/exception 拥有、不能解析 prose”的约束。建议用携带稳定 reason_code 的 typed exception/validation result 贯穿两层,并为 unknown field 与 write-boundary violation 各补一条精确 code 测试。
动机
Issue #3824 要补齐 Reward Memory utility attribution Stage 2:Stage 1 已能从可信 application receipt、verified outcome 与 evaluator proposal 生成 scope-bound observation,但尚没有可重放、可检查、不会改变主工作流的 utility read model。没有 reducer 时,同一 observation 的 retry、冲突 delivery、item/set/none attribution、强弱 evidence 冲突都只能留在原始流里,调用方无法得到 bounded utility、uncertainty、review proposal 与 lineage coverage。最近更小的方案如果只累计一个分数,会错误地把 set credit 分摊到 item,也无法在 owner correction 覆盖弱 inference 时保留审计历史,因此一个显式 versioned reducer 是合理的最小产品 seam;ranking、provider writeback、memory deletion、quota/scheduler/todo authority 继续是非目标。
改动思路
新 CLI loopx reward-memory utility-project 显式读取完整 observation stream、scope、retrieval/policy snapshot 与可选 previous projection。Reducer 先复用 Stage 1 validator,严格比对 scope/snapshot,再按 canonical observation id 折叠 semantic replay、隔离同 id 不同 payload 的 delivery;随后按 item/set/none subject 分组,以 owner_correction > controlled_replay > deterministic_effect > evaluator_inference > insufficient 计算有效方向、confidence、uncertainty 和 review proposal。输出经第二个 readback validator 复核 identity、边界布尔值、计数、history、subject 与 proposal 的交叉一致性。
正向路径是“显式 CLI/API 输入 -> Stage 1 normalization -> replay/conflict grouping -> subject reduction -> bounded history -> readback validation -> read-only projection”。负向路径中,malformed observation 或 scope/snapshot/version mismatch 返回 status=rejected 且没有 subjects;同 observation id 的不同 delivery 不参与 utility,只形成 quarantine proposal;harmful 只形成 attenuation proposal,不会执行删除或外部写。当前 P1 发生在 history 已截断后的 readback 路径:决定性强证据被丢弃后,aggregate marginals 不足以重新证明 reducer 的联合语义。
具体改动
Exact head e278d1c6724b850ad5967977fb764dbe3968be37 相对 PR base 共 17 个文件、+3150/-53:runtime/API +1854/-11,tests/examples +945/-0,docs/README +351/-42。生产面新增 reducer、独立 readback validation、CLI command、public exports、architecture/catalog registration,并只对 Stage 1 confidence overflow 做兼容性加固;测试与 smoke 覆盖 label、replay、conflict、precedence、set/none、mismatch、tampering、history budget 和 no-write boundary;中英文 protocol/RFC/README 同步描述 Stage 2 与非目标。
关键代码讲解
reduce_reward_memory_utility_observations:公共 reduction owner;校验 context/previous identity,调用 batch normalization,生成 subject/history/rejections,最后强制经过 readback validator。没有 provider、ranking 或 lifecycle side effect,CLI 是真实 production caller。_validate_observation_batch:以observation_id + semantic fingerprint区分 replay 与 conflicting delivery;冲突 identity 整体不进入 accepted subject,并生成 bounded rejection facts。_reduce_subject:实现 evidence precedence、same-tier conflict、strong unknown、confidence 合并以及 harmful/none review proposal,是 utility 方向的核心语义 owner。_bound_history:保证最多 256 条且每个 subject 至少保留 latest;它没有保留“决定 effective state 的最强 evidence”,与后续 aggregate validator 组合后产生本次 P1。validate_reward_memory_utility_projection/_validate_aggregate_subject_semantics:复核公共 projection。未截断时可以从完整 history 重算 subject;截断时退化到边际计数,当前无法验证 label 与 strongest basis 的对应关系。
对主干的风险
最强风险不是 reducer 首次计算错误,而是一个已持久化/传输的 truncated projection 被错误或恶意修改后仍被公共 validator 视为 canonical。因为 harmful 可以被翻成 helpful 且 projection_ready 保持 true,未来任何把这个 read model 接入人工 review、attenuation 或 ranking 实验的 consumer 都可能收到反向信号;当前虽无 action authority,协议完整性已经是 Stage 2 的 shipped contract,不能推迟到 provider integration 再修。回滚很简单(该 command 是新增且无写 side effect),但最低修复需要补足联合 aggregate 事实,而不是只增加一条 history 示例。
Default-off/隔离方面,现有主工作 lane、retrieval、provider、quota、scheduler 与 Todo 路径没有调用 reducer;只有显式 CLI/API 会执行,architecture/catalog 的变化是加法式 discoverability。Authority semantics 也基本对齐:read_only=true,所有 action/provider/external-write grant 均为 false,conflict/attenuation/quarantine 都明确是 proposal。Item、set 与 none 使用不同 subject identity,domain wording 保持 Reward Memory capability 内部,没有把它提升为通用 control-plane obligation。
独立验证:Reward Memory focused Python suite 150 passed;architecture 与 utility reducer 两个 smoke 通过;targeted mypy 通过;Ruff lint 与 git diff --check 通过;premerge gate 17/17 通过;public-boundary scan 17 files clean;GitHub 11 个 checks 全部成功。ruff format --check 对 catalog_entry.py 仍报告 whole-file drift,但相同 drift 在 PR base 已存在,未作为本 PR blocker。上述绿色验证没有覆盖 P1 的 label×tier tampering counterexample。
我的整体评价
方向、placement 与 no-write boundary 是对的,17-file 变更也围绕 Issue #3824 的单一 Stage 2 seam;大量代码主要来自严格 projection validation 和系统性负向测试,修复 joint aggregate 后 scope 可以保持在本 PR 内。当前却在最需要 readback proof 的 truncation 分支丢失了 evidence precedence 的决定性关联,导致协议宣称的 fail-closed validation 不成立;typed reason taxonomy 也还依赖 prose substring。结论为 Request changes:先补充可验证的 label×evidence 联合事实和 257-entry tamper regression,并把 reason code 改为 typed propagation;无需在本 PR 引入 ranking、provider writeback 或自动 attenuation。
English verdict: REQUEST_CHANGES on exact head e278d1c6724b850ad5967977fb764dbe3968be37. The reducer is well-scoped, deterministic on its normal path, and independently passes focused tests, smokes, mypy, premerge, and all GitHub checks. However, once history is truncated, the readback validator loses the label-to-evidence-tier relationship and accepts a tampered helpful result even when the only strongest-tier observation was harmful. Preserve and validate joint label×tier evidence, add the 257-observation tamper regression, and replace prose-substring reason classification with a typed code path before re-review.
|
Two notes that may help the merge decision:
I haven't gone through all 1.4k lines of |
Summary
Closes #3824.
This PR implements Reward Memory utility attribution Stage 2 inside the existing
reward_memorycapability. It reduces a complete Stage 1 observation stream intoa deterministic, bounded
memory_utility_projection_v0and exposes the read-onlyprojection through
loopx reward-memory utility-project(with theutility-reducealias).Shipped behavior
retrieval-snapshot, and policy-snapshot bindings;
observation_ida no-op and quarantines changeddeliveries as conflicts;
none) attribution separate;bounded utility, confidence, uncertainty, latest identity, and bounded
history;
it never deletes memory, writes a provider, changes ranking, grants authority,
spends quota, or changes the main work lane;
and rejects non-canonical or overflowing numeric/timestamp input.
Changed surfaces
architecture packet, and catalog registration.
Validation
uv run pytest -q: 5090 passed, 12 skipped, one existing Pydantic forward-reference warning;ruff checkand formatter check on changed Python files: passed;mypy --follow-imports=skipfor reducer and CLI: passed;loopx checkover all changed public surfaces: 0 errors, 0 warnings;loopx canary premerge --from-git-diff --tier standard: 17 selected,17 executed, 0 failures, 0 warnings, 0 manual holds;
The full repository mypy baseline contains unrelated pre-existing errors; the
new reducer and CLI pass the isolated check above. No benchmark jobs, provider
calls, uploads, credentials, raw trajectories, or private artifacts were used.
Commits
de971b2d2runtime/API reducer and CLIc6c4a5232focused tests and smokes33e960b94public protocol and catalog documentation