Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .playwright-screens/ds2-grid.png
Binary file not shown.
Binary file removed .playwright-screens/ds2-locked.png
Binary file not shown.
Binary file removed .playwright-screens/ds2-viewport.png
Binary file not shown.
Binary file removed .playwright-screens/ds3-instrument.png
Binary file not shown.
Binary file removed .playwright-screens/ds6-full-motion.png
Binary file not shown.
Binary file removed .playwright-screens/ds6-reduced-motion.png
Binary file not shown.
Binary file removed .playwright-screens/ds7-big.png
Binary file not shown.
Binary file removed .playwright-screens/ds7-small.png
Binary file not shown.
Binary file removed .playwright-screens/ds7-stacked.png
Binary file not shown.
Binary file removed .playwright-screens/ds8-syntax.png
Binary file not shown.
Binary file added .playwright-screens/hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed .playwright-screens/strip-closeup.png
Binary file not shown.
Binary file removed .playwright-screens/v0.2-stepper.png
Binary file not shown.
Binary file removed .playwright-screens/v10-final-lower.png
Binary file not shown.
Binary file removed .playwright-screens/v10-final-top.png
Binary file not shown.
Binary file removed .playwright-screens/v10-mid.png
Binary file not shown.
Binary file removed .playwright-screens/v10-narrow.png
Binary file not shown.
Binary file removed .playwright-screens/v10-wide.png
Binary file not shown.
Binary file removed .playwright-screens/variant-b.png
Binary file not shown.
18 changes: 11 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,21 @@ human-only clean-profile demo gate (see `.agents/agent-relay/adapter.json`).

## Architecture Overview

Static React/Vite app; all compilation is local (no application network
requests). Full details: `docs/architecture.md`, ADRs in `docs/adr/`,
honest cut-line in `docs/limitations-v0.1.md`.
Static React/Vite app; all compilation and execution is local (no
application network requests). Full details: `docs/architecture.md`, ADRs
in `docs/adr/`, honest cut-line in `docs/limitations-v1.0.md`.

- `packages/domain` — locked solc environment, immutable normalized models, UTF-8/UTF-16 index
- `packages/compiler` — web-worker solc (exact version or fatal), instruction/source-map decoding, `normalize()`
- `packages/domain` — locked solc environment, immutable normalized models, UTF-8/UTF-16 index, shared hex primitives
- `packages/compiler` — web-worker solc (exact version or fatal), settings-aware Standard JSON, instruction/source-map decoding, `normalize()`
- `packages/layout` — solc storageLayout → exact bigint slot/cell model
- `packages/session` — share-URL schema v1 + bounded codec
- `packages/executor` — in-browser EVM worker (EthereumJS, Cancun), keyframe/delta trace, revert/event decode
- `packages/semantics` — Layer-3 resolver: keccak-chain grounding → exact/inferred/unresolved
- `packages/lifecycle` — generic worker-lifecycle client shared by `compiler` and `executor`
- `packages/session` — share-URL schema v1/v2 + bounded codec, `.slotscope.json`
- `packages/challenges` — challenge schema, runtime-derived answer validator, progress store
- `packages/ui` — design tokens, focus ring, reduced-motion contract
- `packages/fixtures` — public fixture corpus, goldens, manifests, Forge cross-check
- `apps/web` — composition: CodeMirror editor, assembly pane, storage grid, sharing
- `apps/web` — composition: CodeMirror editor, assembly pane, probe pane, cockpit bar, execute strip, sharing

## Conventions & Patterns

Expand Down
18 changes: 11 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,21 @@ human-only clean-profile demo gate (see `.agents/agent-relay/adapter.json`).

## Architecture Overview

Static React/Vite app; all compilation is local (no application network
requests). Full details: `docs/architecture.md`, ADRs in `docs/adr/`,
honest cut-line in `docs/limitations-v0.1.md`.
Static React/Vite app; all compilation and execution is local (no
application network requests). Full details: `docs/architecture.md`, ADRs
in `docs/adr/`, honest cut-line in `docs/limitations-v1.0.md`.

- `packages/domain` — locked solc environment, immutable normalized models, UTF-8/UTF-16 index
- `packages/compiler` — web-worker solc (exact version or fatal), instruction/source-map decoding, `normalize()`
- `packages/domain` — locked solc environment, immutable normalized models, UTF-8/UTF-16 index, shared hex primitives
- `packages/compiler` — web-worker solc (exact version or fatal), settings-aware Standard JSON, instruction/source-map decoding, `normalize()`
- `packages/layout` — solc storageLayout → exact bigint slot/cell model
- `packages/session` — share-URL schema v1 + bounded codec
- `packages/executor` — in-browser EVM worker (EthereumJS, Cancun), keyframe/delta trace, revert/event decode
- `packages/semantics` — Layer-3 resolver: keccak-chain grounding → exact/inferred/unresolved
- `packages/lifecycle` — generic worker-lifecycle client shared by `compiler` and `executor`
- `packages/session` — share-URL schema v1/v2 + bounded codec, `.slotscope.json`
- `packages/challenges` — challenge schema, runtime-derived answer validator, progress store
- `packages/ui` — design tokens, focus ring, reduced-motion contract
- `packages/fixtures` — public fixture corpus, goldens, manifests, Forge cross-check
- `apps/web` — composition: CodeMirror editor, assembly pane, storage grid, sharing
- `apps/web` — composition: CodeMirror editor, assembly pane, probe pane, cockpit bar, execute strip, sharing

## Conventions & Patterns

Expand Down
11 changes: 9 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,15 @@ See `docs/architecture.md` and the ADRs in `docs/adr/`.
message says what changed and why.
3. Every commit must leave every gate green — there are no allowed-failure
jobs and no retries for correctness or benchmark assertions.
4. Deployments are a deliberate act: `vercel deploy --prebuilt --prod` ships
the locally gate-verified artifact. Git pushes never deploy.
4. `master` is branch-protected: work happens on a branch, opens a PR, and
merges only once every required check (`quality`, `unit-fixtures`,
`build`, `browser`, `release-verify`) is green. No force-pushes, no
direct deletion, linear history only.
5. Deployment is native: Vercel is connected to `master` and redeploys
production automatically on every merge (Build Command `pnpm build`,
Output Directory `apps/web/dist`). A manual
`vercel deploy --prebuilt --prod` is only for verifying a build locally
before it lands.

## Design system

Expand Down
105 changes: 71 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,77 @@
<h1 align="center">SlotScope</h1>

<p align="center"><strong>EVM-1 · storage &amp; bytecode probe</strong><br/>
A precision instrument for Solidity: compile one contract entirely in your
browser and inspect the exact truth of it — deployed bytecode related to
source in both directions, and the storage layout as byte-accurate 32-byte
slots.</p>
A precision instrument for Solidity: compile, deploy, and step through a
contract entirely in your browser, and see the exact truth of it — source
related to bytecode in both directions, every storage slot byte-accurate,
and every runtime access named honestly or not named at all.</p>

<p align="center"><a href="https://slotscope-theta.vercel.app"><strong>▶ Live instrument</strong></a></p>

![SlotScope — the instrument](.playwright-screens/ds7-big.png)
![SlotScope — the cockpit-bar workbench](.playwright-screens/hero.png)

## What it does

The full measure loop — compile, deploy, call, step the trace, read every
named storage access — works on one screen: source, assembly, and the
storage probe stay visible while the cockpit bar and execute strip drive
execution beneath them.

- **Compile locally, exactly.** One bundled solc
(`0.8.36+commit.8a079791.Emscripten.clang`, cancun, optimizer off, via-IR
off) runs in a web worker. No backend, no network requests, works offline
after load. A version mismatch is a fatal error, never a fallback.
(`0.8.36+commit.8a079791.Emscripten.clang`, cancun) runs in a web worker.
Optimizer (with runs) and via-IR are live toggles; the header echoes the
environment the latched result _actually_ compiled with, never the
request. No backend, no network requests, works offline after load. A
version mismatch is a fatal error, never a fallback.
- **Source ↔ assembly, honestly.** Hover, keyboard-focus, or pin either side
to see the exact compiler source range on the other — the complete set of
instructions sharing a range, never a fake one-to-one mapping. Rows without
a user source range say so.
- **Storage as a memory map.** One row per slot, 32 byte cells under a
31 → 0 ruler (byte 0 is the LSB, rightmost), cross-inheritance packing with
31 → 0 ruler (byte 0 is the LSB, rightmost), a per-slot record listing
every field's name, byte range, and type, cross-inheritance packing with
declaring-contract attribution from AST ids, packed structs, static arrays,
hatched padding, and honest "expansion unavailable" spans for anything the
compiler output can't confidently expand.
- **Run it locally.** Deploy into an in-browser EVM (EthereumJS, Cancun) and
call it through ABI forms, then scrub the trace: stack, memory, calldata,
storage overlays, step in/over/out, and the exact instruction plus source
range at every step.
hatched padding, and an honest explanation for anything the compiler
output can't confidently expand (a mapping's entries live at keccak-derived
runtime slots — deploy and call to see them named).
- **Initialized values, visible on deploy.** The constructor is an execution
like any other: deploying captures its trace exactly like a call, so every
initializer's actual byte value shows up in Runtime storage the moment
"Deploy locally" succeeds — labeled _from the constructor_, never parsed
from source.
- **Run it locally, one screen.** Deploy into an in-browser EVM (EthereumJS,
Cancun) and call it through ABI forms. The live storage strip stays pinned
above the trace detail tabs at every cursor position — one band per
touched slot, bytes written up to the cursor filled amber and byte-diffed
to the proven changed range. A full-width cockpit bar (steppers, scrubber,
cursor facts, outcome) keeps stepping in view without losing the source or
storage picture.
- **Storage accesses get honest names.** `allowance[0xaa…][0xbb…]`, `mp[9].b`,
`arr[2]` — resolved only when every hop is grounded in recorded keccak
bytes and layout facts, with an auditable derivation chain (KeccakFlow),
byte-level write diffs, string-form migration badges, and cold/warm Cancun
cost facts. Anything ungrounded says `unresolved`, never a guess.
- **Share as a URL.** The whole state — source, locked environment,
selection, one pin — travels in the `#s=` fragment (schema v1, bounded and
tamper-rejecting). The recipient recompiles locally; nothing is hosted.
cost facts. Resolution status is a border treatment and a mark
(`=`/`≈`/`?`), never a color alone. Anything ungrounded says `unresolved`,
never a guess.
- **Revert forensics and events.** A failed call decodes `Error(string)`,
`Panic(code)` with its meaning, or a declared custom error by name —
never a guess for an unknown selector — with the reverting step and a
jump-to-it. Emitted logs decode against the ABI when the shape matches
exactly, honest raw topics/data otherwise.
- **A curriculum, not just an inspector.** Six Layout/Derivation challenges
whose expected answers are _derived at runtime_ from the same compiler and
executor output the panes show — never an authored constant that could
drift — including one deliberately `Unresolved` case to resolve by hand.
- **Share as a URL or a file.** The whole state — source, compiler settings,
the deterministic call sequence, trace cursor, one pin — travels in the
`#s=` fragment (schema v2, bounded and tamper-rejecting) with live
size feedback against the 2,000-character budget; larger sessions round-trip
through `.slotscope.json`. The recipient's link recompiles, redeploys, and
replays the recorded calls locally; nothing is hosted.
- **Keyboard-first, motion-optional.** Every interaction works without a
mouse; every animation collapses to 0 ms under reduced motion with
identical final state; axe-clean in both modes.
mouse (a Ctrl/⌘K command palette reaches the rest); every animation
collapses to 0 ms under reduced motion with identical final state;
axe-clean in both modes.

## Quickstart

Expand All @@ -67,25 +99,30 @@ with zero retries. Evidence lives in [docs/releases](docs/releases/).

## Architecture

Static React/Vite workspace, seven exact-pinned packages:

| Package | Role |
| ------------------- | --------------------------------------------------------------------- |
| `packages/domain` | Locked environment, immutable models, UTF-8↔UTF-16 index |
| `packages/compiler` | Worker (exact solc), instruction + source-map decoding, `normalize()` |
| `packages/layout` | solc storageLayout → exact bigint slot/cell model |
| `packages/session` | Share-URL schema v1, bounded codec |
| `packages/ui` | Instrument design tokens, focus + motion contract |
| `packages/fixtures` | Public fixture corpus, goldens, Forge cross-check |
| `apps/web` | Composition: editor, assembly, storage grid, sharing |
Static React/Vite workspace, ten exact-pinned packages:

| Package | Role |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `packages/domain` | Locked environment, immutable models, UTF-8↔UTF-16 index, hex primitives |
| `packages/compiler` | Worker (exact solc), settings-aware Standard JSON, instruction/source-map decoding, `normalize()` |
| `packages/layout` | solc storageLayout → exact bigint slot/cell model |
| `packages/executor` | In-browser EVM worker (EthereumJS), keyframe/delta trace, revert/event decode |
| `packages/semantics` | Layer-3 resolver: keccak-chain grounding, exact/inferred/unresolved |
| `packages/session` | Share-URL schema v2 + bounded codec, `.slotscope.json` |
| `packages/challenges` | Challenge schema + runtime-derived answer validator, progress store |
| `packages/lifecycle` | Generic worker-lifecycle client shared by the compiler and executor |
| `packages/ui` | Instrument design tokens, focus + motion contract |
| `packages/fixtures` | Public fixture corpus, goldens, Forge cross-check |
| `apps/web` | Composition: editor, assembly, probe pane, cockpit bar, execute strip, sharing |

Details: [docs/architecture.md](docs/architecture.md) ·
ADRs: [docs/adr](docs/adr/) ·
honest cut-line: [docs/limitations-v0.1.md](docs/limitations-v0.1.md) ·
honest cut-line: [docs/limitations-v1.0.md](docs/limitations-v1.0.md) ·
design system: [docs/design/instrument-identity-v0.15.md](docs/design/instrument-identity-v0.15.md)

## Roadmap

v0.1 Compile Spine ✔ → v0.15 Instrument Identity ✔ → v0.2 Stepper ✔ →
v0.5 Semantics ✔ → v1.0 Launch ✔ (KPI test pending — see docs/releases/v1.0.md).
v0.5 Semantics ✔ → v1.0 Launch ✔ → v1.1 Cockpit workbench ✔
(v1.0 KPI test pending — see [docs/releases/v1.0.md](docs/releases/v1.0.md)).
History: [CHANGELOG.md](CHANGELOG.md).
Loading