--- id: PLN-0125 ticket: perf-async-background-work-lanes-for-assets-and-fs title: Asset Backlog and Stable Slot Handles status: done created: 2026-06-28 completed: ref_decisions: [DEC-0034] tags: [perf, asset, async, runtime] --- # PLN-0125 - Asset Backlog and Stable Slot Handles ## Briefing `DEC-0034` changes asset loading from request-owned thread spawning to a serial backlog keyed by `bank_type/slot`. Handles become stable bank-slot observers with separate resident slot state and request state. ## Decisions de Origem - `DEC-0034` - Async Work Lane and Asset Backlog Contract. ## Alvo Refactor `AssetManager` so asset requests are tracked by target bank slot, deduplicated/superseded by target, and observable through stable handles. ## Escopo Included: - Stable handle structure with `bank_type`, `slot`, `slot_state`, and `request_state`. - Backlog keyed by `bank_type/slot`. - Already-resident fast path. - Superseding for queued and active requests. - Main-lane commit/install boundary. Fora de Escopo: - Public backlog syscall wiring. - Percentile telemetry. - FS public API. ## Plano de Execucao ### Step 1 - Model Slot Handles **What:** Replace transient load-operation assumptions with stable bank-slot handle state. **How:** Introduce structures equivalent to: ```text handle: bank_type, slot slot_state: loaded_asset_id, resident_state, slot_generation request_state: requested_asset_id, request_generation, state, position, progress ``` **Files:** `crates/console/prometeu-drivers/src/asset.rs` and HAL asset types if public type definitions belong there. ### Step 2 - Key Backlog by Target **What:** Ensure at most one current request per `bank_type/slot`. **How:** Add a target index from `(bank_type, slot)` to current request generation/handle state. Enqueue only when the target does not already have the same resident asset and no newer request supersedes it. **Files:** `crates/console/prometeu-drivers/src/asset.rs`. ### Step 3 - Implement Already-Resident Fast Path **What:** Return a ready handle immediately when the requested asset already resides in the target slot. **How:** Compare requested `asset_id` with the target `slot_state.loaded_asset_id` and resident validity before creating a queued job. **Files:** `crates/console/prometeu-drivers/src/asset.rs`. ### Step 4 - Implement Superseding **What:** New request for the same target supersedes previous queued or active request. **How:** Remove queued older request immediately. For active work, update target generation so the old result is discarded if it cannot stop cooperatively. **Files:** `crates/console/prometeu-drivers/src/asset.rs`; async lane module from `PLN-0124`. ### Step 5 - Preserve Main-Lane Commit **What:** Keep install/commit into resident banks on the main runtime lane. **How:** Async lane produces staged materialized result. `asset.commit(handle)` installs only when the request generation is current and ready. **Files:** `crates/console/prometeu-drivers/src/asset.rs`; VM runtime dispatch if commit behavior changes. ## Criterios de Aceite - [ ] No asset load spawns an OS thread per request. - [ ] At most one request exists per `bank_type/slot`. - [ ] Same-target newer request supersedes older queued request. - [ ] Same-target newer request prevents active stale result from installing. - [ ] Already-resident target returns ready handle without backlog entry. - [ ] Handles remain queryable for empty, queued, active, ready, committed, canceled, superseded, and error states. ## Tests / Validacao - Unit tests for handle state transitions. - Unit tests for target-keyed superseding. - Unit tests for already-resident fast path. - Integration test for stale active result discard. - Existing asset load/commit tests must continue passing. ## Riscos - Confusing handle identity with request generation. - Installing a stale async result after superseding. - Losing compatibility with existing `asset.status/commit/cancel` behavior.