Show keccak-derived slots as derivations under their reserved row - #6
Open
halaprix wants to merge 2 commits into
Open
Show keccak-derived slots as derivations under their reserved row#6halaprix wants to merge 2 commits into
halaprix wants to merge 2 commits into
Conversation
slotscope-zvd gave every reserved slot a row but could not show what lives in a mapping, because those entries sit near 2^256, nowhere near the declared sequence. They now appear as child rows under the head they descend from. The address is written the way the EVM computes it — keccak(0xaa…, 1), or keccak(0xbb…, keccak(0xaa…, 2)) for a nested hop, or keccak(3)+2 for an array element — and that string goes in the slot rail, which is the address column everywhere else in this instrument. The raw 32-byte slot is a hover detail. The derivation is the identity, because it is the thing worth learning. Every child is reconstructed from Layer-1 facts alone: KeccakObservation carries the exact preimage, so a 64-byte input splits into key and base, a 32-byte input is an array or data head, and a nested hop is followed until its tail is a declared slot. Parent linkage is therefore slot arithmetic, not name matching — a head nested inside a struct attaches with no special case, and the derivedCountByBase name-matching gap from v1.2 disappears rather than being patched. buildRows stays compiler-only: the gapless invariant is about DECLARED slots, and a derived slot is not one. Children attach at the view layer. Decisions worth keeping: - The child set spans the whole run rather than stopping at the cursor. Roving focus is index-based, so a row appearing mid-scrub would move focus under the reader; the cursor changes values, never row positions. - Read-only entries are included and marked. Nothing surfaced them before, and "read but never written" is worth teaching. - A touched slot whose derivation cannot be reconstructed becomes a visible orphan, never a silent drop. - RuntimeStorage becomes a write log in observation order. The grid is the map; two maps of the same state only made a reader pick one to believe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
docs/design/derived-slots-v1.4.md. Closesslotscope-xu8(.1,.2).What you see
slotscope-zvdgave every reserved slot a row but could not show what actuallylives in a mapping — those entries sit near 2^256, nowhere near the declared
sequence. They now appear as child rows under the head they descend from.
The address is the derivation, not the number. The rail reads
keccak(0xaa…, 1), orkeccak(0xbb…, keccak(0xaa…, 2))for a nested hop, orkeccak(3)+2for an array element. That is the slot rail — the address columneverywhere else in this instrument (line numbers, PCs, slot numbers) — so a
derived entry's address is written the way the EVM computes it. The raw 32-byte
slot is a hover detail.
Entries that were only read are included and marked read-only. Nothing in the
product surfaced those before, and "read but never written" is worth teaching.
How a child finds its parent
From Layer-1 facts alone, never by parsing a display label.
KeccakObservationcarries the exact preimage, so:
key ‖ baseSlot— both halves exact;keccak(base) + delta;key ‖ innerHash, so the tail is followed until it is adeclared slot.
Parent linkage is therefore slot arithmetic, not name matching. A head nested
inside a struct attaches with no special case, and the
derivedCountByBasename-matching gap noted in the v1.2 plan disappears rather than being patched.
buildRowsstays compiler-only — the gapless invariant is about declared slots,and a derived slot is not one — so children attach at the view layer.
Decisions worth keeping
stepIndex <= cursor. Roving focus isindex-based, so a row appearing mid-scrub would move focus under the reader. The
cursor changes values, never row positions.
gets its own honest heading instead of being dropped.
RuntimeStoragebecomes a write log in observation order with step numbers,keeping the status pill, migration badge and constructor-origin heading. The grid
is the map; two maps of the same state, ordered differently, only made a reader
decide which to believe. Its
runtime-groupe2e assertion is replaceddeliberately.
child exactly like a declared slot.
Verification
format:check,lint,typechecktest:unitderivedRowssuite runs real compiled contracts through the EVM, not hand-built layoutstest:e2efixtures:verifyrelease:verifybuild:checkbenchmark:v0.1🤖 Generated with Claude Code