accept real render worker decision

This commit is contained in:
bQUARKz 2026-06-15 12:31:01 +01:00
parent 1022750c12
commit cafbc42018
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
3 changed files with 299 additions and 3 deletions

View File

@ -1,8 +1,8 @@
{"type":"meta","next_id":{"DSC":43,"AGD":44,"DEC":33,"PLN":110,"LSN":49,"CLSN":1}}
{"type":"meta","next_id":{"DSC":43,"AGD":44,"DEC":34,"PLN":110,"LSN":49,"CLSN":1}}
{"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-15","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":"open","created_at":"2026-06-06","updated_at":"2026-06-06"}],"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"}],"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"]}],"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-15","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"]}],"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"}]}

View File

@ -2,7 +2,7 @@
id: AGD-0043
ticket: real-render-worker-establishment
title: Real Render Worker Establishment
status: open
status: accepted
created: 2026-06-06
resolved:
decision:

View File

@ -0,0 +1,296 @@
---
id: DEC-0033
ticket: real-render-worker-establishment
title: Real Render Worker Contract
status: accepted
created: 2026-06-15
accepted:
agenda: AGD-0043
plans: []
tags: [runtime, renderer, worker, concurrency, host, hal, architecture]
---
## Status
Decision accepted from agenda `AGD-0043`.
This is the normative contract for implementation plans that establish the real render worker for Prometeu.
## Contexto
`DEC-0031` established the VM/render boundary around closed render submissions, single-slot handoff, frame pacing, AppMode policy, ownership epoch, and render telemetry.
`DEC-0032` and plans `PLN-0098` through `PLN-0109` prepared the platform boundary required for a real worker:
- `HardwareBridge` was removed from production/runtime contracts;
- `RuntimePlatform` became the runtime-facing platform service boundary;
- `RenderSubmissionSink` accepts owned render submissions;
- `Game2DFrameComposer` separates logical Game 2D frame closure from backend rendering;
- `gfx2d.*` and `gfxui.*` syscalls buffer commands instead of mutating `Gfx` immediately;
- firmware, Hub, runtime, host desktop, and tests moved to platform services;
- specs now state that worker/render consumers must not depend on `&mut Hardware`, `&mut Gfx`, live `FrameComposer`, or mutable VM state.
The remaining work is to replace the cooperative/local `LocalRenderWorker` proof with a real worker that drains render submissions without blocking VM progress and publishes complete RGBA8888 frames for host presentation.
## Decisao
Prometeu SHALL implement the real render worker as a runtime-owned worker controller with host-provided backend integration.
The worker controller SHALL live in `prometeu-system`, near `RenderManager`, because `RenderManager` owns AppMode policy, ownership/epoch, latest-wins handoff semantics, and render telemetry.
Shared contract types and traits SHALL live in `prometeu-hal` when they cross runtime/host/driver boundaries. Local/default and test implementations SHALL live in `prometeu-drivers` or host crates as appropriate.
The worker SHALL consume owned `RenderSubmission` values through a thread-safe single-slot latest-wins handoff. The VM producer MUST NOT block on rasterization, publication, presentation, or worker completion.
The worker SHALL publish owned RGBA8888 frames, not native window/swapchain objects. The initial shared frame type SHALL be `OwnedRgba8888Frame` in `prometeu-hal`.
The host event loop SHALL remain responsible for native window upload/present. The worker MUST NOT depend on winit, pixels, SDL, swapchain handles, native textures, or host window APIs.
The agenda may be implemented through multiple plans, but `AGD-0043` is complete only when the worker functions on the real host path, not merely in fake/local tests.
## Rationale
The real worker must prove the architecture promised by `DEC-0031`: VM execution and render consumption can proceed independently without crossing mutable runtime state into the renderer.
Putting the controller in `prometeu-system` keeps render policy in the same layer that already owns frame lifecycle, ownership epochs, latest-wins behavior, and telemetry. Putting it only in the host would make the contract desktop-specific and harder to test without a window.
Publishing an owned RGBA8888 frame keeps the worker host-agnostic. The host can upload that frame to any native presentation backend while the worker stays testable through ordinary memory comparisons.
Using a single explicit pending slot directly models the accepted backpressure rule. Channels or queues can accidentally preserve history or block producers. The runtime contract is not "render every produced frame"; it is "the latest complete submission wins and the VM does not wait for the consumer."
Read-only bank access by id preserves the no-copy resource boundary. Banks are render resources, not payloads to duplicate into each submission. The worker should resolve resource ids through a compact read-only interface without taking `&mut Hardware`, `&mut Gfx`, a live `FrameComposer`, or VM state.
## Invariantes / Contrato
### 1. Runtime controller ownership
The worker controller MUST live in `prometeu-system`.
`RenderManager` SHALL remain the authority for:
- AppMode render policy;
- ownership/epoch;
- latest-wins handoff semantics;
- render telemetry;
- stale submission discard;
- shutdown/request-stop coordination visible to runtime policy.
Host crates MAY instantiate or wire the controller, but they MUST NOT redefine worker semantics.
### 2. Shared HAL contracts
`prometeu-hal` SHALL define shared types/traits that cross the runtime/host/driver boundary.
At minimum, the worker work SHALL introduce:
- `OwnedRgba8888Frame`;
- compact read-only render resource access contracts for bank lookup by id;
- typed worker/backend error contracts where they are shared across crates.
### 3. Owned RGBA8888 frame publication
`OwnedRgba8888Frame` SHALL represent a completed logical frame ready for host upload/present.
It MUST include:
- `FrameId`;
- render ownership/epoch metadata;
- width;
- height;
- `stride_pixels`;
- owned RGBA8888 pixel data as `Vec<u32>`.
The pixel data MUST use the canonical RGBA8888 raw value contract already used by the runtime specs. It MUST NOT be described as native-endian host pixels, native texture data, or backend-specific surface memory.
Repeating the last valid frame SHALL mean reusing the last published `OwnedRgba8888Frame`, not recomposing from VM state or live composer state.
### 4. Thread-safe latest-wins handoff
The real handoff SHALL be a thread-safe single-slot latest-wins structure.
The initial implementation SHOULD use an explicit slot based on `Mutex<Option<RenderSubmission>> + Condvar`.
Producer behavior:
- publish replaces the pending submission if one already exists;
- replacement increments drop/replacement telemetry;
- publish MUST NOT wait for rasterization or present;
- publish MUST wake the consumer when needed.
Consumer behavior:
- wait for pending submission or shutdown;
- take ownership of the latest pending submission;
- leave the pending slot empty while work is in flight;
- discard stale work before publication if ownership/epoch no longer matches.
### 5. Pending and in-flight are separate
The worker MUST distinguish pending submissions from in-flight work.
Once the worker takes a submission, that submission is in flight. New producer submissions may replace the pending slot while the worker is still rasterizing the previous in-flight submission.
Before publishing an in-flight frame, the worker MUST check:
- stop/shutdown state;
- render owner;
- render epoch/generation.
If the frame is stale, the worker MUST discard it and update telemetry. It MUST NOT publish stale pixels.
### 6. Shutdown is bounded
Worker shutdown MUST be bounded and observable.
The shutdown timeout MUST be configurable. The initial default SHOULD be `250ms`.
On shutdown:
- stop state MUST be signaled;
- the worker MUST be woken if it is waiting;
- join MUST complete within the configured bound or return/report a `ShutdownTimeout` failure;
- in-flight work MAY finish rasterization, but MUST NOT publish after stop/epoch invalidation says it is stale.
### 7. Read-only bank access by id
The render backend SHALL resolve render resources through a compact read-only interface by stable ids.
Banks are read-only by definition during render consumption. The worker MUST NOT copy entire banks into submissions. The worker MUST NOT require bank snapshots. The worker MUST NOT require `Arc` as part of the public contract.
Implementation may use any internal storage strategy that satisfies the public contract, but the render worker contract is ids plus read-only access.
Resource installation, mutation, and residency changes remain outside in-flight render consumption.
### 8. Backend and host presentation split
The worker backend SHALL consume `RenderSubmission` plus read-only resource access and produce `OwnedRgba8888Frame`.
The host event loop SHALL upload/present the latest published frame through its native API.
The worker MUST NOT call native window present directly unless a future decision revises the host presentation model.
### 9. Typed error model
The worker work SHALL introduce a minimal typed error model, such as `RenderWorkerError`.
The error model MUST cover at least:
- backend unavailable;
- render failed;
- publish/present handoff failed;
- shutdown timeout;
- stale submission discarded;
- worker panic captured as internal failure.
Panic containment MAY remain as a safety net. Ordinary worker/backend failure MUST NOT rely on panic as the normal reporting path.
### 10. Telemetry
Worker telemetry SHALL preserve and extend the existing render telemetry model.
At minimum, telemetry SHOULD include:
- submissions produced;
- pending submissions replaced/dropped;
- submissions consumed;
- frames published/presented;
- stale submissions discarded;
- render failures;
- repeated-frame count;
- shutdown timeout count.
Telemetry MUST NOT change VM semantics.
### 11. Test contract
The worker contract MUST be proven without a native window.
Tests SHALL use deterministic synchronization primitives such as barriers and condvars, not timing sleeps as the primary proof mechanism.
The test matrix MUST prove:
- VM producer does not block when worker rasterization is held;
- latest-wins replacement occurs while a frame is in flight;
- stale owner/epoch prevents publication;
- shutdown is bounded;
- typed errors and telemetry are emitted;
- repeat uses the last published `OwnedRgba8888Frame`;
- fake/local backend behavior matches the contract before desktop integration.
### 12. Final scope
The implementation MAY be split into multiple plans.
However, the agenda is not complete until the real host path uses the worker. A fake/local backend is required for contract tests, but it is not sufficient as the final state of `AGD-0043`.
## Impactos
### Spec
Runtime specs must document:
- `OwnedRgba8888Frame`;
- the thread-safe single-slot latest-wins worker handoff;
- the worker/host presentation split;
- read-only bank access by id;
- shutdown and typed error behavior;
- telemetry expectations.
### Runtime
`prometeu-system` must add the worker controller and integrate it with `RenderManager`.
The VM tick path must submit render work without blocking on worker consumption.
### HAL
`prometeu-hal` must expose shared worker contracts:
- owned RGBA8888 frame type;
- render resource read-only access traits;
- worker/backend error types as needed.
### Drivers
`prometeu-drivers` must provide fake/local implementations suitable for deterministic tests and non-window integration.
Concrete local rendering may continue to use existing GFX machinery internally, but must expose the worker-facing contract without leaking `&mut Hardware`, `&mut Gfx`, or live `FrameComposer`.
### Host
The desktop host must integrate the real worker path and upload/present the latest published `OwnedRgba8888Frame` through its native window backend.
The host owns native presentation; the worker owns render consumption and frame publication.
### Tests
Tests must cover concurrency behavior deterministically and must include final host-path integration evidence.
## Referencias
- `AGD-0043`: Real Render Worker Establishment.
- `AGD-0042`: Host Hardware and Render Boundary Preparation.
- `DEC-0031`: VM and Render Parallel Execution Boundary.
- `DEC-0032`: Platform Layer and HardwareBridge Elimination.
- `LSN-0048`: Render Workers Need a Closed Packet Contract.
- `docs/specs/runtime/04-gfx-peripheral.md`.
- `docs/specs/runtime/11-portability-and-cross-platform-execution.md`.
## Propagacao Necessaria
Create implementation plans before editing specs or code.
Recommended plan sequence:
1. define `OwnedRgba8888Frame`, read-only bank access contracts, and worker error types in HAL;
2. introduce the thread-safe latest-wins handoff and deterministic fake/local worker tests;
3. implement worker controller lifecycle, stop token, bounded shutdown, pending/in-flight separation, and telemetry in `prometeu-system`;
4. implement fake/local backend that consumes `RenderSubmission` and produces `OwnedRgba8888Frame`;
5. integrate runtime render submission path with the worker without blocking VM ticks;
6. add stale owner/epoch discard and repeat-last-published-frame behavior;
7. integrate desktop host upload/present from the latest published `OwnedRgba8888Frame`;
8. update specs and final validation tests.
## Revision Log
- 2026-06-15: Initial decision draft generated from accepted `AGD-0043`.