Work from
When loading progress controls memory lifetime
Why reaching 100% too early was more than a display bug.
In a staged model loader, reaching 1.0 triggered cleanup of the mapped model data. An inaccurate progress total could therefore release data that a later backend context still needed.
The accounting originally followed tensor requests. The actual loading work followed tensors retained by finalized backend contexts. Those are different sets of work.
One physical GGUF weight can appear in more than one context. Each retained occurrence needs to be counted because each participates in loading. Conversely, a synthetic tensor with no backing GGUF weight must not extend the mapping’s lifetime.
Count what the loader will visit
The mesh-llm change recomputes the total from finalized contexts, following the same traversal as the load operation. It counts an occurrence only when it resolves to a real GGUF weight.
There is a separate path to preserve: quantization initializes mappings before model contexts exist. That path keeps its weight-map fallback rather than interpreting an empty context list as no work.
Intermediate progress stays below 1.0. Exact completion is reserved for the transition after the final retained bytes have loaded, and cleanup happens once. The clamp supports correct accounting; it cannot replace it.
Test the lifetime, not just the total
The regression loads two contexts in sequence. After the first, progress must remain incomplete and the mapping must stay alive. After the second, completion and cleanup happen exactly once. A synthetic tensor and a post-completion context exercise the cases that a simple byte-total assertion misses.
Review also caught that the regression needed to be wired into the supported native test lane. A test file outside the normal execution path offers little protection.
Here, the progress callback also acted as a resource-lifetime signal. Its meaning had to match the work still using the resource, including work in a later context.