Skip to content

Fix "entries seen" chip double-counting on reserved rows - #10

Merged
halaprix merged 3 commits into
masterfrom
fix/derived-entries-overcount
Jul 31, 2026
Merged

Fix "entries seen" chip double-counting on reserved rows#10
halaprix merged 3 commits into
masterfrom
fix/derived-entries-overcount

Conversation

@halaprix

Copy link
Copy Markdown
Owner

The bug

A single history.push(7) in a constructor reports "2 entries seen" on the
history reserved row, not 1.

Root cause

runtimeView.ts's derivedCountByBase counted distinct resolution labels
grouped by baseVariable. A dynamic array's push touches two storage slots
under the same baseVariable ("history"):

  1. the declared length slot itself — read on entry, rewritten on exit, labeled
    history.length by resolveReferenceBaseSlot;
  2. the actual new element, at a keccak-derived slot, labeled history[0].

Both got counted as if they were derived entries, so the label-based count always
overcounted a push by exactly one — the reserved slot's own bookkeeping access was
mistaken for a second entry.

The fix

derivedRows.ts's buildDerivedChildren — added in v1.4 for the child-row
rendering — already solves this correctly: it explicitly excludes a variable's own
declared slot from the derived set (if (declaredSlots.has(slot)) continue),
counting only slots that are genuinely keccak-derived. StorageGrid.tsx already
computes that exact list per row as children (it drives the rendered child rows).
The chip now reads children.length instead of the separate, buggy
derivedCountByBase mechanism — one source of truth, so the chip and the rows can
never disagree.

Bonus fix, same root cause: this also resolves the struct-nesting gap flagged
when v1.4 shipped. derivedCountByBase keyed on baseVariable (a name), which
never matched a mapping declared inside a struct (s.m vs baseVariable: "m").
byParentSlot keys on the actual slot number, so it's correct regardless of
nesting.

derivedCountByBase was used nowhere else, so it's removed entirely along with its
now-obsolete unit test, rather than left as a second, disagreeing mechanism.

Verification

Reproduced the exact reported scenario as an e2e assertion first (confirmed it
failed against the old code — showed "2 entries seen" — before applying the fix),
then verified green after:

'a reserved slot shows the value the constructor put in it' — history.push(7)
  now asserts: contains '1 entry seen', does not contain '2 entries seen'
Gate Result
format:check, lint, typecheck clean
test:unit 240/240
test:e2e (storage.spec.ts) 10/10
test:e2e (full suite) 62/62
fixtures:verify no drift
release:verify passed
build:check 226 KB main entry

🤖 Generated with Claude Code

…ce row

A single history.push(7) reported "2 entries seen" instead of 1. runtimeView's
derivedCountByBase counted distinct resolution LABELS per baseVariable, but a
dynamic array push touches two storage slots under the same baseVariable: the
declared length slot itself (read on entry, rewritten on exit — labeled
"history.length") and the actual new element at a keccak-derived slot (labeled
"history[0]"). Both got counted as if they were derived entries, so one push
always overcounted by exactly one.

derivedRows.ts's buildDerivedChildren already solves this correctly for the
child-row rendering added in v1.4: it explicitly excludes a variable's own
declared slot from the derived set (`if (declaredSlots.has(slot)) continue`),
counting only slots that are genuinely keccak-derived. StorageGrid.tsx already
computes that exact list per row as `children`; the chip now reads its length
instead of the separate, buggy derivedCountByBase mechanism.

This also fixes the struct-nesting gap flagged when v1.4 shipped:
derivedCountByBase keyed on baseVariable (a name), which never matched a
mapping declared inside a struct (s.m vs baseVariable "m"). byParentSlot keys
on the actual slot number, so it's correct regardless of nesting.

derivedCountByBase is now dead (was used nowhere else) and removed, along with
its now-obsolete unit test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
slotscope Ready Ready Preview Jul 31, 2026 1:30pm

@halaprix
halaprix merged commit 5a23a6c into master Jul 31, 2026
8 checks passed
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