Skip to content

Commit 373a34b

Browse files
author
Roy Lin
committed
feat: add atomic self-drawn runtime and React Aria gate
1 parent 4fa34ff commit 373a34b

20 files changed

Lines changed: 3104 additions & 53 deletions

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ required-features = ["winui-native"]
2727
name = "component_playground"
2828
required-features = ["authoring"]
2929

30+
[[example]]
31+
name = "self_drawn_calculator"
32+
required-features = ["authoring", "platform-runtime", "software-reference"]
33+
3034
[[example]]
3135
name = "appkit_counter"
3236
required-features = ["appkit-native"]
@@ -94,6 +98,7 @@ graphics = ["dep:a3s-graphics"]
9498
software-reference = ["graphics", "a3s-graphics/software"]
9599
gpu = ["graphics", "a3s-graphics/gpu"]
96100
platform-host = []
101+
platform-runtime = ["platform-host", "graphics"]
97102
host-macos = ["platform-host"]
98103
host-windows = ["platform-host"]
99104
host-linux-wayland = ["platform-host"]

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ path uses a DOM, CSSOM, WebView, or framework-owned content renderer.
2121
> generic self-drawn layout-to-Scene slice has landed; self-drawn text, input,
2222
> IME, accessibility bridges, and real thin-host presentation remain roadmap
2323
> work. The TSX runtime, local host session, and npm packages are architecture
24-
> only and have not been implemented yet.
24+
> only and have not been implemented yet. React Aria component parity is not
25+
> claimed yet.
2526
2627
The target is unambiguous: A3S draws all application content. The existing
2728
`appkit-native`, `gtk4-native`, and `winui-native` modules create controls only
@@ -55,6 +56,29 @@ The GPU result is local DX12 evidence, not a Metal/Vulkan parity claim. Text and
5556
real self-drawn window presentation are not represented by the screenshot
5657
above.
5758

59+
## Complete React Aria scope
60+
61+
The calculator is only the first vertical renderer fixture. The product target
62+
remains every semantic component in the official React Aria catalog. The
63+
versioned [component matrix](docs/react-aria-component-matrix.json) pins
64+
`react-aria-components` 1.19.0 and is schema-checked in CI:
65+
66+
- all 51 official top-level component families map to registered A3S RSX
67+
authoring components;
68+
- `Button` currently has scene/software-pixel smoke evidence through the shared
69+
calculator, but no component is self-drawn conformant yet;
70+
- Checkbox, Radio, and Switch Field/Button parts plus ToastList and
71+
ToastContent are recorded as eight explicit API gaps;
72+
- a component reaches `conformant` only with behavior, layout/hit, Graphics
73+
scene, deterministic software, accessibility, and real self-drawn macOS,
74+
Windows, and Linux evidence.
75+
76+
Existing AppKit, GTK4, and WinUI control paths cannot satisfy that final gate.
77+
They remain frozen comparison baselines until the equivalent A3S-drawn stories
78+
pass and their content-control code is removed. See the
79+
[React Aria native direction](docs/react-aria-native.md) for the acceptance
80+
contract.
81+
5882
## TSX to native, without a browser
5983

6084
The proposed TypeScript path follows
@@ -218,8 +242,10 @@ independently.
218242
bindings, fragments, slots, and spreads
219243
- stable semantic identity and ordered prepare/commit/ACK transactions with
220244
rollback, degraded-state recovery, replay, and sensitive-value redaction
221-
- a broad built-in `rsx_ui` registry covering foundations, forms, collections,
222-
overlays, date/time, color, feedback, routing, and drag/drop semantics
245+
- a broad built-in `rsx_ui` registry with name-level coverage for all 51 pinned
246+
React Aria families across foundations, forms, collections, overlays,
247+
date/time, color, feedback, routing, and drag/drop semantics; this is
248+
authoring coverage, not a self-drawn parity claim
223249

224250
### Interaction and accessibility
225251

@@ -259,6 +285,20 @@ independently.
259285
- executable source and Cargo-feature firewalls proving the common contract has
260286
no Graphics, OS toolkit, or legacy renderer dependency
261287

288+
### Atomic self-drawn frames
289+
290+
- opt-in `platform-runtime` orchestration from one owned `NativeElement` tree
291+
through layout, hit regions, Graphics Scene, accessibility, and a monotonic
292+
zero-widget host transaction
293+
- a transactional `PlatformScenePresenter` seam: pixels are prepared without
294+
exposure, published only after host commit, and discarded on rejection
295+
- retained resize, fractional-scale, damage, occlusion, redraw, delayed
296+
acknowledgement, and surface-loss replay without changing semantic identity
297+
- an identical-frame fast path that performs no layout, scene, host, or
298+
presentation work, plus semantic-only commits that skip pixel presentation
299+
- a software Graphics presenter and shared `self_drawn_calculator` smoke that
300+
preserve the reviewed 410x620 layout and scene fingerprints
301+
262302
## Roadmap at a glance
263303

264304
| Milestone | State | Evidence or next gate |
@@ -269,8 +309,9 @@ independently.
269309
| M3 · Layout and Scene | Current | Generic calculator rectangle slice landed; full flex, stacking, redraw scheduling, cross-platform fingerprints, and thin-host presentation remain |
270310
| M4 · Text and interaction cutover | Planned | Shaping, glyphs, GUI-owned input, IME, accessibility bridges, overlays, and complete calculator scenarios |
271311
| M5 · Default cutover | Planned | Make self-drawn content the default, then delete the three legacy widget renderers |
272-
| H0-H5 · Thin platform hosts | H0 complete; H1 next | Zero-widget records, transactions, recording host, target feature markers, and dependency/source firewalls landed; shared window runtime is next |
312+
| H0-H5 · Thin platform hosts | H0 complete; H1 in progress | Atomic shared frames, transactional presentation, lifecycle recovery, zero-toolkit firewalls, and calculator pixels landed; portable input/reducer routing and a real raw-surface presenter remain |
273313
| T0-T5 · TSX native authoring | Proposed | Automatic JSX runtime, versioned Node-to-host session, state/event runtime, self-drawn native window, packages, and stable SDK |
314+
| M6-M8 · React Aria components | Catalog pinned; conformance planned | 51/51 families mapped, eight public parts explicitly missing, Button scene smoke only; full software and three-OS self-drawn evidence required |
274315

275316
The dependency-ordered plan and acceptance gates are in the
276317
[delivery roadmap](docs/roadmap.md).
@@ -286,6 +327,7 @@ The default set is `headless + authoring + design-system + software-reference`.
286327
| `software-reference` | Deterministic retained reference renderer; implies `graphics` |
287328
| `gpu` | Owned offscreen GPU renderer and readback path; implies `graphics` |
288329
| `platform-host` | H0 zero-widget records, transaction trait, recording host, and conformance tests; no Graphics or OS dependency |
330+
| `platform-runtime` | H1 Native IR/layout/scene/accessibility frame orchestration over `platform-host + graphics`; no OS toolkit dependency |
289331
| `host-macos`, `host-windows` | H0 target markers over `platform-host`; OS shell implementations land in H2/H3 |
290332
| `host-linux-wayland`, `host-linux-x11`, `host-linux` | H0 target markers over `platform-host`; Linux implementations land in H4 |
291333
| `authoring` | SWC-backed RSX parsing, `ComponentCx`, and explicit component registries |
@@ -305,6 +347,9 @@ cargo check --locked --no-default-features --features software-reference --lib
305347
cargo check --locked --no-default-features --features gpu --lib
306348
cargo check --locked --no-default-features --features platform-host --lib
307349
cargo test --locked --no-default-features --features platform-host --lib platform_host::
350+
cargo check --locked --no-default-features --features platform-runtime --lib
351+
cargo test --locked --no-default-features --features platform-runtime --lib platform_runtime::
352+
cargo test --locked --test react_aria_component_matrix
308353
```
309354

310355
## Platform hosts: migration baseline and target
@@ -350,6 +395,7 @@ cargo run --locked --example state_loop
350395
cargo run --locked --example native_runtime_app
351396
cargo run --locked --example dogfood_session
352397
cargo run --locked --example component_playground
398+
cargo run --locked --no-default-features --features authoring,platform-runtime,software-reference --example self_drawn_calculator
353399
```
354400

355401
Host-selecting recipes:
@@ -415,10 +461,11 @@ src/
415461
| LayoutSnapshot to Graphics Scene lowering
416462
|- render_contract.rs executable field/role/event milestone inventory
417463
|- platform_host/ H0 zero-widget records, transactions, recorder, and validation
464+
|- platform_runtime/ H1 atomic frames, presentation lifecycle, and Graphics smoke
418465
|- backend/ + platform/ legacy execution/planning migration baseline
419466
`- *_native/ AppKit, GTK4, and WinUI control hosts during migration
420467
421-
examples/ headless, calculator, dogfood, controls, and playground apps
468+
examples/ headless, self-drawn, calculator, dogfood, controls, and playground apps
422469
docs/ architecture, contracts, packaging, language, and roadmap
423470
packaging/ unsigned native smoke-bundle assets and validators
424471
```
@@ -436,6 +483,7 @@ packaging/ unsigned native smoke-bundle assets and validators
436483
- [TSX to native runtime architecture](docs/tsx-native-runtime.md)
437484
- [Native style contract](docs/style-contract.md)
438485
- [React Aria native direction](docs/react-aria-native.md)
486+
- [Executable React Aria component matrix](docs/react-aria-component-matrix.json)
439487
- [Native app shell](docs/app-shell.md)
440488
- [Native packaging](docs/packaging.md)
441489
- [Delivery roadmap](docs/roadmap.md)

docs/architecture.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ This is a runtime ownership boundary, not a second component model. All three
140140
paths produce the same compiled RSX tree and enter the same semantic/native
141141
lowering pipeline.
142142

143+
### React Aria catalog gate
144+
145+
The built-in registry is checked against the complete official React Aria
146+
Components 1.19.0 navigation catalog. The versioned
147+
[`react-aria-component-matrix.json`](react-aria-component-matrix.json) contains
148+
all 51 top-level families, their registered A3S component parts, the eight
149+
currently missing public parts, delivery milestones, self-drawn status, and
150+
evidence links. `tests/react_aria_component_matrix.rs` rejects a missing family,
151+
an unregistered mapping, an untracked newly implemented part, or a conformance
152+
claim without software and all three operating-system lanes.
153+
154+
Registry coverage proves that an author can name and lower a component. It
155+
does not prove self-drawn parity. Component completion additionally requires
156+
portable behavior, layout and hit regions, Graphics scene and deterministic
157+
pixels, accessibility semantics, and real self-drawn macOS/Windows/Linux host
158+
automation. AppKit, GTK4, and WinUI content-control runs remain migration
159+
oracles only.
160+
143161
## Dependency Direction
144162

145163
Cargo features enforce both the authoring/runtime split and the graphics
@@ -149,8 +167,11 @@ the built-in `rsx_ui` registry. `graphics` enables only the pinned engine scene
149167
contract, while `software-reference` adds deterministic retained
150168
rasterization. `gpu` adds the real offscreen renderer, capability report, and
151169
readback path from pinned Graphics commit `8748fab`; there is no placeholder
152-
backend. The default feature set keeps the existing authoring experience plus
153-
software reference evidence, while
170+
backend. `platform-host` adds only bounded zero-widget OS records, while
171+
`platform-runtime` adds the one-way Native IR/layout/scene/accessibility frame
172+
coordinator and Graphics presentation seam without enabling an OS toolkit. The
173+
default feature set keeps the existing authoring experience plus software
174+
reference evidence, while
154175
`cargo check --no-default-features --lib` proves that protocol, semantic,
155176
interaction, focus, selection, i18n, and accessibility remain usable without
156177
Graphics, SWC, or `rsx_ui`.
@@ -168,9 +189,13 @@ diagnostics share those identities. The semantic-only layout module produces a
168189
versioned `LayoutSnapshot`, while the optional Graphics adapter rejects
169190
error-level M3 omissions and derives stable `DrawId` values from layout paths.
170191
The existing shared calculator tree pins layout and scene fingerprints plus
171-
software and local Direct3D 12 image evidence. This is rectangle-path evidence,
172-
not a claim that text, full flex/grid behavior, presentation, or M4 interaction
173-
has landed.
192+
software and local Direct3D 12 image evidence. The H1-in-progress
193+
`SelfDrawnWindowRuntime` now commits that same tree, layout, hit data, scene,
194+
and accessibility projection as one monotonic host frame. Its transactional
195+
presenter publishes software Graphics pixels only after host commit and replays
196+
the last scene after surface loss. This remains rectangle-path evidence, not a
197+
claim that text, full flex/grid behavior, a real OS swapchain, or portable M4
198+
input routing has landed.
174199

175200
The remaining dependencies stay one-way:
176201

@@ -205,6 +230,11 @@ capability types but must not depend on the ACL parser or its AST.
205230

206231
## Native Input Evidence Boundary
207232

233+
The existing capability manifests in this section describe the legacy
234+
content-control baseline that the self-drawn runtime must preserve. They do not
235+
complete a React Aria matrix entry. Final component evidence must drive the
236+
zero-widget platform hosts and A3S-owned pixels.
237+
208238
`NativeCapabilities` describes the behavior a backend claims for each role.
209239
`NativeInputConformanceManifestV1` turns native press claims into a canonical
210240
role/scenario matrix, including activation, cancellation, disabled-state, and

docs/platform-hosts.md

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Self-Drawn Platform Host Architecture
22

3-
Status: H0 contract and dependency firewall complete; H1 shared window runtime
4-
is next. The desktop OS shells described here are not implemented yet.
3+
Status: H0 complete; H1 atomic frame orchestration and presentation lifecycle
4+
in progress. Portable input/reducer routing and real desktop OS shells are not
5+
implemented yet.
56

6-
Updated: 2026-08-01
7+
Updated: 2026-08-02
78

89
## Decision
910

@@ -43,12 +44,15 @@ The repository currently contains three distinct layers:
4344
system-service records; atomic revision transactions; a recording host; and
4445
executable dependency/source firewalls.
4546

46-
The next missing layer is the H1 shared runtime that connects committed layout,
47-
scene, hit-region, accessibility, and service state to the new host contract.
48-
Production H2-H4 hosts must then attach Graphics to real top-level surfaces and
49-
return OS services without constructing content controls. The old control
50-
backends are frozen until this replacement passes its gates. They are migration
51-
inputs, not the target architecture and not a base for new TSX work.
47+
The first H1 layer now connects committed Native IR, layout, scene, hit-region,
48+
and accessibility state to the new host contract. It also owns transactional
49+
scene preparation/publication plus resize, scale, damage, occlusion, redraw,
50+
delayed acknowledgement, and surface-loss replay. Portable hit/focus/action
51+
routing is the next H1 slice. Production H2-H4 hosts must then attach Graphics
52+
to real top-level surfaces and return OS services without constructing content
53+
controls. The old control backends are frozen until this replacement passes
54+
its gates. They are migration inputs, not the target architecture and not a
55+
base for new TSX work.
5256

5357
## Target Pipeline
5458

@@ -200,21 +204,35 @@ src/platform_host/
200204
201205
tests/platform_host_firewall.rs
202206
207+
src/platform_runtime/
208+
|- frame.rs committed Native IR/layout/scene/a11y snapshot
209+
|- runtime.rs atomic candidate preparation and host commit
210+
|- events.rs resize, scale, occlusion, redraw, and ack lifecycle
211+
|- presenter.rs raw-surface prepare/publish contract and recorder
212+
|- reference_presenter.rs
213+
| transactional software Graphics evidence
214+
|- accessibility.rs stable layout-path semantic projection
215+
`- tests.rs atomicity, no-op, recovery, and identity gates
216+
217+
tests/platform_runtime_firewall.rs
218+
examples/self_drawn_calculator.rs
219+
203220
Planned next:
204-
src/platform_host/runtime.rs
221+
src/platform_runtime/interaction.rs
205222
src/platform_host/macos/
206223
src/platform_host/windows/
207224
src/platform_host/linux/
208225
209-
examples/self_drawn_calculator.rs
210226
src/bin/a3s_gui_host.rs
211227
```
212228

213229
The `platform-host`, `host-macos`, `host-windows`, `host-linux-wayland`,
214-
`host-linux-x11`, and `host-linux` features landed in H0. The target features
215-
currently select the common contract only; OS dependencies arrive with their
216-
H2-H4 implementation. None enables or imports `appkit-native`, `gtk4-native`,
217-
`winui-native`, or the legacy widget-planning modules.
230+
`host-linux-x11`, and `host-linux` features landed in H0. H1 adds the separate
231+
`platform-runtime = platform-host + graphics` feature so the H0 wire boundary
232+
stays Graphics-free. The target features currently select the common contract
233+
only; OS dependencies arrive with their H2-H4 implementation. Neither H0 nor
234+
H1 enables or imports `appkit-native`, `gtk4-native`, `winui-native`, or the
235+
legacy widget-planning modules.
218236

219237
The new modules are created beside the legacy directories rather than by
220238
renaming a control backend. This makes accidental content-widget reuse visible
@@ -307,7 +325,7 @@ Evidence:
307325

308326
### H1 - Shared self-drawn window runtime
309327

310-
Status: next; depends on the M3 presentation boundary.
328+
Status: in progress; atomic frame and presentation-lifecycle slice landed.
311329

312330
Deliverables:
313331

@@ -319,6 +337,30 @@ Deliverables:
319337
pipeline
320338
- add the shared `self_drawn_calculator` entrypoint and fake-host smoke runner
321339

340+
Landed evidence:
341+
342+
- `SelfDrawnWindowRuntime` builds one immutable Native IR, layout, hit-region,
343+
scene, and stable-id accessibility snapshot before host mutation
344+
- `PlatformScenePresenter` prepares candidate pixels, publishes only after a
345+
matching host commit, and discards rejected candidates
346+
- identical frames skip layout, scene, host, and presenter work; semantic-only
347+
changes commit accessibility without presenting identical pixels
348+
- resize, fractional scale, damage, occlusion, redraw, delayed acknowledgements,
349+
dropped frames, and surface loss replay the retained scene deterministically
350+
- 14 focused runtime/software tests and three recursive feature/source
351+
firewall tests pass without any legacy renderer or OS toolkit dependency
352+
- `self_drawn_calculator` commits the existing 410x620 shared Native IR and
353+
reproduces layout fingerprint `16529597026056060935`, scene fingerprint
354+
`2100550662756266801`, and deterministic RGBA pixels
355+
356+
Remaining before H1 is complete:
357+
358+
- route raw host input through portable hit testing, focus, interaction state,
359+
action selection, and the application reducer without a legacy widget plan
360+
- implement the Graphics raw-surface presenter used by H2-H4; the landed
361+
presenter contract and software implementation deliberately expose no raw
362+
handle to components or common host records
363+
322364
Gates:
323365

324366
- an unchanged frame creates no new layout, scene, or present work
@@ -463,7 +505,8 @@ or dependency-boundary evidence.
463505

464506
## First Reviewable Commit Sequence
465507

466-
1. Add H1 shared frame orchestration and raw-surface presentation lifecycle.
508+
1. Finish H1 portable hit/focus/reducer routing and bind its presenter contract
509+
to the Graphics raw-surface edge.
467510
2. Present the rectangle-only shared calculator through the Windows host.
468511
3. Present the same rectangle-only calculator through the macOS host.
469512
4. Present it through Wayland, then add the separately gated X11 fallback.

0 commit comments

Comments
 (0)