Skip to content

feat(scene): wire useSceneTrace into App so real sessions emit frames#958

Merged
esengine merged 1 commit into
mainfrom
rust-stage0-producer-wiring
May 15, 2026
Merged

feat(scene): wire useSceneTrace into App so real sessions emit frames#958
esengine merged 1 commit into
mainfrom
rust-stage0-producer-wiring

Conversation

@esengine
Copy link
Copy Markdown
Owner

Closes the last open Stage 0 item in #947 — `useSceneTrace` hooks
into AppInner so a real session running with
`REASONIX_SCENE_TRACE=path/to/frames.jsonl` produces one frame per
state change. The Rust binary from #953 can read that trace and
debug-print decoded SceneFrames, end-to-end on real data.

What gets emitted

A one-line summary today: card count, busy/idle, activity label.
Wrapped in a Box with `paddingX: 1` so the frame is a believable
SceneNode shape, not just a string.

```
reasonix · 3 cards · busy · awaiting response
```

Why a stub frame, not a full lowering

`lowerInkToScene` only handles Ink primitives — `Text` and `Box`. The
App render tree is mostly function components, and lowering them
automatically requires either (a) finishing #565 enough that
subtrees decompose to primitives, or (b) a function-component
expansion helper. Both are bigger pieces of work.

This PR gets us the wiring without committing to that path. The
producer is real, the boundary is proven on real data, and the
shape is stable enough for the Rust side to test against. When
lowering matures, only the body of `useSceneTrace` changes; the
call site in App stays one line.

Surface area in App.tsx

Three lines added:

  • 1 new import (alphabetically slotted).
  • 1 new `useAgentState` selector for `cardCount` next to the
    existing `isStreaming` selector.
  • 1 `useSceneTrace({ cardCount, busy, activity: activityLabel })`
    call after the existing `busyRef` effect.

No state ownership changes, no render-tree changes, no behavior
change when the env var is unset (which is the default).

Refs #868 #947

Closes the last open Stage 0 item from #947 — a real session running
with REASONIX_SCENE_TRACE=path/to/frames.jsonl now writes one frame
per state change to the trace file. The Rust binary from #953 can
read this trace and replay decoded SceneFrames end-to-end.

The frame today is a one-line summary (card count, busy/idle,
activity label), not a full lowering of the Ink tree. That's
intentional: lowerInkToScene only handles Ink primitives, and the
App tree is mostly stateful components. A full automatic lowering
is blocked on either (a) finishing #565 so the render tree is
decomposable, or (b) adding a function-component expansion helper —
both bigger pieces of work.

What this PR gets us anyway: a wired producer, the boundary proven
on real data, and a stable shape for the Rust side to test against.
When the lowering matures, only the body of useSceneTrace changes;
the call site in App stays the same.

Refs #868 #947
@esengine esengine merged commit d499928 into main May 15, 2026
4 checks passed
@esengine esengine deleted the rust-stage0-producer-wiring branch May 15, 2026 15:07
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