--- id: DEC-0021 ticket: scene-bank-glyph-runtime-binding-leak title: Scene Bank glyph dependencies MUST bind by asset_id, not runtime slot status: in_progress created: 2026-04-24 accepted: 2026-04-24 agenda: AGD-0029 plans: [PLN-0040, PLN-0041, PLN-0042] tags: [gfx, runtime, asset, scene, glyph, format, architecture] --- ## Status Accepted on 2026-04-24. ## Contexto The current `SCENE` binary payload serializes `glyph_bank_id` per layer and the runtime uses that serialized value as the operational key to resolve the resident glyph bank during rendering. That design leaks runtime residency topology into a cold asset format. A scene asset is therefore coupled to whichever glyph slot layout happened to exist when the payload was authored, which violates the intended separation between: - cold asset description; - runtime residency and slot assignment; - frame-time composition. The repository discussion in `AGD-0029` concluded that this contract is incorrect and must be replaced. ## Decisao The `SCENE` asset contract MUST stop serializing runtime glyph slot identifiers. From this decision forward: 1. Each scene layer MUST declare its glyph dependency by `AssetId`. 2. `SceneBank` MUST NOT carry a runtime glyph slot id as part of its canonical loaded model. 3. The runtime MUST resolve `AssetId -> glyph slot` through runtime-owned residency state, not through scene payload bytes interpreted as slot ids. 4. The runtime MUST maintain an internal reverse index `AssetId -> slot` for committed glyph assets. 5. The lookup mechanism MAY become a public API later, but in this stage it MUST remain internal. 6. The `SCENE` payload field used for the glyph dependency MUST widen to carry canonical `AssetId = i32`. 7. The scene payload MUST keep the dependency attached directly to each layer; no shared dependency table is introduced in this decision. 8. No compatibility layer and no format version migration are introduced in this stage. ## Rationale The previous contract was wrong at the boundary level, not only at the implementation level. Why this decision is correct: - runtime slot ids are operational state and MUST remain runtime-owned; - `AssetId` is the stable cold identity already used by the asset system; - resolving dependencies at runtime preserves freedom of preload, commit, relocation, and slot reuse; - a reverse index gives the runtime the correct primitive for both internal use and possible future API exposure; - keeping the dependency per layer is the lowest-risk migration path and avoids speculative structure growth. This decision deliberately prefers a clean contract over temporary compatibility because the current behavior is architecturally invalid. ## Invariantes / Contrato ### Canonical scene contract - A `SCENE` asset MUST describe glyph dependencies in cold asset terms only. - A `SCENE` asset MUST NOT encode runtime slot topology. - A scene layer MUST own exactly one glyph dependency reference. - That dependency reference MUST be serialized as `AssetId` and MUST use `i32` width. ### Runtime residency contract - The asset manager MUST own the authoritative mapping from committed glyph residency to slot. - The runtime MUST maintain a reverse index from committed glyph `AssetId` to glyph slot. - The reverse index MUST be updated whenever glyph preload or glyph commit changes slot ownership. - The reverse index MUST be treated as internal runtime state in this stage. ### Bind-time and draw-time contract - `bind_scene` MUST validate that every glyph dependency referenced by the target scene resolves to a currently committed glyph slot. - If any dependency cannot be resolved during `bind_scene`, the machine MUST fail fatally and emit a clear log describing the missing dependency. - Render-time composition MAY consult the reverse index again while drawing a layer instead of relying on a frozen slot snapshot. - If a dependency becomes unresolved during draw/composition, the machine MUST fail fatally and emit a clear log describing the missing dependency. - The runtime MUST NOT continue scene composition after a missing dependency is detected at bind time or draw time. ### Error semantics - `ERROR_MISSING_DEPENDENCIES` is not part of the accepted contract. - Missing scene glyph dependencies are not passive operational rejections in the accepted model. - Missing scene glyph dependencies MUST escalate as fatal machine errors with explicit logging. ### Non-goals for this decision - This decision does NOT expose the reverse lookup as a public API yet. - This decision does NOT introduce payload compatibility with the old serialized `glyph_bank_id`. - This decision does NOT introduce a dependency table shared across scene layers. - This decision does NOT define the later public guest ABI for querying `asset_id -> slot`. ## Impactos ### Spec - The `SCENE` binary payload specification MUST be updated to replace per-layer runtime slot ids with per-layer `AssetId`. - The payload layout MUST reflect widened field width for `AssetId = i32`. - Runtime/spec text that implies scene glyph dependencies are operational status returns rather than fatal errors MUST be corrected. ### Runtime - `SceneLayer` and related scene/cache structures MUST stop carrying canonical runtime glyph slot ids. - The asset manager MUST maintain the reverse glyph residency index. - `bind_scene` MUST validate scene glyph dependencies against the reverse index and fatalize on absence. - The draw path MUST resolve or revalidate layer dependencies against runtime residency and fatalize on absence. ### Host - Fatal machine logging for missing scene glyph dependencies MUST be clear enough to identify: - the scene being bound or drawn; - the layer involved; - the missing glyph dependency `AssetId`. ### Tooling - Scene encoders, packers, fixtures, and stress tools MUST serialize per-layer glyph dependency as `AssetId`, not runtime slot id. - Existing tests and fixtures that publish `glyph_bank_id` in `SCENE` payloads MUST be rewritten. ## Referencias - Agenda: `AGD-0029-scene-bank-glyph-runtime-binding-leak.md` - Related runtime area: `DSC-0025` lesson on scene/canonical/cache separation - Related asset identity context: `DSC-0018` lesson on asset load asset id int contract ## Propagacao Necessaria - Update the canonical `SCENE` payload layout in specs. - Update HAL scene types to reflect `AssetId` dependency semantics. - Update asset decode/encode logic for `SCENE`. - Introduce and maintain reverse glyph residency index in the asset manager. - Update `FrameComposer` bind path and draw path to use runtime dependency resolution and fatal logging. - Rewrite affected tests, fixtures, and tooling payload writers. - Create an execution plan before spec/code changes. ## Revision Log - 2026-04-24: Initial accepted decision derived from AGD-0029. - 2026-04-24: Moved to in_progress after plan family creation (`PLN-0040`, `PLN-0041`, `PLN-0042`).