Skip to content

Implement semantic context compaction checkpoints - #35

Merged
Ev3rGan merged 2 commits into
mainfrom
codex/issue-33-context-compaction-v2
Sep 8, 2026
Merged

Implement semantic context compaction checkpoints#35
Ev3rGan merged 2 commits into
mainfrom
codex/issue-33-context-compaction-v2

Conversation

@Ev3rGan

@Ev3rGan Ev3rGan commented Sep 8, 2026

Copy link
Copy Markdown
Owner

关联

Relates to #33

本 PR 实现 Context Compaction v2。详细语义与边界见 Context Compaction v2 设计文档。本 PR 合并不关闭 Issue #33;Issue 必须保持开放,等待 post-merge 真实验收。

问题范围

当前确定性前缀摘要会丢失修改文件、验证结果、blocker、关键决策与 next step;重复压缩还可能把旧 checkpoint 当作普通消息,形成递归 summary,并让 Agent 在压缩后重复已经完成的探索。

核心机制

  • 引入独立、append-only 的 v2 compaction checkpoint,不删除 Session tree 原始历史,也不把 checkpoint 伪装成普通 conversation message。
  • 只压缩最新 checkpoint 尚未覆盖的旧消息,保留近期完整 turns,并维护累计 coverage、first-kept、lineage、depth 与 thrashing guard。
  • 在 ToolCall/ToolResult 完整边界选择安全切点;仅对已知可再生内置工具输出做类型感知、有界 shedding,保留未知 Extension tool output。
  • 生产摘要通过现有 provider-neutral ModelProvider、无 Tool 调用完成,采用固定八段语义 schema,并验证 usage、stream、关闭和失败路径。
  • 当前权威 instructions、resources 与 Permission Mode 每次在预算分配前重新投影;Extension authority 只能通过 CONTEXT_RESOURCE Hook 注入。
  • ProviderRequest、Context 与 Compaction Extension 均在 checkpoint 持久化前运行;最终 Hook-transformed plan 由唯一 ContextPipeline 重新投影和验证,summary、coverage、first-kept、metrics、ProviderRequest 与持久化 payload 保持一致。
  • v1 checkpoint 保持可读,新写入使用 v2;Session write/replay 与 Context 使用同一 compaction contract decoder。
  • COMPACTION_STARTEDCOMPACTION_SUCCEEDEDCOMPACTION_FAILED 保持 Host 可观察,并保证每个 started compaction 都有 succeeded/failed 终止事件。
  • SWE-bench CLI 增加 context character budget,并由唯一 SWEbenchRunConfig 同时驱动 Kernel、config.jsonmanifest.json

兼容性与原子性

现有 Context、Session、Extension、DeepSeek 与 SWE-bench 路径继续使用同一 Kernel seam。ContextPipeline.build 的 async 调用迁移已写入设计说明。摘要 Provider 失败、取消、空输出、超预算或 schema 非法时,不持久化部分 checkpoint,也不启动正常 Coding Turn Provider 请求,Session 保持可恢复。Coding 与 Compaction Provider 路径共用取消隔离,Provider-owned cancellation 会形成结构化 compaction_provider_failed

协作者审查处置

针对 review 5143237599,本次 follow-up commit 4bea3e17ca5616a6e1fa618a8a4f8de287db7587 完成以下修复:

  • 真实 JSON 转义后的摘要不再因 placeholder 低估而使可成立的压缩硬失败;最终请求按真实编码重新选择和验证保留窗口。
  • 已满足预算但降载较小的重复压缩记录 thrashing,而不再错误终止整个 Agent Run;派生 thrashing metrics 受到一致性校验。
  • 明确 pipeline 与最终 ProviderRequest 的 before/after metrics 口径。
  • 最终请求只保留一个 canonical checkpoint projection,拒绝第二 summary 与被覆盖 raw entries,同时允许合法 supplemental messages。
  • Coding 与 Compaction Provider 共用取消隔离;Provider-owned cancellation 被结构化处理。
  • Context/Provider Hook 后失败也会终止对应 compaction lifecycle,不留下只有 started 的事件序列。
  • Hook-transformed CompactionPlan 经唯一 ContextPipeline 重新投影,确保 coverage、first-kept、request、metrics 与持久化 payload 一致。
  • 文档补充 async ContextPipeline.build 迁移、ContextResource 责任边界、automatic/manual 边界、retained raw 行为与 resource compatibility,并精确归属 README 中的 ContextSettings、Tool schema 与 ContextResource。
  • 删除未使用的 retained-message 返回值。

经独立检查后保持不变的兼容决策:

  • [Feature]: 实现 Context Compaction v2 语义 checkpoint 与权威上下文重投影 #33 不新增 manual CLI;manual 仅保留为 wire-compatible trigger value。
  • retained recent entries 在最终请求中保持 raw,不重复注入 summary prompt。
  • config.json version 保持 1;该设置为 additive,当前不存在 strict field-set parser。
  • 空 resources 恢复仅用于兼容旧的 pre-resources Extension;非空 authority replacement 仍明确拒绝。
  • previous coverage filtering 不能绕过合法性约束,因为 checkpoint replay 与 append validation 是权威门禁。

验证证据

  • Targeted module gate:150 passed。
  • Full pytest:362 passed,2 skipped;skip 分别来自未安装的 SWE-bench optional contract test 与未开启的官方 dataset network test。
  • strict mypy:PASS,34 source files。
  • Ruff check:PASS。
  • Ruff format check:PASS,52 files formatted。
  • git diff --check:PASS。
  • 单次最终 global Standards review:PASS。
  • 单次最终 global Spec review 发现的三个 gap 组均已修复;repair-scoped Spec review 无直接问题,repair-scoped Standards review PASS。
  • release wheel 构建与 declared-dependency clean venv 安装:PASS。
  • wheel:coding_agent_kernel-0.1.0-py3-none-any.whl
  • wheel SHA-256:f8494bcd4da9ec5c9f55bc98dc3c9dcf9963b9cd790f805c0fda9c404cd5ddad
  • 安装后 CLI --help:PASS。
  • 安装后 demo context-compaction:PASS,事件顺序为 compaction_startedcompaction_succeeded,持久化 v2 checkpoint,最终请求为 649/650 characters。

当前完整 PR:20 paths,3,622 additions / 367 deletions;head 为 4bea3e17ca5616a6e1fa618a8a4f8de287db7587

Issue #33 关闭门禁

本 PR 合并后,仍需至少两个彼此不同、且不同于原诊断样例的额外 SWE-bench Verified 实例完成最终验收。每个实例必须:

  1. 使用真实带凭据的 DeepSeek Adapter 和公开 SWE-bench CLI;
  2. 明确产生至少一个合法 v2 context compaction checkpoint;
  3. 通过官方 Harness;
  4. 同时满足 FAIL_TO_PASS: PASSPASS_TO_PASS: PASS
  5. 将无 secret 的运行配置、checkpoint、prediction、patch 与 Harness report 证据发布到 Issue [Feature]: 实现 Context Compaction v2 语义 checkpoint 与权威上下文重投影 #33

在这些门禁全部完成前,Issue #33 保持 OPEN。


English appendix

This PR implements Context Compaction v2 through an independent append-only checkpoint, recent complete-turn retention, incremental coverage and lineage validation, a tool-free semantic summary through the existing provider-neutral ModelProvider, authoritative resource re-projection, and validate-before-persist atomicity.

The review follow-up at 4bea3e17ca5616a6e1fa618a8a4f8de287db7587 corrects JSON-escaped budget estimation, treats bounded low-reduction compaction as observable thrashing instead of a Run failure, aligns metrics, preserves one canonical checkpoint projection, shares Provider cancellation isolation, terminates every started lifecycle, and re-projects final Hook-transformed plans through the single ContextPipeline. Compatibility decisions for the manual wire value, retained raw entries, additive config versioning, empty-resource restoration, and authoritative checkpoint validation remain intentional.

The final frozen tree passed 150 targeted tests, 362 full-suite tests with 2 documented optional/network skips, strict mypy, Ruff, diff checks, review gates, wheel installation, and installed CLI acceptance. Merging this PR does not close Issue #33; closure still requires two additional credentialed DeepSeek SWE-bench Verified runs with actual v2 compaction and official Harness PASS results for both FAIL_TO_PASS and PASS_TO_PASS.

@better-er better-er left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PR #35 审阅:Implement semantic context compaction checkpoints

  • 仓库:Ev3rGan/coding-agent-kernel
  • PR:#35
  • head:43bf5c80b70aab4a91ac64e6f230d88cbc9ba500
  • base:origin/main = c26db32,单 commit,17 文件,+3048 / -249
  • 审阅环境:Windows,CPython 3.14.0,pytest 9.1.1,mypy 2.3.1,ruff 0.16.6
  • 结论:机制实现与设计文档一致,质量门禁可复现,测试覆盖扎实。发现 1 个会让合法压缩被硬失败的功能缺陷、1 个会终止整个 Run 的过严判定,以及若干口径与文档问题。

一、事实核对

1. 测试与质量门禁

门禁 PR 声明 本次复核
pytest 355 passed,2 skipped 355 passed,2 skipped
strict mypy PASS,34 source files PASS,34 source files
ruff check / format PASS PASS,52 files formatted
git diff --check PASS PASS
wheel 构建 PASS PASS,coding_agent_kernel-0.1.0-py3-none-any.whl

本机 pytest 原始输出是 5 failed, 350 passed, 2 skipped。这 5 个失败在 origin/main 上以完全相同的方式失败,与本 PR 无关,全部是 Windows 环境限制:

  • tests/test_swebench.py::test_docker_workspace_normalizes_trusted_mode_only_image_head_and_host_noise
  • tests/test_swebench.py::test_docker_workspace_rejects_tracked_symlink_that_escapes_workspace
  • tests/test_swebench.py::test_docker_workspace_rejects_symlinked_git_control_file_before_reset
  • tests/test_tool_loop.py::test_agent_run_executes_tool_batch_and_sends_ordered_results_to_next_turn
  • tests/test_tool_loop.py::test_bash_progress_is_observable_before_process_completion

前三个失败于 symlink_to 需要开发者模式或管理员权限,后两个失败于测试内 python/bash 子进程在该环境不可用。两处 skip 与 PR 声明一致:未安装 swebench optional 依赖、未开启官方 dataset network test。

PR 声明的 wheel SHA-256 未复核。wheel 默认包含构建时间戳,本机重建的哈希与 PR 不同属于正常现象,不作为问题。

2. CLI 与 demo 声明

逐条复现 PR 正文的验收声明,全部一致:

  • python -m coding_agent swebench run --context-max-characters 存在;传 0 时返回 2,输出 configuration/prediction_invalid 记录。
  • python -m coding_agent demo context-compaction --case success:exit 0,checkpoint_count=1bounded=truemessage_roles=["summary","user"]
  • python -m coding_agent demo context-compaction --case summary-error:exit 1,compaction_summary_failedprovider_calls=0checkpoint_count=0session_resumable=true
  • PR 正文使用 Relates to #33,并明确合并不关闭 Issue #33,与设计文档 §11.2 一致。

3. 设计条款核对

逐条对照 docs/design/context-compaction-v2.md,均有实现与聚焦测试:

  • v2 checkpoint 独立对象、lineage、first-kept、typed evidence、strategy、metrics:compaction.pytest_context_compaction_v2.py
  • 增量压缩只输入 previous checkpoint 与新增 span,不再产生 summary:summary:test_repeated_compaction_passes_previous_checkpoint_separately_and_projects_only_latest
  • 近期完整 turn 与 ToolCall/ToolResult 安全切点、类型感知 shedding、未知 Extension tool 输出不 shed:test_safe_cut_never_splits_tool_transaction_and_sheds_only_regenerable_outputtest_non_regenerable_extension_tool_output_is_not_shed_from_semantic_input
  • 权威资源每次重新投影、Skill 不进入 conversation summary:test_extension_skill_resource_is_reprojected_and_never_enters_compaction_span
  • summary Provider 无 Tool、stream 校验与关闭、失败原子性、失败早于 Coding Turn 请求:test_summary_provider_failure_is_observable_atomic_and_precedes_coding_turn 等。
  • v1 可读并升级为 v2、非法 v2 replay 拒绝:test_v1_checkpoint_replays_and_upgrades_to_v2_without_rewriting_historytest_replay_rejects_invalid_v2_checkpoint_contract
  • COMPACTION_STARTED/SUCCEEDED/FAILED 可观察。

4. 随机化探查

用 200 组会话、每组最多 12 步随机历史,混合普通 turn、工具调用 turn 与 assistant 追加消息,预算取 600/900/1200/2000/4000,每步构建并在产生 plan 时写入 Session,最后 close 后 Session.resume 重新加载并重建投影。未发现 checkpoint 持久化失败、resume 校验失败、投影出现多个 summary、或重建上下文超预算。核心不变量在这组随机输入下成立。

二、修改要求

1. 中等:保留窗口的预算估计与真实摘要编码不一致,会硬失败掉本来可成立的压缩

ContextPipeline._select_retained_turnsBranchSummaryMessage(text="x" * summary_budget) 估计候选请求大小,但 estimate_provider_request_characters 对 message 文本做 canonical JSON 编码。真实摘要必须包含 8 个 ## 标题,必然带换行,换行在 JSON 里变成两字节,引号同理。因此占位符估计系统性偏小,最多偏小到 summary_budget 量级。

实测:构造 400 字符、含 215 个换行的合法摘要,JSON 编码长度 615;会话为 1 个旧 turn 加 3 个近期 turn。

retained 0  placeholder_est 614   real_est 827
retained 1  placeholder_est 1024  real_est 1237

max_characters 取 1030 到 1230 时,build 选中 retained 1 后抛 context_budget_exceeded,而 retained 0 的真实估计只有 827,完全在预算内。也就是说,一个合法且 bounded 的压缩方案存在,实现却直接失败。这会在紧预算下把 Agent Run 变成 context_budget_exceeded,而不是退化成更小的保留窗口。

建议:占位符改用转义后的上界,或按 summary_budget 预留 JSON 转义开销;或者在最终 characters_after > max_characters 时回退到更小的保留窗口再试一次,而不是立即失败。

2. 中等:thrashing guard 会在压缩结果已经满足预算时终止整个 Run

build 先判定 characters_after > max_characters 通过,随后又用 reduction < max(32, characters_before // 20)compaction_thrashing。此时上下文已经被验证为 bounded,可以继续执行,却被判成 Run 失败。设计文档 §7 的原话是「报告 compaction thrashing 并停止自动重试」,并没有要求把已经 bounded 的上下文判为失败。判定还发生在一次真实 summary Provider 调用之后,失败无法回收这次调用。

建议:当 characters_after <= max_characters 时记录 thrashing_detected 并继续,仅在压缩后仍超预算且无新 span 可压时失败;或者在 PR 与设计中明确「压缩收益不足即失败」这一更强的语义。

3. 低:metrics.characters_beforecharacters_after 口径不同

characters_before 由 pipeline 在 Extension transform 之前计算,characters_afterAgentKernel._build_context 里被替换成最终请求的估计值,而最终请求已经包含 Extension 通过 context_resourceContextSupplement 注入的资源。两个字段不是同一口径,checkpoint 里记录的前后对比会失真。测试 test_persisted_characters_after_matches_final_supplemented_provider_request 只断言了 characters_after,掩盖了这一点。

建议:要么两个字段都在 Extension transform 之后计算,要么在 metrics 里区分 pipeline 估计与最终请求估计。

4. 低:可观察性字段目前永远是默认值

  • CompactionMetrics.trigger 只会是 automatic,仓库没有 manual compaction 入口。
  • CompactionMetrics.thrashing_detected 永远是 False,因为触发 thrashing 时直接抛错、不落 checkpoint,而 decode_v2_compaction_checkpoint 又强制该字段必须为 False
  • CompactionInput.retained_recent_entries 被两个 engine 完整忽略,生产摘要请求里没有任何近期保留窗口的信息。

设计 §10 要求 trigger 与 thrashing guard 可检查。建议要么补齐 manual 触发与落盘路径,要么在设计与 PR 说明里承认这些字段当前是占位。

5. 低:兼容性与文档未覆盖

  • ContextPipeline.build 从同步改为 async,是公开 API 的调用约定变更。PR 正文写「现有 Context、Session、Extension、DeepSeek 与 SWE-bench 路径继续使用同一 Kernel seam」,没有提到这一点,也没有迁移说明。
  • config.json 新增 context_max_characters,但 version 仍为 1。
  • CONTEXT.mddocs/specs/coding-agent-kernel.md 未补充 CONTEXT_RESOURCE Hook、ContextResource 与 v2 checkpoint 字段。

6. 低:校验里的两处不对称与静默处理

  • ExtensionRuntime.transform_contexttransform_provider_request 在 handler 把 resources 清空时静默恢复 canonical 值,但改动其中一个就报错。这种不对称容易掩盖 handler 的 bug,建议统一为拒绝。
  • _validate_v2_compaction_payload 对 previous coverage 做 entry_id in set(message_ids) 过滤,非法 id 被静默丢弃而非拒绝。前置 checkpoint 的自身校验通常能挡住,但这里应显式报错。

三、结论

机制方向正确,测试与门禁证据基本可复现,未发现数据损坏、checkpoint 原子性或 replay 校验被绕过的问题。合并前建议至少处理第 1、2 条:第 1 条会在紧预算下把可用的压缩变成 context_budget_exceeded,第 2 条会在结果已满足预算时终止 Run。其余为口径、文档与可观察性改进。

@Ev3rGan

Ev3rGan commented Sep 8, 2026

Copy link
Copy Markdown
Owner Author

感谢在 review 5143237599 中提供的可复现审阅。该报告已按不可信 bug report 独立复现和检查;对应修复已作为普通 follow-up commit 4bea3e17ca5616a6e1fa618a8a4f8de287db7587 推送。

逐项处置:

  1. 已修复真实 JSON 转义导致的 summary placeholder 低估;最终请求会按真实编码重新选择、投影并验证保留窗口。
  2. 已修复 bounded 但低 reduction 的压缩被误判为 Run 失败;现在记录 thrashing,并校验派生 metrics。
  3. 已统一 before/after metrics 口径,使 checkpoint 与最终 ProviderRequest 可比。
  4. 已补充 async ContextPipeline.build 迁移、ContextResource 责任边界、automatic/manual 边界、retained raw 行为和 resource compatibility;README 中 ContextSettings、Tool schema 与 ContextResource 的归属也已精确化。
  5. 已删除未使用的 retained-message 返回值。
  6. 后续 global Spec review 发现的 gap 已修复:最终请求只保留一个 canonical checkpoint projection;Coding/Compaction Provider 共用取消隔离;每个 started lifecycle 均有终止事件;最终 Hook-transformed plan 由唯一 ContextPipeline 重新投影,使 coverage、first-kept、request、metrics 与持久化 payload 一致。

有意保持不变:

  • [Feature]: 实现 Context Compaction v2 语义 checkpoint 与权威上下文重投影 #33 不新增 manual CLI;manual 保留为 wire-compatible value。
  • retained recent entries 在最终请求中保持 raw,不重复放入 summary prompt。
  • additive context_max_characters 不提升 config version,因为不存在 strict field-set parser。
  • 空 resources 恢复继续兼容 pre-resources Extensions;非空 authority replacement 仍拒绝。
  • previous coverage 不能成为绕过路径;checkpoint replay/append validation 仍是权威门禁。

同一最终树验证:150 targeted passed;362 full-suite passed、2 documented skips;strict mypy、Ruff lint/format、diff-check、global Standards 与 repair-scoped Standards/Spec 均通过;wheel SHA-256 f8494bcd4da9ec5c9f55bc98dc3c9dcf9963b9cd790f805c0fda9c404cd5ddad;隔离安装与 installed CLI compaction demo 通过,最终请求 649/650 characters。


English summary: commit 4bea3e17ca5616a6e1fa618a8a4f8de287db7587 addresses the reproduced escaped-budget, bounded-thrashing, metrics, canonical checkpoint projection, Provider cancellation, lifecycle termination, and final-plan re-projection issues. The manual wire value, retained raw entries, additive config version, empty-resource compatibility, and authoritative checkpoint validation remain intentional. The updated frozen tree passed the targeted/full test, typing, Ruff, diff, review, wheel-install, and installed CLI gates described above.

@better-er better-er left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

机制方向正确,测试与门禁可复现,未发现数据损坏与 checkpoint 原子性问题。合并前请优先处理评审第 1、2 条:紧预算下的收益判定,以及已满足预算时的 thrashing 失败语义。

@Ev3rGan
Ev3rGan merged commit 815b166 into main Sep 8, 2026
1 check passed
@Ev3rGan
Ev3rGan deleted the codex/issue-33-context-compaction-v2 branch September 8, 2026 17:09
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.

2 participants