Skip to content

feat(sim): the frame inspector + the handshake-refusal path - #19

Merged
Kinflou merged 1 commit into
masterfrom
feat/sim-1e-inspector
Sep 2, 2026
Merged

feat(sim): the frame inspector + the handshake-refusal path#19
Kinflou merged 1 commit into
masterfrom
feat/sim-1e-inspector

Conversation

@Kinflou

@Kinflou Kinflou commented Sep 2, 2026

Copy link
Copy Markdown
Member

Milestone 1e — completes Phase 1.

Frame inspector

  • framedecode.ts reads a raw frame back with the same framing / Handshake decoders the runtime uses, then JSON-decodes the sub-frames. It resolves a datagram call id → function name and reverses the handshake's wire-format / framing FNV name-hashes.
  • framelog.ts rows are <details> now: direction, kind, function, Δ since the previous frame, byte length — expand for the decoded envelope (params / ok / err · ordinal), a hex toggle, and the framing name. Handshake / unknown frames read distinctly; a clear button.

Version skew → handshake refusal

Each instance snapshots the schema's ir_hash when placed. rebuild leaves it alone, so editing a schema and returning keeps a surviving instance on the old IR. resyncInstance — a button in the inspector, shown only when the snapshot is stale — snaps it forward.

engine.connect now handshakes each end with its own instance's hash and doesn't throw on a mismatch: it returns LiveConnection.error = "handshake". The wire turns red, the call form hides, and the log gets a connection refused · handshake row. Both handshake frames are still captured.

Also: a per-connection latency knob (ms) in the inspector.

Tests

✔ 1d — place, connect, call … (now also: labelled handshake frames + an expanded request frame's decoded params)
✔ 1e — resyncing only the server after a schema edit refuses the handshake

The 1e test drives the whole demo: connect on V1 → setShape(V2) (both stay live) → resync only the server → wire-refused + a frame-refused row + "connection refused · handshake" in the inspector.

15/15 sim tests pass. npm run build green; +~1.3 KB gz.

Milestone 1e (docs: design/playground-simulation.md) — completes Phase 1.

- framedecode.ts — read a raw frame back with the same framing / handshake
  decoders the runtime uses, plus a JSON decode of the sub-frames.
  Resolves a datagram call id to a function name; reverses the handshake's
  wire-format / framing name hashes.

- framelog.ts — rows are now <details>: direction, kind, function, Δ since
  the previous frame, byte length; expand for the decoded envelope
  (params / ok / err), a hex toggle, and the framing name. Handshake and
  unknown frames read distinctly; a "clear" button; a refusal row.

- version-skew / handshake refusal. Each instance snapshots the schema's
  `ir_hash` when placed; `rebuild` leaves it alone, so editing a schema and
  returning keeps a surviving instance on the old IR. `resyncInstance`
  (a button in the inspector, shown only when the snapshot is stale) snaps
  it forward. `engine.connect` handshakes each end with its own instance's
  hash and no longer throws on a mismatch — it returns
  `LiveConnection.error = "handshake"`; the wire goes red, the call form
  hides, and the log gets a "connection refused · handshake" row.

- a per-connection latency knob (ms) in the inspector.

- view.test.ts: the 1d call test now also checks the labelled handshake
  frames and an expanded request frame's decoded params; a new test drives
  the whole refusal demo (connect on V1 → edit to V2 → resync only the
  server → refused).

15/15 sim tests pass.
@Kinflou
Kinflou merged commit f746599 into master Sep 2, 2026
2 checks passed
@Kinflou
Kinflou deleted the feat/sim-1e-inspector branch September 2, 2026 19:14
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