Skip to content

feat(arc): 赛马输赢回流研究记忆——前向结果表、裁判记账与沿接班链回流 - #79

Merged
Shadowell merged 9 commits into
mainfrom
codex/race-outcome-memory
Oct 22, 2026
Merged

Shadowell merged 9 commits into
mainfrom
codex/race-outcome-memory

Conversation

@Shadowell

Copy link
Copy Markdown
Owner

Description

为什么

用户的目标是所有模拟盘策略每天自动进化。BitPro 现在每个母体同时赛 3 个变体,HyperTrade 的研究端却记不住赛马的结局:谁赢了接班、谁明显落后被淘汰、谁终考没过,这些真实前向结果不会回到下一轮研究,模型可能反复提出已经输过的方向。本 PR 是「赛马输赢回流研究记忆」第一期;第二期「输家逐项消融」由另一个会话在 codex/loser-ablation 上并行做,排在本 PR 之后合入。

改了什么

  1. 前向结果表:新表 arc_forward_outcomes 与迁移 0050,每个 (目标, 母体, 挑战者) 一行。
  2. 记账规则(arc/forward_outcomes.py):
    • 只有 won/lost_futility/lost_exam 算输赢证据;超时、被同母体接班顶替、操作者取消、来源不明只做中性记录,不当负面证据。
    • 具体结论写入后不再改写,只有"来源不明"可以被升级成具体结论;并发写入撞唯一约束时回滚并对齐。
    • 按挑战者的 BitPro 编号找回当初的研究任务和改动(研究血缘),找不到记 no_lineage,不推断。
  3. 赛马裁判记账(paper/race_judge.py):赛道结束时写入结果,进程启动时补录状态文件里已结束的赛道;记账失败不影响卡片、状态文件与轮询。
  4. 位置被补走的漏判:BitPro 终考/超时淘汰后约 15 秒就把位置补给排队候选、删掉旧计划行,裁判 60 秒才扫一次,以前只能记"已结束"、不发淘汰卡片。配套 BitPro PR(https://github.com/Shadowell/BitPro/pull/1288)让 relay-control 对已不占位的挑战者附上最近一次淘汰归档,裁判据此照常发卡片、记输赢;字段缺失(旧 BitPro)时退回原行为,两边部署顺序不限。
  5. 沿接班链回流研究记忆(EvolutionService._memory):
    • 赢家接班后编号会变,所以研究时沿 won 记录往回 3 代,取已对接血缘的有效证据,最多 8 条。
    • 这些证据作为 type=forward_outcome 的记忆条目放在开发记忆之前,每条标明和当前策略的关系(自己赢下的那场/当前策略的变体/前任的比赛)。
    • 可在 evidence_refs 里用 outcome:… 引用;AVO 系统提示说明怎么用,以及单场比赛只是有噪声的观察。
  6. 研究血缘按事件定位:研究提速到每天最多 32 轮后,"扫最近 500 个任务"会让旧任务滑出窗口,改为先按写入编号的事件定位,再回退扫描。
  7. 可观察:GET /api/v1/arc/evolution 新增 forward_outcomes 统计;研究证据视图把前向结果单列为 forward_outcome_references。
  8. 文档:契约、架构、README 迁移数量、进度。

已合入最新 main(efce391):README.md 冲突采用 main 的英文版并把迁移数量改为 50;docs/progress.md 两边条目都保留;main 新增的面试手册里的迁移数量同步改为 50。

Type of Change

  • feat: New feature or capability
  • fix: Bug fix(位置被补走时裁判漏判淘汰、研究提速后血缘对不上)
  • docs: Documentation updates or additions
  • refactor: Code refactoring without functional changes
  • test: New or modified tests
  • ci: CI/CD workflows and automation

Risk & Safety Boundaries

  • Does this PR adhere to the live trading safety boundary (live_allowed=false)?
    不碰实盘与 Paper 下单:赛马裁判仍然只读(不调用 adopt/enable_auto/cancel),只多写本地账本;研究记忆只影响下一轮提案的上下文。

  • Are ASTGatekeeper and sandbox constraints maintained? 未改动。

  • Are secret keys and credentials excluded from version control? 是。

  • EvolutionService._memory 在研究主循环和模拟盘反馈两条路径上(GitNexus 影响分析:HIGH)。改动是加法,出错时记运行错误、照常研究,两条路径拿到的上下文结构相同。

  • 结果最多占模型可见 20 条记忆里的 8 条,开发记忆的可见条数相应减少。这是有意的取舍。

  • 同一挑战者被重新放行后的第二场比赛,不会覆盖账本里第一场的结论(已知限制)。

  • 没有线上实测;生产库读取被权限拦截。

Verification Checklist

  • Verified locally via ./scripts/check.sh:合入最新 main 后整套通过(前端 3 个文件 15 项测试与 lint/构建、ruff、mypy 318 个文件、后端 2277 项)。
  • Architectural docs under docs/architecture/ updated(迁移数 50;Paper & Evolution 行补记前向结果回流)。
  • docs/progress.md updated with implementation summary and verification evidence。

补充验证:

  • 新增 tests/test_forward_outcomes_ledger.py、tests/test_arc_forward_outcomes.py、tests/test_arc_forward_outcomes_postgres.py(PostgreSQL 真库:迁移升降级、唯一组合、JSON 路径查询);test_race_judge/test_arc_evolution/test_source_variant_avo/test_avo_evidence/test_arc_external_surface 补充用例。
  • 变异检验 12 处,去掉任一处都有用例失败:裁判记账 4 处(读取淘汰归档、重新放行复位、记账标记、不读候选重评数字);研究记忆 4 处(结果排在开发记忆之前、只取已对接血缘、沿链回溯、证据视图分列);血缘定位 4 处(事件定位、数字编号转字符串、取最新事件、提案事件取 attempt 路径)。
  • GitNexus:EvolutionService._memory 与 _lineage_index 影响分析为 HIGH(研究主循环 tick 与模拟盘反馈 check_paper_feedback),已确认两条路径的上下文都带 target_id 与 source_strategy_id,相关测试通过;race_judge.py 的索引映射不可靠(报告 critical,但所列流程并不调用裁判),已用文本检索核对真实调用方只有 worker 循环与运营端「立即运行」(FastAPI 线程池里执行)。
  • 配套 BitPro PR 已合入最新 main,接力相关 130 项测试通过。

由 DeepSeek V4.1 Flash 按 Claude 写的任务说明实现,Claude 负责规划、逐轮审查、变异检验和全量检查。

🤖 Generated with Claude Code

Shadowell and others added 8 commits October 21, 2026 11:30
每个已结束的 BitPro 赛道一行:母体、挑战者、位号、结论、结束时间、证据摘要与研究血缘
(任务、候选、参数与结构改动、作用范围)。同一 (目标, 母体, 挑战者) 唯一。迁移同时适用于
SQLite 与 PostgreSQL,含 SQLite 迁移测试与隔离 PostgreSQL 上的升降级测试。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 只记已结束赛道:won/lost_futility/lost_exam 是有效输赢证据,超时、被同母体顶替、
  操作者取消与来源不明都是中性记录,不当负面证据。
- 同一 (目标, 母体, 挑战者) 只留一行;具体结论写入后不再改写,只有「来源不明」可被更具体的
  结论升级;并发插入撞唯一约束时回滚并按已有行对齐。
- 血缘按 BitPro 策略 id 对上 ARC 尝试(最新任务优先,找全即停),一次扫描可批量对接;
  record(link=False) 供补录先记账、再统一对接;对不上的标 no_lineage,不推断。
- summary 用 SQL 聚合,不把整表读进内存。

由 DeepSeek V4.1 Flash 按 Claude 的任务说明实现,经 Claude 审查一轮后修改。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 赛道变为 completed/cancelled/ended 时写入 arc_forward_outcomes(completed 用计划的
  updated_at、cancelled 用归档的 cancelled_at 作为结束时间);记账失败只记日志、下次再试,
  不影响卡片、状态文件与轮询。
- 计划消失但 relay-control 带回淘汰归档时(BitPro 已把位置补给下一个候选、删了旧计划行),
  按取消处理:照常发终考未过/超时等卡片并记输赢,数字保留上次镜像的、不用候选重评的;
  不带归档(旧 BitPro)时仍记为已结束。
- 重新放行的挑战者复位记账标记(账本不改写第一场的具体结论,已知限制);进程首次巡检前
  补录状态文件里已结束的赛道,一次扫描批量对接研究血缘。
- 抽出 _mirror_cancellation 与 _announce,行为不变。

由 DeepSeek V4.1 Flash 按 Claude 的任务说明实现,经 Claude 审查与变异检验(4 处守卫均被用例抓住)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ForwardOutcomeLedger.evidence_for_lineage 取代 evidence_for_parent:赢家接班后编号会变,
  它赢下的那场和前任们的比赛都记在前任名下,所以沿 won 记录往回最多 3 代,取已对接血缘的
  有效证据(最多 8 条),每条标 relation(made_current/variant_of_current/made_ancestor/
  variant_of_ancestor)与 generations_back;防环。
- EvolutionService._memory 把这些结果作为 type=forward_outcome 的记忆条目放在开发记忆之前
  (模型只看前 20 条),manifest 记 forward_outcomes 计数;账本出错记运行错误、研究照常。
- AVO 系统提示说明各 relation 的含义、改动相对那场比赛的母体、输家方向无新证据不重复、
  赢的方向附近优先、单场是噪声观察不是因果结论;outcome:… 可在 evidence_refs 引用。
- 研究证据视图:memory_references 只列开发参照,前向结果单列 forward_outcome_references。

由 DeepSeek V4.1 Flash 按 Claude 的任务说明实现,经两轮审查与变异检验(4 处均被用例抓住)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
研究预算提到每天最多 32 轮后,「按最近更新的 500 个任务逐个加载投影」只覆盖约半个月,
而变体可能排队几天再赛 14~17 天,结束时当初的任务已滑出窗口,被永久记成 no_lineage。

- 新增 _locate_by_events:只在 candidate_proposed/bitpro_self_tested/candidate_validated
  三类事件里,用 JSON 路径取编号字段(不读含整份策略代码的事件正文),按事件 id 倒序流式
  读取(PostgreSQL 走服务端游标),最新事件优先,全部找到即停并关闭游标;数字编号统一
  按字符串比较。
- _lineage_index:先按事件定位、每个命中任务只加载一次投影;仍未找到的再回退扫描最近
  任务(覆盖事件内联存储的早期任务),已加载过的跳过。
- 测试:旧任务滑出扫描窗口仍能对上且只加载一次投影、重复使用的编号取最新任务、只能靠
  回退的任务、数字编号、载荷异常不报错;PostgreSQL 真库验证 JSON 路径查询与排除无关事件。

由 DeepSeek V4.1 Flash 按 Claude 的任务说明实现,经两轮审查与变异检验(4 处均被用例抓住)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- GET /api/v1/arc/evolution 在接口层附上 forward_outcomes(总数、按结论、按血缘、有效证据数、
  最近记账时间;读取失败只带 error、接口照常 200)。不改 EvolutionService.status():研究扫描
  每轮内部调用它多次,用不上这份统计。
- 合同文档:「消失的赛道」改为带淘汰归档时按淘汰处理;新增「赛马前向结果回流研究记忆
  (2026-10-21)」一节。架构文档、三个 README 的迁移数量 49→50;spec 与 progress 同步。

由 DeepSeek V4.1 Flash 按 Claude 的任务说明实现,经 Claude 审查。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mory

冲突处理:README.md 采用 main 的英文版,并把迁移数量改为 50;docs/progress.md 两边新增条目
都保留(本分支条目在前)。main 新增的面试手册里的迁移数量同步改为 50。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Shadowell
Shadowell marked this pull request as ready for review October 22, 2026 02:09
@Shadowell
Shadowell merged commit c3bfc17 into main Oct 22, 2026
2 checks passed
@Shadowell
Shadowell deleted the codex/race-outcome-memory branch October 22, 2026 02:16
@Shadowell
Shadowell restored the codex/race-outcome-memory branch October 22, 2026 02:16
@Shadowell
Shadowell deleted the codex/race-outcome-memory branch October 22, 2026 02: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