Skip to content

fix(reward-memory): recover pending TS projections without repeating work - #5232

Merged
huangruiteng merged 1 commit into
mainfrom
codex/reward-memory-projection-recovery-20260928
Sep 28, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/reward-memory-projection-recovery-20260928

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

Summary / 摘要

Fix caller-retained Reward Memory results that become permanently incomplete when the provider/application has already finished but the existing TS result projection fails.

修复 Reward Memory 调用方保留结果的恢复缺口:provider/应用已经执行,TS 结果投影暂时失败后,相同请求只能永久返回 incomplete,待确认产物也无法恢复。

  • Retain a private snapshot of the original SDK observation and pending output.
  • Exact-request replay retries only reward_memory.decision.project; assessment first recovers delivery, or returns the already-attempted semantic projection without another callback—even for invalid attribution.
  • A later explicit assessment can still correct incomplete SDK evidence without recalling.
  • TS remains the sole admission/completion owner; Python only retains existing private provider/applier values and transports their original receipts. No new policy owner, persistent store, enablement, retry loop or action authority.

私有快照保留原 SDK 观察和产物;精确请求重放只重试原 TS 投影。assessment 先恢复交付,已尝试的语义判断不因投影恢复而重复调用,即使归因无效;后续显式判断仍可纠正不完整证据。TS 继续持有准入/完成语义,Python 仅适配和保留既有私有值,不新增持久化、开关、循环或授权。

Validation / 验证

  • Original source base ee9dad81b14c6d15d32b95851b5d38fcc485e732: existing 42 decision tests pass; the first four new projection-recovery cases fail before the fix.
  • An additional invalid-assessment recovery case reproduced an unintended second callback before the refinement.
  • Relevant Python suites: 137 passed, including 55 decision tests.
  • Existing native TS decision tests: 10 passed, no skips.
  • Capability configuration tests: 30 passed; existing personal-workspace contract smoke passed.
  • Scoped Ruff, changed-file compile, repository mypy (19 source files) and TS typecheck passed.
  • Candidate public/private boundary scan: zero errors; unrelated live-registry status warnings are not adoption evidence.
  • Extra exploratory mypy --follow-imports=skip decision.py reports two unchanged no-any-return errors, independently reproduced at the immutable source base; the official repository mypy gate passes.
  • Risk-based premerge passed: 5 direct checks and 17 executed canary/smoke checks, zero failures or advisory failures. The initial missing-TypeScript dependency failure was resolved with the existing lockfile's npm ci --ignore-scripts; no manifest/lockfile change or budget increase.

原基线的 42 项决策测试通过,新增前四个恢复场景先红后绿;额外负例确认并修复了无效归因恢复时的重复 callback。137 项相关 Python 测试、10 项原 TS 测试、30 项配置测试及原前端契约检查通过;Ruff、编译、正式 mypy 和 TS 类型检查通过。额外跳过导入的严格 mypy 检查两处原有错误已在独立基线复现,不伪称通过。

User paths, boundaries and rollback / 产品入口、边界与回滚

The changed entry points are run_reward_memory_decision(..., previous_result=result) and assess_reward_memory_decision(result, ...). Reuse the caller's complete private result and stable application/artifact identity. Only public_packet is displayable.

The existing Dashboard configuration fields (config_path, enabled_agents) and their configuration owner are unchanged, so no new control or packaged frontend asset is needed. Existing configuration and bilingual frontend contracts were checked. Lark remains status-only; universal frontend/Lark consumption, cross-process restore and memory utility are not delivered here. All provider/model test inputs are synthetic; this is not financial-effect evidence.

本次改变两个既有调用入口的恢复行为;必须保留完整私有结果和稳定应用/产物身份,只展示 public_packet。Dashboard 原配置字段及 owner 未变,无新增控件或前端资产;原配置和双语前端契约已检查。Lark 保持状态投影,不宣称通用端到端回传、跨进程恢复或实际记忆收益。本地验收使用合成 provider/callback,不代表金融效果。

Rollback to the original optional automatic-recall hook, or disable through the existing configuration owner. Ordinary research remains fail-open. No query/lesson/model rationale or pending output is sent to TS, generic UI or Lark.

Scope / 范围

One bounded implementation commit: existing private adapter, focused regression tests and bilingual contract documentation. Reused the existing TS projection and test fixtures rather than adding a second decision service or a new smoke family. Local state, provider data, credentials and generated logs are excluded. Maintainer review/merge and qualified installation remain separate; no unmerged installation is performed.

…work

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

@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)

审阅 head:2b7b0cbeeb6f6dc667064b4925ef2e049f0d8cb3。未发现阻塞本次有界修复的问题;不把源码验证等同于安装采用、跨进程恢复或记忆实际效果。

动机

已有 query-ready API 在 provider/应用完成后遇到 TS 投影异常,会保留部分回执,却丢失待确认产物;相同请求只能一直 incomplete,重新判断还可能增加模型调用。该缺口已在不可变基线复现,不是为了增加一个新的记忆服务。本 PR 是有价值的独立增量:恢复同进程内已经完成的工作,不宣称完成更大的记忆闭环。

改动思路

复用原 SDK、配置与 TS owner,在调用方完整私有 result 中暂存原始 SDK 观察和产物。重试先过既有请求摘要,再仅调用原 TS 投影,由它重新核验应用、产物和经验归因;没有把经验正文或判断规则复制到 Python。doing nothing 虽然仍可继续独立研究,但已付费的结果会被遗失;只有公开回执又无法重建产物。当前私有快照比新增缓存、恢复协议或第二决策服务更小。

具体改动

关键代码讲解

  • 私有 pending 快照 保存原 SDK 状态、累计遥测、两类回执和产物;可选字段默认 None,旧调用方式不变,它不成为新的持久权威。
  • 共享恢复入口 只经过既有 TS RPC。成功后按 TS 的 preserve_base_output 选择产物并清除 pending;故障返回同一基线结果,不调用 provider/applier。
  • 精确重放 保留关闭时的早退和原请求 fence;配置、问题、范围、产物变化不能挪用旧结果。首次 hook 完成后先保留私有快照,再请求投影。
  • 语义判断 区分“恢复已尝试判断的投影”和“第一次判断”。无效归因恢复也不能顺便再调用模型;后续显式 assessment 仍可纠正不完整 SDK 证据,无需重新召回。

全 diff 为生产 54+/12-、测试 213+、双语文档 24+。13 个新回归覆盖交付/判断恢复、持续异常、精确身份拒绝、错误归因和产物快照;复用原测试 fixture,没有新 smoke 家族或临时 probe 入库。文档说明所有私有字段不得进入通用前端/飞书,并保留 EOF/重启不能恢复的边界。

对主干的风险

最强反例是“投影恢复偷偷再次执行模型”或“无效回执被升级”。额外 invalid-assessment 负例曾直接报 second model judgment,已修复;两 corpus 的累计调用/过滤计数、原交付链和非法归因拒绝均验证。关闭路径仍 None、零 TS/provider 调用;配置未变化,原 Dashboard 配置与双语契约已检查,无新增前端资产。Lark 保持状态入口,不声称所有用户入口已打通。

同一 fixture 经真实 SDK→TS 入口在 base/head 对照,15 个正常/拒绝场景的完整公开 packet、产物和调用计数摘要完全一致:b3722cf8adac81a6f41860a4f6b90f8dbb08913232f36b8b586f7d271d9e328c。唯一刻意变化是恢复场景由 incomplete 到 context_delivered,provider/交付 callback 均保持一次。旧基线 42 项通过,新恢复场景先红后绿;exact head 的组合 Python 167 项、原 TS 10 项及前端契约通过。5 项直接检查和 17 项预合并检查全部通过,没有放宽预算。

语义与 CI 对齐

复用既有状态和单一 TS owner,不新增公共词表或 actor/授权语义。正式 mypy(19 文件)、TS typecheck、Ruff、编译和语义/公开边界检查通过。额外 follow-imports=skip 类型探针两处 no-any-return 在不可变 base/head 的原 RPC/callback 返回位置均复现,单独披露,不伪称通过。首次预合并缺 TypeScript 依赖已按锁文件安装后消除,未修改依赖清单或门槛。按本 Goal 的 wait_for_ci=false,未查询、轮询或等待 GitHub CI。

我的整体评价

APPROVE 这一有界修复。长程连续性改善在于已完成结果可恢复且不重复工作;用户体验改善在于使用原入口、原配置获得诚实回执,而非额外手工同步。简化已体现在共用恢复 helper 和原 TS owner,未为了 TS 偏好扩大语言重写。真实 provider/model 效果、跨进程恢复、通用前端/Lark 回传及安装采用仍需独立证据;它们不被本次合成验收冒充完成。需要 Core maintainer 合并后再走受控升级,本自评审不提供合并权限。

English verdict: APPROVE - 2b7b0cb; bounded private SDK-result recovery reuses the existing TS owner without repeated provider/judgment work. Matched base/head observations, 167 Python tests, 10 TS tests and exact-head premerge pass; persistence, utility and installation remain out of scope.

@huangruiteng
huangruiteng merged commit 1bcdba6 into main Sep 28, 2026
33 checks passed
@huangruiteng
huangruiteng deleted the codex/reward-memory-projection-recovery-20260928 branch September 28, 2026 03:17
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