Skip to content

fix(kiro): de-duplicate snapshot traversal and align model-id key-sets - #752

Merged
junhoyeo merged 2 commits into
mainfrom
fix/kiro-715-snapshot
Jun 22, 2026
Merged

fix(kiro): de-duplicate snapshot traversal and align model-id key-sets#752
junhoyeo merged 2 commits into
mainfrom
fix/kiro-715-snapshot

Conversation

@junhoyeo

@junhoyeo junhoyeo commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Problem

crates/tokscale-core/src/sessions/kiro.rs parses Kiro IDE globalStorage snapshots. Three confirmed bugs (#715):

  • (a) Double-count. collect_kiro_snapshot_text recursed into every present key across three overlapping key-sets ([prompt,response,content,text,message], the container set, and [parts,items,nodes]). When a single object stored the same payload under aliased keys — e.g. both content and text, or both messages and entries — the text was counted once per alias, inflating estimated token totals.
  • (b) Key-set mismatch. find_kiro_snapshot_model_id omitted prompt/response/parts/items/nodes — keys that collect_kiro_snapshot_text descends into — so a model id nested under those keys was missed and fell back to unknown.
  • (c) Date bucketing. The snapshot is emitted as one message at the file mtime, mis-bucketing historical usage into the day the file was last written.

Fix

  • (a) Treat each key-set as an ordered list of aliases for the same logical payload and descend into only the first present key per group, so each node's text is collected exactly once.
  • (b) Align find_kiro_snapshot_model_id's key-set with collect_kiro_snapshot_text (adds prompt, response, parts, items, nodes).
  • (c) Kiro snapshots carry no per-turn timestamps (unlike the CLI .jsonl and sqlite request_metadata sources). No timestamps are synthesized; mtime is kept and the limitation is documented with a clear comment so a future schema with per-turn times can split into per-turn messages.

Tests

Added regression tests:

  • test_collect_kiro_snapshot_text_does_not_double_count_aliased_keys — same body under content + text counted once.
  • test_collect_kiro_snapshot_text_does_not_double_count_aliased_containers — same list under messages + entries counted once.
  • test_find_kiro_snapshot_model_id_descends_into_aliased_text_keys — model id under parts and prompt is discovered.

cargo test -p tokscale-core (13 kiro tests pass) and cargo clippy -p tokscale-core --tests are green.

Residual concern

(c) is documented, not fixed — it requires a snapshot schema that exposes per-turn timestamps, which does not currently exist.

🤖 Generated with Claude Code


Summary by cubic

Fixes double-counting in Kiro snapshot parsing by de-duplicating alias keys by value while still counting distinct subtrees, and aligns model-ID discovery. Fixes #715; date bucketing remains at file mtime and is documented.

  • Bug Fixes
    • De-duplicate traversal in collect_kiro_snapshot_text by visiting all keys in each alias group but skipping structurally equal subtrees, so identical aliased text is counted once while distinct prompt/response or messages/history bodies are both counted (regression tests added).
    • Align find_kiro_snapshot_model_id with the same key-sets so IDs under prompt, response, content, text, message, container aliases, and parts/items/nodes are found (regression tests added).
    • Keep snapshot date bucketing at file mtime; document the limitation and future path if per-turn timestamps appear.

Written for commit 86b0883. Summary will update on new commits.

Review in cubic

Kiro IDE globalStorage snapshots are parsed by collect_kiro_snapshot_text,
which recursed into every present key across three overlapping key-sets.
When a single object stored the same payload under aliased keys (e.g. both
`content` and `text`, or both `messages` and `entries`), the text was
counted once per alias, inflating estimated token totals.

(a) Treat each key-set as an ordered list of aliases for the same logical
    payload and descend into only the first present key per group, so each
    node's text is collected exactly once.
(b) find_kiro_snapshot_model_id omitted `prompt`/`response`/`parts`/`items`/
    `nodes`, keys that collect_kiro_snapshot_text descends into, so a model
    id nested under those keys was missed and fell back to `unknown`. Align
    the key-sets.
(c) Snapshots have no per-turn timestamps, so the whole blob is emitted as a
    single message at the file mtime, mis-bucketing historical usage. No such
    timestamps exist in the schema, so mtime is kept and the limitation is
    documented explicitly rather than synthesizing timestamps.

Adds regression tests for (a) (aliased text keys and aliased containers) and
(b) (model id under `parts` and `prompt`).

Confidence: high
Scope-risk: narrow
Not-tested: real-world snapshot schemas with deeply nested mixed aliases
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
tokscale Ignored Ignored Preview Jun 22, 2026 10:25am

Request Review

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 1 file

Re-trigger cubic

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0788385194

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


for key in ["parts", "items", "nodes"] {
if let Some(item) = map.get(key) {
if let Some(item) = group.iter().find_map(|key| map.get(*key)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve distinct snapshot fields when de-duplicating aliases

When a snapshot object contains more than one key from a group with different subtrees (for example a turn with both prompt and response, or a chat object with both messages and history), this find_map only visits the first present key and silently drops the rest, undercounting tokens that the previous traversal would have included. The double-count fix should only skip later keys when they are actually duplicate payloads, rather than treating every key in the group as mutually exclusive.

Useful? React with 👍 / 👎.

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.

Fixed in 86b0883. You're right — the find_map made every key in a group mutually exclusive, so an object holding distinct subtrees under multiple group keys (e.g. both prompt and response, or both messages and history) silently dropped all but the first, undercounting tokens.

collect_kiro_snapshot_text now descends into every present key in each alias group but de-duplicates by VALUE: a subtree structurally equal to one already visited in the same group is skipped. Distinct payloads are all counted; genuine aliases (identical text under content+text, or the same list under messages+entries) are still counted once, preserving this PR's original double-count fix.

Added two regression tests: test_collect_kiro_snapshot_text_counts_distinct_alias_subtrees (distinct prompt/response bodies both counted) and test_collect_kiro_snapshot_text_counts_distinct_container_subtrees (distinct messages/history lists both counted). The existing identical-alias dedup tests still pass. cargo test -p tokscale-core (988 passed) and cargo clippy -p tokscale-core --tests are green.

collect_kiro_snapshot_text used find_map to visit only the FIRST present
key in each alias group, which silently dropped distinct subtrees stored
under other keys of the same group (e.g. a turn with both `prompt` and
`response`, or a chat with both `messages` and `history`), undercounting
tokens. Now descend into every present key but skip subtrees structurally
equal to one already visited in the same group, so distinct payloads are
all counted while genuine aliases are still counted once.

Constraint: Must preserve the PR's original double-count fix for identical aliased text
Rejected: Visit only first present key | drops distinct sibling payloads
Confidence: high
Scope-risk: narrow
@junhoyeo
junhoyeo merged commit 24e3771 into main Jun 22, 2026
14 of 15 checks passed
makoMakoGo added a commit to makoMakoGo/tokscale that referenced this pull request Jun 23, 2026
ported from upstream junhoyeo#735
ported from upstream junhoyeo#737
ported from upstream junhoyeo#747
ported from upstream junhoyeo#750
ported from upstream junhoyeo#752
ported from upstream junhoyeo#760
ported from upstream junhoyeo#766
t1000040 pushed a commit to tmobi-internal/tokscale that referenced this pull request Jun 30, 2026
junhoyeo#752)

* fix(kiro): de-duplicate snapshot traversal and align model-id key-sets

Kiro IDE globalStorage snapshots are parsed by collect_kiro_snapshot_text,
which recursed into every present key across three overlapping key-sets.
When a single object stored the same payload under aliased keys (e.g. both
`content` and `text`, or both `messages` and `entries`), the text was
counted once per alias, inflating estimated token totals.

(a) Treat each key-set as an ordered list of aliases for the same logical
    payload and descend into only the first present key per group, so each
    node's text is collected exactly once.
(b) find_kiro_snapshot_model_id omitted `prompt`/`response`/`parts`/`items`/
    `nodes`, keys that collect_kiro_snapshot_text descends into, so a model
    id nested under those keys was missed and fell back to `unknown`. Align
    the key-sets.
(c) Snapshots have no per-turn timestamps, so the whole blob is emitted as a
    single message at the file mtime, mis-bucketing historical usage. No such
    timestamps exist in the schema, so mtime is kept and the limitation is
    documented explicitly rather than synthesizing timestamps.

Adds regression tests for (a) (aliased text keys and aliased containers) and
(b) (model id under `parts` and `prompt`).

Confidence: high
Scope-risk: narrow
Not-tested: real-world snapshot schemas with deeply nested mixed aliases

* fix(kiro): de-duplicate snapshot aliases by value, not first-key-only

collect_kiro_snapshot_text used find_map to visit only the FIRST present
key in each alias group, which silently dropped distinct subtrees stored
under other keys of the same group (e.g. a turn with both `prompt` and
`response`, or a chat with both `messages` and `history`), undercounting
tokens. Now descend into every present key but skip subtrees structurally
equal to one already visited in the same group, so distinct payloads are
all counted while genuine aliases are still counted once.

Constraint: Must preserve the PR's original double-count fix for identical aliased text
Rejected: Visit only first present key | drops distinct sibling payloads
Confidence: high
Scope-risk: narrow
@junhoyeo
junhoyeo deleted the fix/kiro-715-snapshot branch July 13, 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