Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

perf(core): reduce source cache memory peaks - #78

Merged
makoMakoGo merged 5 commits into
personal/local-clientsfrom
fix/source-cache-memory-revisions
Jun 24, 2026
Merged

perf(core): reduce source cache memory peaks#78
makoMakoGo merged 5 commits into
personal/local-clientsfrom
fix/source-cache-memory-revisions

Conversation

@makoMakoGo

@makoMakoGo makoMakoGo commented Jun 24, 2026

Copy link
Copy Markdown
Owner

What changed

  • Split source-message shard invalidation into a cache format version plus per-source parser revisions.
  • Added parser revision checks to source cache hits, including mixed-source adapter units through SourceUnitMeta.
  • Replaced the generic cold-cache messages.clone() path with a borrowed CacheWritePlan that writes the shard before moving the same message vector into the sink.
  • Added Copilot large-OTEL regression coverage: a parser-level 50 MB fixture test and a Linux end-to-end cold/warm source-cache RSS test.

This keeps old shards without the new metadata stale with no compatibility migration. Antigravity parser, discovery, model decoding, and dedup semantics are unchanged; it only participates in the generic cache-write plumbing.

Closes #76.

Validation

  • cargo fmt --all -- --check
  • cargo test -p tokscale-core sessions::copilot
  • cargo test -p tokscale-core message_cache
  • cargo test -p tokscale-core adapters::antigravity
  • cargo test -p tokscale-core adapters::codex
  • cargo test -p tokscale-core adapters::opencode
  • cargo test -p tokscale-cli --test copilot_memory -- --nocapture
  • cargo test --workspace
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo build --release -p tokscale-cli

Memory checks

Generated Copilot OTEL fixture: 52,429,642 bytes.

  • cold source-cache large Copilot run: 17,676 KB max RSS
  • warm source-cache large Copilot run: 17,680 KB max RSS
  • cold/warm large Copilot outputs matched

Single-client real-data smoke checks with release binary:

  • Copilot: 10,720 KB max RSS
  • Antigravity: 16,860 KB max RSS
  • Kiro: 37,716 KB max RSS

Summary by cubic

Reduce source-cache memory peaks by writing shards from borrowed message buffers and making cache hits parser-aware by per-source parser identity (id + revision). Cache reads now verify path, parser, and fingerprint; Codex append cache reads are restored; stale or mismatched shards are skipped. Closes #76.

  • Refactors

    • Split shard validity into cache format version + per-source parser_version (id + revision); stored in shard headers and keys.
    • Added parser_version to SourceUnit/CachedSourceEntry; adapters set explicit versions, with sensible client defaults.
    • Introduced cache I/O plans: CacheReadPlan for hits and CacheWritePlan/CacheWrite for writes; write_messages writes borrowed buffers, and take_messages[_with_fallback] require a read plan and revalidate before returning.
    • Cache APIs now key by parser: get_meta(path, parser_version) and remove(path, parser_version); Codex/file/policy adapters updated to use plans and borrowed writes while preserving incremental metadata.
    • Added a large Copilot fixture + Linux RSS test, plus tests for per-parser shard separation and stale read-plan rejection.
  • Bug Fixes

    • Restored Codex append-mode cache reads via CacheReadPlan, ensuring tails append correctly on cache hits.
    • Tests now restore Codex cache env safely to avoid cross-test env leaks.

Written for commit 114ba5a. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • 推出消息缓存的版本化校验与分片写入规划,缓存读取/写入按解析器版本进行隔离,提升跨解析场景的一致性。
  • Bug Fixes

    • 调整缓存命中与失效/移除判定逻辑:仅在需要且缺失写入时移除对应缓存条目,减少误失效与结果不一致。
  • Tests

    • 新增 Linux 专用回归:冷/热启动 stdout 完全一致,并校验峰值内存与源缓存分片复用。
    • 扩展大型 Copilot JSONL 用例,验证大/小文件解析一致性;补齐相关缓存测试的环境隔离与稳定性处理。

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

概览

本 PR 将源消息缓存从即时写入的 cache_entry 重构为延迟写入的 cache_write,并引入 parser_versionCACHE_FORMAT_VERSION 分离缓存格式版本和解析器版本;同时新增 Copilot 大文件解析回归与 Linux 冷热缓存内存测试。

变更说明

缓存版本化与写入重构

Layer / File(s) Summary
缓存版本模型与 SourceUnit 传播
crates/tokscale-core/src/message_cache.rs, crates/tokscale-core/src/adapters/mod.rs, crates/tokscale-core/src/adapters/discover.rs, crates/tokscale-core/src/adapters/file.rs
新增 ParserIdParserRevisionParserVersion、带版本字段的缓存键/条目类型,以及 SourceUnit/ParsedUnitparser_versioncache_write 字段;各类适配器在 discover 路径上写入对应版本信息。
缓存计划与分片校验
crates/tokscale-core/src/message_cache.rs, crates/tokscale-core/src/lib.rs
get_metawrite_messagestake_messages、分片头读写和相关测试改为校验 parser_versionformat_version,并使用 read/write plan 贯穿读取与落盘。
通用缓存管道与 fold 写入迁移
crates/tokscale-core/src/adapters/cache.rs, crates/tokscale-core/src/adapters/claude.rs, crates/tokscale-core/src/adapters/antigravity.rs, crates/tokscale-core/src/adapters/opencode.rs, crates/tokscale-core/src/adapters/goose.rs, crates/tokscale-core/src/adapters/hermes.rs, crates/tokscale-core/src/adapters/kilo.rs, crates/tokscale-core/src/adapters/kiro.rs, crates/tokscale-core/src/adapters/trae.rs, crates/tokscale-core/src/adapters/junie.rs, crates/tokscale-core/src/adapters/pi.rs
缓存命中与解析流程改用 unit.parser_versionCacheWrite;多个适配器的 ParsedUnitfold 路径同步切换为统一写缓存和按版本失效。
Codex 版本化缓存写入
crates/tokscale-core/src/adapters/codex.rs
Codex 增量解析、缓存命中、追加源构造和写入流程全部迁移到 parser_version + CacheWrite 组合,并更新相关测试。
Copilot 大文件与内存回归
crates/tokscale-core/src/sessions/copilot.rs, crates/tokscale-cli/tests/copilot_memory.rs
新增大体积 Copilot JSONL fixture 生成与解析一致性测试,并增加 Linux 端到端内存回归,校验 cold/warm 运行的输出、shard 复用与 RSS 峰值。

时序图

sequenceDiagram
  participant Adapter as 适配器
  participant CachePipeline as cache.rs
  participant SourceMessageCache as SourceMessageCache
  participant FoldUnits as fold_units
  participant WriteCache as write_cache

  Adapter->>CachePipeline: SourceUnit (含 parser_version)
  CachePipeline->>SourceMessageCache: get_meta(path, parser_version)
  alt 命中
    SourceMessageCache-->>CachePipeline: CachedSourceMeta
    CachePipeline-->>Adapter: ParsedUnit { cache_write: None }
  else 未命中
    CachePipeline->>CachePipeline: 解析 messages
    CachePipeline-->>Adapter: ParsedUnit { cache_write: Some(...) }
  end
  Adapter->>FoldUnits: ParsedUnit
  FoldUnits->>FoldUnits: resolve_messages
  FoldUnits->>WriteCache: write_cache(cache_write, ctx, messages)
  WriteCache->>SourceMessageCache: write_messages / insert
Loading

预估代码审查工作量

🎯 4 (Complex) | ⏱️ ~60 minutes

相关 PR

小诗

🐇 缓存分家不打架,格式版本与解析版本各自挂,
旧 shard 见了新规矩,乖乖重跑不喧哗。
Copilot 扛起大 JSONL,冷热都能稳稳答,
兔子拍手蹦一蹦:内存小了,夜色也更亮啦!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了降低源缓存内存峰值这一主变更。
Linked Issues check ✅ Passed 新增 Copilot 大文件回归测试、按 parser_version 拆分缓存版本并消除冷缓存克隆,符合 [#76] 的核心要求。
Out of Scope Changes check ✅ Passed 改动集中在源缓存版本、适配器解析版本和 Copilot 回归测试,没有明显超出 [#76] 的无关代码变更。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/source-cache-memory-revisions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Jun 24, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 10.85%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 3 improved benchmarks
✅ 15 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
normalize_model_for_grouping[claude_anthropic_date] 3.2 µs 2.8 µs +11.28%
normalize_model_for_grouping[kimi_free_tier] 3.2 µs 2.9 µs +11.14%
normalize_model_for_grouping[longcat_quantized] 3.2 µs 2.9 µs +10.13%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/source-cache-memory-revisions (114ba5a) with personal/local-clients (812c926)

Open in CodSpeed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/tokscale-core/src/adapters/junie.rs (1)

155-191: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Drop 守卫恢复 TOKSCALE_CONFIG_DIR

这里直到 Line 191 才恢复环境变量;前面的 unwrap() 或断言一旦失败,进程级 env 就会残留在临时目录,后续测试会被污染。更稳妥的做法是像 crates/tokscale-core/src/lib.rs 里的 HomeEnvGuard 一样用 RAII 包住这次覆盖。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/adapters/junie.rs` around lines 155 - 191, The test
in JUNIE adapter setup restores TOKSCALE_CONFIG_DIR manually at the end, which
can leak the temporary env value if any unwrap or assertion fails. Update the
adapter_cache_hit_matches_fresh_parse test to use an RAII guard, similar to
HomeEnvGuard in lib.rs, around the temporary TOKSCALE_CONFIG_DIR override so the
original value is always restored automatically.
🧹 Nitpick comments (2)
crates/tokscale-core/src/adapters/discover.rs (1)

124-130: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

不要在 PrimaryWithSiblings 分支硬编码 parser revision。

Line 129 绕过了 SourceUnitMeta::parser_revision() 的集中映射;以后 bump None 的 revision 时,这个分支会继续命中旧缓存。改成同一来源可以避免版本漂移。

建议修改
         FingerprintPolicy::PrimaryWithSiblings { sibling_names } => SourceUnit {
             client,
             path,
             fingerprint_policy: FingerprintPolicy::PrimaryWithSiblings { sibling_names },
             meta: crate::adapters::SourceUnitMeta::None,
-            parser_revision: 1,
+            parser_revision: crate::adapters::SourceUnitMeta::None.parser_revision(),
         },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/adapters/discover.rs` around lines 124 - 130, The
PrimaryWithSiblings branch is hardcoding parser_revision instead of using the
centralized mapping, which can cause revision drift and stale cache hits. Update
the SourceUnit construction in discover.rs so the parser revision comes from
SourceUnitMeta::parser_revision() (or the same shared source used by the other
branches) rather than a literal value, keeping the revision logic consistent
with the rest of SourceUnit creation.
crates/tokscale-core/src/message_cache.rs (1)

1476-1502: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

补上旧分片头缺少 parser_revision 的回归用例。

这里覆盖了 format_version 不匹配,但 PR 目标还要求旧 shard(只有旧 schema_version、没有 parser_revision)必须 stale。建议用一个本地 legacy header struct 按旧字段顺序序列化,断言 get_meta(..., 1) 仍返回 None,避免旧 schema_version == CACHE_FORMAT_VERSION 时被误收。

建议补充测试
+    #[test]
+    #[serial_test::serial]
+    fn test_get_meta_ignores_legacy_shard_without_parser_revision() {
+        #[derive(Serialize)]
+        struct LegacyCachedShardHeader {
+            schema_version: u32,
+            path: CachedPath,
+            fingerprint: SourceFingerprint,
+            fallback_timestamp_indices: Vec<usize>,
+            codex_incremental: Option<CodexIncrementalCache>,
+            message_count: usize,
+        }
+
+        let temp_home = TempDir::new().unwrap();
+        let prev_env = sandbox_cache_env(temp_home.path());
+
+        let source = write_temp_file(b"source\n");
+        let shard = shard_path(source.path()).unwrap();
+        ensure_cache_dir(shard.parent().unwrap()).unwrap();
+        let header = LegacyCachedShardHeader {
+            schema_version: CACHE_FORMAT_VERSION,
+            path: CachedPath::from_path(source.path()),
+            fingerprint: SourceFingerprint::from_path(source.path()).unwrap(),
+            fallback_timestamp_indices: Vec::new(),
+            codex_incremental: None,
+            message_count: 0,
+        };
+        let header_bytes = bincode::options().serialize(&header).unwrap();
+        let mut file = File::create(&shard).unwrap();
+        file.write_all(&(header_bytes.len() as u64).to_le_bytes()).unwrap();
+        file.write_all(&header_bytes).unwrap();
+        file.flush().unwrap();
+
+        let loaded = SourceMessageCache::load();
+        assert!(loaded.get_meta(source.path(), 1).is_none());
+
+        restore_cache_env(prev_env);
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/message_cache.rs` around lines 1476 - 1502, Add a
regression test for legacy shard headers that are missing parser_revision, not
just mismatched format_version. Update the existing test around
test_get_meta_ignores_stale_shard_format_version or add a sibling case that
serializes an old header layout with only
schema_version/CACHE_FORMAT_VERSION-equivalent fields, then verify
SourceMessageCache::load().get_meta(source.path(), 1) returns None. Use a local
legacy header struct with the old field order so the test covers shards that
match the current format version but are still stale because parser_revision is
absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/tokscale-cli/tests/copilot_memory.rs`:
- Around line 69-77: In the copilot_memory test flow, remove the hardcoded
no-write-cache behavior from the CLI args so the warm run can actually persist
and hit source-cache; update the test setup around the repeated CLI invocation
in copilot_memory.rs to allow cache writes for the warm path while keeping the
cold-path setup intact. Use the existing copilot_memory test helpers and the CLI
argument builder in the affected test cases so the cold/warm RSS assertions
reflect a real cache hit.

In `@crates/tokscale-core/src/lib.rs`:
- Line 3502: The get_meta test assertions are hardcoding parser revision 1,
which can hide cache persistence regressions when revisions change. Update the
affected tests around get_meta to derive the revision from the source/unit under
test or use a shared test helper/constant, and replace the literal 1 in the
is_none() checks so the revision matches the adapter/parser being exercised
consistently.

---

Outside diff comments:
In `@crates/tokscale-core/src/adapters/junie.rs`:
- Around line 155-191: The test in JUNIE adapter setup restores
TOKSCALE_CONFIG_DIR manually at the end, which can leak the temporary env value
if any unwrap or assertion fails. Update the
adapter_cache_hit_matches_fresh_parse test to use an RAII guard, similar to
HomeEnvGuard in lib.rs, around the temporary TOKSCALE_CONFIG_DIR override so the
original value is always restored automatically.

---

Nitpick comments:
In `@crates/tokscale-core/src/adapters/discover.rs`:
- Around line 124-130: The PrimaryWithSiblings branch is hardcoding
parser_revision instead of using the centralized mapping, which can cause
revision drift and stale cache hits. Update the SourceUnit construction in
discover.rs so the parser revision comes from SourceUnitMeta::parser_revision()
(or the same shared source used by the other branches) rather than a literal
value, keeping the revision logic consistent with the rest of SourceUnit
creation.

In `@crates/tokscale-core/src/message_cache.rs`:
- Around line 1476-1502: Add a regression test for legacy shard headers that are
missing parser_revision, not just mismatched format_version. Update the existing
test around test_get_meta_ignores_stale_shard_format_version or add a sibling
case that serializes an old header layout with only
schema_version/CACHE_FORMAT_VERSION-equivalent fields, then verify
SourceMessageCache::load().get_meta(source.path(), 1) returns None. Use a local
legacy header struct with the old field order so the test covers shards that
match the current format version but are still stale because parser_revision is
absent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1fa05b1f-d62e-442e-96ed-64a783c6dba1

📥 Commits

Reviewing files that changed from the base of the PR and between 812c926 and d43a5c4.

📒 Files selected for processing (19)
  • crates/tokscale-cli/tests/copilot_memory.rs
  • crates/tokscale-core/src/adapters/antigravity.rs
  • crates/tokscale-core/src/adapters/cache.rs
  • crates/tokscale-core/src/adapters/claude.rs
  • crates/tokscale-core/src/adapters/codex.rs
  • crates/tokscale-core/src/adapters/discover.rs
  • crates/tokscale-core/src/adapters/file.rs
  • crates/tokscale-core/src/adapters/goose.rs
  • crates/tokscale-core/src/adapters/hermes.rs
  • crates/tokscale-core/src/adapters/junie.rs
  • crates/tokscale-core/src/adapters/kilo.rs
  • crates/tokscale-core/src/adapters/kiro.rs
  • crates/tokscale-core/src/adapters/mod.rs
  • crates/tokscale-core/src/adapters/opencode.rs
  • crates/tokscale-core/src/adapters/pi.rs
  • crates/tokscale-core/src/adapters/trae.rs
  • crates/tokscale-core/src/lib.rs
  • crates/tokscale-core/src/message_cache.rs
  • crates/tokscale-core/src/sessions/copilot.rs

Comment thread crates/tokscale-cli/tests/copilot_memory.rs
Comment thread crates/tokscale-core/src/lib.rs Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 19 files

Re-trigger cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/tokscale-core/src/message_cache.rs (1)

501-525: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

让 cache hit 携带并复验 parser_version

Line 520 只在 get_meta 阶段校验版本,但后续 cache-hit 路径只保留 pathtake_messages* 会重新读取当前 shard;如果同一路径被另一解析器或并发进程在 parse 与 fold 之间重写,可能返回错误解析器的消息。建议让命中结果携带期望的 ParserVersion(最好也携带 fingerprint),并在读取 body 前再次校验 header。

Also applies to: 747-765

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/message_cache.rs` around lines 501 - 525, The
cache-hit path in get_meta currently validates parser_version only when locating
metadata, but the later take_messages* flow still re-reads the shard without
rechecking that the body matches the same parser. Update the
CachedSourceMeta/lookup result to carry the expected ParserVersion, and in the
relevant take_messages* read path re-validate the shard header before returning
messages, using the existing get_meta, read_shard_header, and
meta_from_header/meta_from_entry flow to ensure the hit still belongs to the
same parser version.
🧹 Nitpick comments (1)
crates/tokscale-core/src/adapters/file.rs (1)

242-243: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

避免在测试里硬编码 /tmp 路径。

这个测试只需要一个稳定的 PathBuf,用 TempDir 下的路径即可避免平台/环境假设。

建议修改
-    use std::path::{Path, PathBuf};
+    use std::path::Path;
@@
-        let path = PathBuf::from("/tmp/shared-source.jsonl");
+        let dir = tempfile::TempDir::new().unwrap();
+        let path = dir.path().join("shared-source.jsonl");

As per coding guidelines, crates/**/{tests,**/}*.rs: “Use temporary directories or fixtures rather than developer-local paths.”

Also applies to: 341-345

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/adapters/file.rs` around lines 242 - 243, 测试中不要硬编码
/tmp 路径;在 file.rs 里的相关测试应改为使用 TempDir 生成的稳定 PathBuf,并通过 PathBuf/Path
相关辅助构造替代任何开发机本地假设。请定位测试代码中引用 PathBuf、Path 以及相关断言/初始化逻辑,确保所有临时文件路径都来自
TempDir,而不是固定的 /tmp。

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/tokscale-core/src/message_cache.rs`:
- Around line 501-525: The cache-hit path in get_meta currently validates
parser_version only when locating metadata, but the later take_messages* flow
still re-reads the shard without rechecking that the body matches the same
parser. Update the CachedSourceMeta/lookup result to carry the expected
ParserVersion, and in the relevant take_messages* read path re-validate the
shard header before returning messages, using the existing get_meta,
read_shard_header, and meta_from_header/meta_from_entry flow to ensure the hit
still belongs to the same parser version.

---

Nitpick comments:
In `@crates/tokscale-core/src/adapters/file.rs`:
- Around line 242-243: 测试中不要硬编码 /tmp 路径;在 file.rs 里的相关测试应改为使用 TempDir 生成的稳定
PathBuf,并通过 PathBuf/Path 相关辅助构造替代任何开发机本地假设。请定位测试代码中引用 PathBuf、Path
以及相关断言/初始化逻辑,确保所有临时文件路径都来自 TempDir,而不是固定的 /tmp。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3470a449-87ef-4a3c-a3e3-1b882052d9b9

📥 Commits

Reviewing files that changed from the base of the PR and between d43a5c4 and 1be45b3.

📒 Files selected for processing (9)
  • crates/tokscale-cli/tests/copilot_memory.rs
  • crates/tokscale-core/src/adapters/cache.rs
  • crates/tokscale-core/src/adapters/codex.rs
  • crates/tokscale-core/src/adapters/discover.rs
  • crates/tokscale-core/src/adapters/file.rs
  • crates/tokscale-core/src/adapters/mod.rs
  • crates/tokscale-core/src/lib.rs
  • crates/tokscale-core/src/message_cache.rs
  • crates/tokscale-core/src/sessions/copilot.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/tokscale-core/src/sessions/copilot.rs
  • crates/tokscale-core/src/lib.rs
  • crates/tokscale-core/src/adapters/codex.rs
  • crates/tokscale-core/src/adapters/cache.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread crates/tokscale-core/src/adapters/codex.rs Outdated

@makoMakoGo makoMakoGo 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.

Code review complete: no blocking findings. The stale read-plan path no longer poisons taken_paths; exact-hit and append-hit cache reads recover by using a verified replacement shard or by reparsing the full Codex file; and append recovery only writes after the full parse can produce a cache entry tied to the final fingerprint. The double-writer, missing-base, and stale-plan regressions cover the previously identified data-loss windows. I would approve this revision; GitHub does not permit approving one's own pull request.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/tokscale-core/src/adapters/codex.rs (1)

653-657: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

从被测 unit 派生 Codex ParserVersion

这里手写 ParserVersion::new(ParserId::Codex, 1) 会在 Codex parser revision bump 后查询/删除错误 shard;尤其 Line 807-810 的“base cache disappears”测试会因为没有删到当前版本缓存而假阳性通过。请复用 codex_unit(...).parser_version 或测试 helper 中的当前版本常量。

Also applies to: 807-810

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/adapters/codex.rs` around lines 653 - 657, The tests
are hardcoding the Codex ParserVersion instead of deriving it from the unit
under test, which can cause stale shard lookups and false positives after parser
revision bumps. Update the assertions and cache operations in codex.rs to use
codex_unit(...).parser_version or the shared current-version test helper
constant rather than ParserVersion::new(ParserId::Codex, 1), especially in the
base cache disappears coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/tokscale-core/src/adapters/codex.rs`:
- Around line 653-657: The tests are hardcoding the Codex ParserVersion instead
of deriving it from the unit under test, which can cause stale shard lookups and
false positives after parser revision bumps. Update the assertions and cache
operations in codex.rs to use codex_unit(...).parser_version or the shared
current-version test helper constant rather than
ParserVersion::new(ParserId::Codex, 1), especially in the base cache disappears
coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0e25113d-a48a-491a-8a10-d71d426f18c1

📥 Commits

Reviewing files that changed from the base of the PR and between 1be45b3 and 114ba5a.

📒 Files selected for processing (9)
  • crates/tokscale-core/src/adapters/antigravity.rs
  • crates/tokscale-core/src/adapters/cache.rs
  • crates/tokscale-core/src/adapters/claude.rs
  • crates/tokscale-core/src/adapters/codex.rs
  • crates/tokscale-core/src/adapters/mod.rs
  • crates/tokscale-core/src/adapters/opencode.rs
  • crates/tokscale-core/src/adapters/pi.rs
  • crates/tokscale-core/src/lib.rs
  • crates/tokscale-core/src/message_cache.rs
🚧 Files skipped from review as they are similar to previous changes (7)
  • crates/tokscale-core/src/adapters/claude.rs
  • crates/tokscale-core/src/adapters/pi.rs
  • crates/tokscale-core/src/adapters/opencode.rs
  • crates/tokscale-core/src/adapters/mod.rs
  • crates/tokscale-core/src/adapters/antigravity.rs
  • crates/tokscale-core/src/adapters/cache.rs
  • crates/tokscale-core/src/message_cache.rs

@makoMakoGo
makoMakoGo merged commit 5e5bf54 into personal/local-clients Jun 24, 2026
9 checks passed
@makoMakoGo
makoMakoGo deleted the fix/source-cache-memory-revisions branch June 24, 2026 22:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(core): prevent local-source memory regressions

1 participant