From 850ca8691b7cf9b5b4a48b139988dd7490b2b18f Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 16 Jun 2026 05:46:13 +0100 Subject: [PATCH] implements PLN-0120 --- discussion/index.ndjson | 2 +- ...LN-0120-update-real-render-worker-specs.md | 2 +- docs/specs/runtime/04-gfx-peripheral.md | 44 +++++++++++++++++++ .../runtime/09-events-and-concurrency.md | 31 ++++++++++++- ...ortability-and-cross-platform-execution.md | 11 ++++- docs/specs/runtime/README.md | 7 +++ 6 files changed, 92 insertions(+), 5 deletions(-) diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 29ccbc53..d41e1fad 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -2,7 +2,7 @@ {"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."} {"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]} {"type":"discussion","id":"DSC-0041","status":"open","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-06-05","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-foreground-stack-game-pause-shell-vm-backed.md","status":"open","created_at":"2026-06-05","updated_at":"2026-06-05"}],"decisions":[],"plans":[],"lessons":[]} -{"type":"discussion","id":"DSC-0042","status":"in_progress","ticket":"real-render-worker-establishment","title":"Real Render Worker Establishment","created_at":"2026-06-06","updated_at":"2026-06-16","tags":["runtime","renderer","worker","concurrency","host","hal","architecture"],"agendas":[{"id":"AGD-0042","file":"AGD-0042-host-hardware-render-boundary-preparation.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-06"},{"id":"AGD-0043","file":"AGD-0043-real-render-worker-establishment.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-15"}],"decisions":[{"id":"DEC-0032","file":"DEC-0032-platform-layer-and-hardwarebridge-elimination.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-06","ref_agenda":"AGD-0042"},{"id":"DEC-0033","file":"DEC-0033-real-render-worker-contract.md","status":"accepted","created_at":"2026-06-15","updated_at":"2026-06-15","ref_agenda":"AGD-0043"}],"plans":[{"id":"PLN-0098","file":"PLN-0098-define-platform-facade-contracts.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0099","file":"PLN-0099-introduce-owned-render-submission-sink.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0100","file":"PLN-0100-migrate-local-render-publication-to-sink.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0101","file":"PLN-0101-remove-immediate-gfx-syscall-rendering.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0102","file":"PLN-0102-introduce-game2d-frame-composer-service.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0103","file":"PLN-0103-introduce-runtime-platform-and-testplatform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0104","file":"PLN-0104-migrate-vm-runtime-hostcontext-to-platform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0105","file":"PLN-0105-migrate-firmware-and-hub-to-platform-services.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0106","file":"PLN-0106-migrate-desktop-host-to-platform-services.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0107","file":"PLN-0107-migrate-remaining-platform-domains.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0108","file":"PLN-0108-migrate-tests-to-testplatform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0109","file":"PLN-0109-remove-hardwarebridge-and-update-specs.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0110","file":"PLN-0110-define-owned-rgba8888-frame-contract.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0111","file":"PLN-0111-define-read-only-render-resource-access.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0112","file":"PLN-0112-define-render-worker-errors-and-telemetry.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0113","file":"PLN-0113-implement-thread-safe-latest-wins-handoff.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0114","file":"PLN-0114-add-deterministic-render-worker-test-harness.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0115","file":"PLN-0115-implement-render-worker-controller-lifecycle.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0116","file":"PLN-0116-implement-fake-local-render-backend.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0117","file":"PLN-0117-integrate-runtime-submission-with-worker.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0118","file":"PLN-0118-add-stale-epoch-and-repeat-frame-behavior.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-16","ref_decisions":["DEC-0033"]},{"id":"PLN-0119","file":"PLN-0119-integrate-desktop-host-worker-presentation.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-16","ref_decisions":["DEC-0033"]},{"id":"PLN-0120","file":"PLN-0120-update-real-render-worker-specs.md","status":"open","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0121","file":"PLN-0121-final-worker-path-validation-and-hardening.md","status":"open","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0042","status":"in_progress","ticket":"real-render-worker-establishment","title":"Real Render Worker Establishment","created_at":"2026-06-06","updated_at":"2026-06-16","tags":["runtime","renderer","worker","concurrency","host","hal","architecture"],"agendas":[{"id":"AGD-0042","file":"AGD-0042-host-hardware-render-boundary-preparation.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-06"},{"id":"AGD-0043","file":"AGD-0043-real-render-worker-establishment.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-15"}],"decisions":[{"id":"DEC-0032","file":"DEC-0032-platform-layer-and-hardwarebridge-elimination.md","status":"accepted","created_at":"2026-06-06","updated_at":"2026-06-06","ref_agenda":"AGD-0042"},{"id":"DEC-0033","file":"DEC-0033-real-render-worker-contract.md","status":"accepted","created_at":"2026-06-15","updated_at":"2026-06-15","ref_agenda":"AGD-0043"}],"plans":[{"id":"PLN-0098","file":"PLN-0098-define-platform-facade-contracts.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0099","file":"PLN-0099-introduce-owned-render-submission-sink.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0100","file":"PLN-0100-migrate-local-render-publication-to-sink.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0101","file":"PLN-0101-remove-immediate-gfx-syscall-rendering.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0102","file":"PLN-0102-introduce-game2d-frame-composer-service.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0103","file":"PLN-0103-introduce-runtime-platform-and-testplatform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0104","file":"PLN-0104-migrate-vm-runtime-hostcontext-to-platform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0105","file":"PLN-0105-migrate-firmware-and-hub-to-platform-services.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0106","file":"PLN-0106-migrate-desktop-host-to-platform-services.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0107","file":"PLN-0107-migrate-remaining-platform-domains.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0108","file":"PLN-0108-migrate-tests-to-testplatform.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0109","file":"PLN-0109-remove-hardwarebridge-and-update-specs.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-15","ref_decisions":["DEC-0032"]},{"id":"PLN-0110","file":"PLN-0110-define-owned-rgba8888-frame-contract.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0111","file":"PLN-0111-define-read-only-render-resource-access.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0112","file":"PLN-0112-define-render-worker-errors-and-telemetry.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0113","file":"PLN-0113-implement-thread-safe-latest-wins-handoff.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0114","file":"PLN-0114-add-deterministic-render-worker-test-harness.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0115","file":"PLN-0115-implement-render-worker-controller-lifecycle.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0116","file":"PLN-0116-implement-fake-local-render-backend.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0117","file":"PLN-0117-integrate-runtime-submission-with-worker.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]},{"id":"PLN-0118","file":"PLN-0118-add-stale-epoch-and-repeat-frame-behavior.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-16","ref_decisions":["DEC-0033"]},{"id":"PLN-0119","file":"PLN-0119-integrate-desktop-host-worker-presentation.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-16","ref_decisions":["DEC-0033"]},{"id":"PLN-0120","file":"PLN-0120-update-real-render-worker-specs.md","status":"done","created_at":"2026-06-15","updated_at":"2026-06-16","ref_decisions":["DEC-0033"]},{"id":"PLN-0121","file":"PLN-0121-final-worker-path-validation-and-hardening.md","status":"open","created_at":"2026-06-15","updated_at":"2026-06-15","ref_decisions":["DEC-0033"]}],"lessons":[]} {"type":"discussion","id":"DSC-0038","status":"done","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0047","file":"discussion/lessons/DSC-0038-render-frame-packet-boundary/LSN-0047-typed-render-submissions-preserve-domain-boundaries.md","status":"done","created_at":"2026-06-04","updated_at":"2026-06-04"}]} {"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} {"type":"discussion","id":"DSC-0034","status":"done","ticket":"system-os-domain-facades","title":"Agenda - SystemOS Domain Facades","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","services","api-surface","lifecycle","fs"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0043","file":"discussion/lessons/DSC-0034-system-os-domain-facades/LSN-0043-systemos-domain-facades.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} diff --git a/discussion/workflow/plans/PLN-0120-update-real-render-worker-specs.md b/discussion/workflow/plans/PLN-0120-update-real-render-worker-specs.md index b87f770e..2392d491 100644 --- a/discussion/workflow/plans/PLN-0120-update-real-render-worker-specs.md +++ b/discussion/workflow/plans/PLN-0120-update-real-render-worker-specs.md @@ -2,7 +2,7 @@ id: PLN-0120 ticket: real-render-worker-establishment title: Update Real Render Worker Specs -status: open +status: done created: 2026-06-15 completed: ref_decisions: [DEC-0033] diff --git a/docs/specs/runtime/04-gfx-peripheral.md b/docs/specs/runtime/04-gfx-peripheral.md index 1ee1e924..05680535 100644 --- a/docs/specs/runtime/04-gfx-peripheral.md +++ b/docs/specs/runtime/04-gfx-peripheral.md @@ -73,6 +73,24 @@ Color values in the runtime, HAL, host-facing framebuffer, and GFX ABI are logical RGBA8888 values. RGB565 is not a supported runtime framebuffer, palette, host presentation, or compatibility contract. +### Published owned frame + +The canonical worker-published frame value is `OwnedRgba8888Frame`. + +`OwnedRgba8888Frame` contains: + +- the logical `FrameId`; +- render ownership metadata; +- width and height in pixels; +- stride in pixels; +- an owned `Vec` containing packed RGBA8888 pixels in canonical RGBA + channel order. + +The pixel vector is owned by the published frame. Consumers may copy it into a +host upload buffer, retain it as the latest published frame, or repeat it for a +host redraw. Consumers MUST NOT interpret the frame as a native texture, +swapchain image, window handle, or host GPU resource. + --- ## 3. Double Buffering @@ -134,6 +152,11 @@ to the logical/runtime side before handoff, or to an owning service. They MUST NOT require the render consumer to hold mutable VM, `Hardware`, `Gfx`, or `FrameComposer` references. +Read-only resource APIs expose compact lookup by ID. They do not expose mutable +bank state, `Arc` ownership as part of the contract, copies of whole banks, or +snapshot payloads. The implementation may choose its internal sharing mechanism, +but the render boundary contract is ID-based read-only access. + Local host implementations may keep a concrete hardware object internally as a platform implementation detail. That object is not part of the runtime-facing render boundary; the boundary is the typed platform service set. @@ -155,6 +178,12 @@ latest-wins semantics: The consumer status is telemetry. It is not a semantic ACK to the VM. +The real render worker consumes owned `RenderSubmission` values from this +single-slot handoff and publishes owned `OwnedRgba8888Frame` values. The +producer path MUST remain non-blocking with respect to worker rasterization and +host present. A slow worker can cause replacement/drop telemetry, but it MUST +NOT create an unbounded queue or stall VM logical frame production. + ### 4.4 Frame pacing Game logical frames are paced by the runtime frame scheduler, not by render @@ -170,6 +199,10 @@ sequential. The render consumer may repeat the last valid frame, and telemetry records the overrun/repeat. The VM MUST NOT produce catch-up frames to skip from frame `N` to frame `N+k`. +Repeating a frame means reusing the latest published `OwnedRgba8888Frame` +without recomposing, rerunning VM code, or consuming a new submission. Repeat +behavior is presentation cadence behavior, not guest-visible execution. + ### 4.5 AppMode policy Render execution policy is explicit by pipeline/AppMode: @@ -231,6 +264,17 @@ Minimum render telemetry includes: - last produced, consumed, presented, dropped, and error frame IDs; - active render epoch. +### 4.8 Shutdown and typed failures + +Render worker shutdown is bounded and observable. A shutdown request MUST +wake a waiting worker, discard pending submissions that will not be consumed, +and either join within the configured timeout or report a typed shutdown +failure. + +Worker backend failures, sink publication failures, stale ownership discards, +panic capture, and shutdown timeout are typed render worker outcomes. They are +recorded through telemetry and diagnostics; they do not become VM-visible ACKs. + --- ## 5. PROMETEU Graphical Structure diff --git a/docs/specs/runtime/09-events-and-concurrency.md b/docs/specs/runtime/09-events-and-concurrency.md index 200ad704..9337ad90 100644 --- a/docs/specs/runtime/09-events-and-concurrency.md +++ b/docs/specs/runtime/09-events-and-concurrency.md @@ -100,7 +100,34 @@ Important properties: - no execution occurs outside the frame loop; - frame structure remains observable for host tooling and host-owned certification. -## 7 Determinism and Best Practices +## 7 Render Worker Concurrency + +The render worker is not a machine-visible event source and does not introduce +guest callbacks. It is an implementation-side consumer of closed render +submissions. + +The render worker handoff uses single-slot latest-wins semantics: + +- a producer publishes at most one pending owned `RenderSubmission`; +- a newer submission replaces an older unconsumed pending submission; +- replacement is counted as telemetry; +- the producer does not wait for worker rasterization or host present; +- the worker takes ownership of the submission it consumes. + +The worker publishes `OwnedRgba8888Frame` values. Each published frame owns its +RGBA8888 pixel vector and carries frame and ownership metadata. Repeating a +frame reuses the latest published owned frame and does not execute guest code +or recompose the frame. + +Render resources reachable from a submission are resolved through read-only +ID-based access. The worker MUST NOT hold mutable VM state, mutable `Hardware`, +mutable `Gfx`, or a live mutable `FrameComposer` as its cross-thread contract. + +Shutdown is explicit and bounded. A shutdown request wakes a waiting worker, +causes pending work that will not be consumed to be discarded, and reports a +typed failure if the worker cannot join within the configured timeout. + +## 8 Determinism and Best Practices PROMETEU encourages: @@ -115,7 +142,7 @@ PROMETEU discourages: - hidden timing channels; - ambiguous out-of-band execution. -## 8 Relationship to Other Specs +## 9 Relationship to Other Specs - [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine lifecycle and scheduling behavior. - [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines observability and diagnostics surfaces. diff --git a/docs/specs/runtime/11-portability-and-cross-platform-execution.md b/docs/specs/runtime/11-portability-and-cross-platform-execution.md index 845e74d8..82c96016 100644 --- a/docs/specs/runtime/11-portability-and-cross-platform-execution.md +++ b/docs/specs/runtime/11-portability-and-cross-platform-execution.md @@ -118,6 +118,8 @@ Hardware differences: The graphics system: - produces typed logical render submissions that render to RGBA8888 output +- may consume Game submissions through a render worker that publishes owned + `OwnedRgba8888Frame` values - uses an indexed palette - does not depend on a specific GPU @@ -126,7 +128,8 @@ The platform layer: - exposes typed service facades for render submission, render backend execution, Game 2D composition, input, audio, assets, and telemetry - consumes closed render submissions through a render-surface implementation -- transports published RGBA8888 output into a host presentation surface without +- transports published RGBA8888 output or worker-published + `OwnedRgba8888Frame` pixels into a host presentation surface without injecting host-owned debug overlay pixels - is the runtime-facing portability boundary; runtime and firmware code must not depend on a monolithic hardware bridge or on a concrete hardware aggregate @@ -135,6 +138,12 @@ The host presentation layer MUST treat RGBA8888 as the canonical logical framebuffer format. RGB565 conversion is not part of the normal host presentation contract. +Native upload and present belong to the host event loop. The render worker MUST +NOT own or require a native window, swapchain, `pixels` surface, SDL texture, or +host GPU texture as part of its contract. The worker output is an owned +RGBA8888 frame; the host decides how to upload that frame to the native +presentation API for the current platform. + Host presentation SHOULD be driven by published render submissions and explicit host-owned invalidation, not by perpetual redraw polling. diff --git a/docs/specs/runtime/README.md b/docs/specs/runtime/README.md index a2d3ae67..f8ee55ef 100644 --- a/docs/specs/runtime/README.md +++ b/docs/specs/runtime/README.md @@ -56,6 +56,13 @@ input, audio, assets, and telemetry. A concrete local hardware aggregate may exist inside a host or test platform, but it is not the normative runtime-facing contract. +The real render worker contract is documented across the GFX, events, and +portability chapters. `04-gfx-peripheral.md` defines the render submission and +`OwnedRgba8888Frame` publication contract, `09-events-and-concurrency.md` +defines latest-wins handoff and bounded shutdown behavior, and +`11-portability-and-cross-platform-execution.md` defines the split between +worker-owned RGBA8888 frame production and host-owned native upload/present. + ## Document Functions - `normative`: defines the technical contract, expected behavior, or implementation-facing surface.