Skip to content

ci(gates): 集成测试缓存落盘隔离门禁(开稳定层的测试禁写真实状态目录) - #78

Merged
GGGBB merged 1 commit into
mainfrom
agent/69-cache-isolation-gate
Oct 15, 2026
Merged

GGGBB merged 1 commit into
mainfrom
agent/69-cache-isolation-gate

Conversation

@GGGBB

@GGGBB GGGBB commented Oct 15, 2026

Copy link
Copy Markdown
Owner

现场:真实缓存被测试键污染

~/.codex-layer/tools-cache.json 里混进了一批 degrade-ok-*、over-limit-stream-*、
truncated-* 之类的键——全是 cargo test 写进去的。成因:tools 回填缓存落盘之后,
任何以 prompt_prefix = true 启动中继子进程的集成测试都会往真实状态目录写键,
而当时只有两个测试文件注入了隔离路径,后来往第三个文件加用例时重犯了。

危害不是脏文件本身,而是它搅浑了真机判据:「重启后第一个压缩轮是否命中预热」要看
toolsWarmed 与缓存内容,真键和测试键混在一个文件里,这条判据当场失效——
我是在做 v0.3.3 的真机验证时撞上的。

为什么做成门禁而不是写进注释

注入这件事挡不住新增用例:每加一条开稳定层的测试都可能重犯,而犯了的信号只出现在
开发者本机
(真实目录被污染),CI 完全看不见。这类「本地才可见的副作用」正是
本仓库反复吃亏的形态。

判据

纯函数 audit_source,逐文件:出现 prompt_prefix = true 即必须同时出现
CODEX_LAYER_TOOLS_CACHE_PATH。刻意只认这两个字面量、不做语法解析——两者都是
spawn 处必然手写的字符串,漏任一即说明隔离没做。

  • --self-test 四例正反对照(启用+已注入放行、启用+未注入判红、未启用放行、空文件放行)。
  • fail-loud:扫不到 tests/*.rs、或启用稳定层的用例数为 0,一律非零退出——
    不把「没文件可查」当成「全部合规」。
  • 挂进 gates job;必需检查名一字未动。

同时补的修复

tests/native_compaction_wiring.rs 补注入 CODEX_LAYER_HOME 和
CODEX_LAYER_TOOLS_CACHE_PATH。缓存变量单独注入而不是只改 HOME:它是独立的
覆盖变量,只改 HOME 时一旦有人改优先级链,隔离就静默失效——两道都钉住。

有效性反向验过

撤掉注入 → 门禁立刻判红并点名到文件与缺失的变量名;恢复 → 判绿。不是写完就绿。
该文件 9 条测试仍全绿,隔离门禁对真实仓库 4 个启用稳定层的文件全部放行。

稳定层开启后 tools 回填缓存会落盘,任何以 prompt_prefix = true 启动中继子进程的
集成测试都会往真实状态目录写测试键。本机真的混进了一批 degrade-ok-*、
over-limit-stream-* 键,与真键同处一个文件,把「重启后第一个压缩轮是否命中预热」
这个真机判据搅浑。

- tests/native_compaction_wiring.rs:补注入 CODEX_LAYER_HOME 与
  CODEX_LAYER_TOOLS_CACHE_PATH(此前只有另两个文件注入了,后来往这个文件加用例时
  重犯了)。缓存变量单独注入而不是只改 HOME:它是独立覆盖变量,只改 HOME 时
  一旦优先级链改动隔离就静默失效。
- 新增 scripts/ci/tools_cache_isolation_gate.py:判据是纯函数 audit_source,
  源文件出现 prompt_prefix = true 即必须同时出现 CODEX_LAYER_TOOLS_CACHE_PATH。
  带 --self-test 四例正反对照;扫不到测试文件或启用稳定层的用例数为 0 都显式失败,
  不把「没文件可查」当成「全部合规」。
- 挂进 gates job 并写进贡献指南。这条必须进 CI:污染只出现在开发者本机,
  CI 原本完全看不见。

有效性反向验过:把注入撤掉,门禁立刻判红并点名到文件与缺失的变量名。

@GGGBB GGGBB left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

合并前对账(维护者复核,head b50b16e)

CI 四检查全绿,gates job 里三条判据自测都在 CI 内跑通(提交作者 / 新增文件格式 / 隔离)。

判据我看过的三点

  1. 判据面刻意窄:只认 prompt_prefix = true 与 CODEX_LAYER_TOOLS_CACHE_PATH
    两个字面量、不做语法解析。这不是偷懒——两者都是 spawn 处必然手写的字符串,
    做 AST 解析反而会因写法多样而漏判。窄判据配 fail-loud(扫不到测试文件、
    启用稳定层的用例数为 0 都非零退出)才是这里要的组合。
  2. 两个变量都注入而不是只改 CODEX_LAYER_HOME:缓存路径是独立的覆盖变量,
    只改 HOME 时一旦有人调整优先级链,隔离就静默失效——又是一条「本地才可见的失效」。
    这个取舍我认可,注释里也写明了。
  3. 有效性反向验过:撤掉注入立刻判红并点名到文件与缺失变量名,恢复即判绿。
    我本地独立复跑过同样的反向验证,一致。

我这边补的一处

两个 agent 线一度并行做同一件事(我先前开的 worktrees/isogate 与这条线)。
已按「归属只在一处定档」把重复线删除,保留这条带门禁的版本;两处注入内容我逐字比对过,
最终形态是 HOME + 缓存变量双注入,比任一条单独的都严格。

合并后仍要做的一件事(不在本 PR 内,记档防口说无凭)

本机 ~/.codex-layer/tools-cache.json 里历史混进的 e2e 键不会自动消失:常驻进程
预热时已把它们读进内存,之后刷盘写回的还是含脏键的全量内容。它们不影响正确性
(键名带 pid,压缩轮用真实线程 id 查找,永远命中不到),真实风险是键数逼近 32 时
触发整体清空、把真键一起清掉。处置窗口是下一次重启常驻时删掉该文件,
让新进程从零重建;现在热改文件会被内存全量刷回覆盖,做了等于没做。

流程偏差声明

代码与门禁由维护者会话编写,单账号下无法自审 APPROVE,以本条评论留对账依据后执行
rebase 合并。本条评论即合并前的批准口径留痕(供 self-approval aftercheck 交叉)。

@GGGBB
GGGBB merged commit 2a8d79d into main Oct 15, 2026
8 checks passed
@GGGBB
GGGBB deleted the agent/69-cache-isolation-gate branch October 15, 2026 16:40
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