Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...

    A durable record of the scene hitting the refinement BYTE ceiling.

    Surfaced on __luxarDebug.getState().refinementResidency so a capture tool can refuse a scene that stopped short (#2508): the ladder's terminal state is 100% of every node, so a scene that declined is showing a partial one, and WHICH nodes won the remaining headroom is not deterministic. Before this, the only signal was a single console warning, which nothing downstream reads.

    BYTE CEILING ONLY. A density-cap refusal never reaches the reporter — it is camera-dependent, non-sticky across runs, and the density gate's own to report (see RefinementResidencyBudget.admit) — so it is absent here by design. A node deferred on density is still going to refine when the user zooms in; a node declined on bytes is not.

    CUMULATIVE FOR THE LIFE OF THE LOADER, WITH NO RESET, ON PURPOSE. THIS IS THE CANONICAL STATEMENT of that contract; the other places it matters (the debug snapshot field, core/app/debug/capture-readiness.ts, the two READMEs) say it in one sentence and point here. The snapshot's OTHER memory-ceiling signal, gpuPool.byteBudgetEvictions, is governed by the same contract, because the GPU buffer pool is built and thrown away with the same SceneLoader.

    Once present this record stays present until that loader goes away, so it says "refinement hit the ceiling at some point while this scene was loaded", not "the scene is truncated right now" — a scene that stopped and then refined fully after a view change still carries it. That is the answer a capture tool wants: refinement order is path-dependent, so the run that hit the ceiling settled on a composition the next run would not reproduce. A dataset switch builds a fresh loader (SceneLoaderManager.createLoaderAsync) and therefore a fresh reporter and a fresh pool, so the next scene starts from a clean record with no page reload; do not clear either within a loader's life.

    interface RefinementResidencyStop {
        reason: RefinementAdmissionReason;
        residentBytes: number;
        budgetBytes: number;
        firstPath: string;
        declinedPathCount: number;
        declinedPaths: string[];
    }
    Index

    The FIRST refusal's reason — over-budget or next-rung-would-exceed. Named in the capture-readiness message because the two are the difference between "already past the ceiling" and "it fitted, but one more rung would not have", which is the difference between re-authoring the ladder and nudging the budget.

    residentBytes: number

    Tracked sweep-loader bytes at the moment of that first refusal.

    budgetBytes: number

    The ceiling that first refusal was measured against.

    firstPath: string

    The path that hit the ceiling first.

    declinedPathCount: number

    DISTINCT paths refused since the scene loaded — never the truncated length of declinedPaths. The budget is rebuilt per refinement run while the reporter lives for the scene, so a parked path re-declines on every run and must not be counted twice either.

    declinedPaths: string[]

    First-seen-order sample of the declined paths, capped at RESIDENCY_DECLINED_PATH_SAMPLE. Diagnostic only — read declinedPathCount for the magnitude.