Skip to main content

performance-profiling

Diagnose or improve LunCoSim FPS, physics time, periodic stalls, Builder versus View differences, terrain/render cost, or Tracy captures. Use when performance must improve architecturally without changing BigSpace, substeps, shadows, terrain quality, or image fidelity.

Source facts

Repository
LunCoSim/lunco-sim
Last source activity
October 15, 2026 at 22:31
Detected SKILL.md language
English
Stars
107
Forks
21

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
performance-profiling
description
Diagnose or improve LunCoSim FPS, physics time, periodic stalls, Builder versus View differences, terrain/render cost, or Tracy captures. Use when performance must improve architecturally without changing BigSpace, substeps, shadows, terrain quality, or image fidelity.
# Performance profiling: measure the owner, then remove avoidable work Read the current handover in [`docs/reviews/open-400fps-performance-handover.md`](../../docs/reviews/open-400fps-performance-handover.md) before changing code. A status-bar FPS number is a symptom, not an attribution. ## Required separation - Run one production session that you own for the product FPS number, launched from the task checkout on a verified free API port. Do this even if another user's or agent's session is active; never control, stop, restart, or change the scene in a pre-existing session. Report concurrent GPU/CPU workloads and classify affected numbers as contention-affected, not clean acceptance. Do not use Tracy's instrumented number as acceptance evidence. Record the admitted Twin source revision and require its expected authored verdict before comparing completed-mission windows. A tick threshold or zero process exit does not prove acceptance. Exclude source/API errors, and require readiness and diagnostics to pass for the measured cohort. - Run a separate Tracy build/capture using the adjacent `../tracy` checkout; start `tracy-capture` before the production binary and inspect the settled window, not only startup. Check the profiler listener and connection against the owned PID with `ss -ltnp`/`ss -tnp`. A concurrent Tracy client can occupy 8086 and move the owned app to the next port; pass that port with `tracy-capture -p`. A capture from another process is not evidence for the task scene. A zero collector exit does not prove capture integrity. Compare the saved file size with the collector's reported compressed payload plus native file framing, and require a successful native CSV export before using its zones. `FileWrite::GetCompressionStatistics` excludes the six-byte file header and four-byte length per compressed block; these bytes are present on disk. A size mismatch, parser failure or stalled export leaves that capture unusable. A reported instrumentation failure also makes the requested window incomplete. Keep hot zone names bounded: step ids, timestamps, and measured durations must not be span fields when the Tracy layer uses those values as source-location identity. Inspect the exact owned exporter process before terminating an unsuccessful read; do not restart a still-running export solely because an observation timed out. Check disk space while the owned app is live as well as after it exits. Native capture writing can overlap runtime allocations, and the collector can report success despite a truncated file. Native unwrapped CSV rows are grouped by source location; sort by `ns_since_start` before reconstructing chronological phases or transitions. - Compare Builder and View with the same scene, camera, rendering-quality settings, physics substeps, shadow settings, and terrain assets. A Builder- only cost usually means an editor observer, rebuild, projection, or UI path, not that physics needs a different global timestep. - For a settled DEM quality window, require `TerrainLodStatus.stream.wanted == resident`, `stream.pending == 0`, `derived.active == false`, `derived.pending == 0`, and `derived.ready == derived.total`. Record those owner facts before and throughout the window alongside camera and quality inputs. Simulation readiness alone does not certify optional visual-map preparation. Keep this measurement gate out of simulation admission. Audit a surface camera with `world_pos` and `world_rotation` in the active simulation frame; `visual_foci` reports composed root coordinates, which move with celestial ancestors even when the camera is stationary over the terrain. - Attribute CPU, GPU, physics, terrain, and UI separately. Never disable shadows, lower authored terrain quality, change BigSpace, or change the standard substep count to make a graph look better. In a diagnostics-enabled render host, `lunco-render-bevy` adds `lunco_shadow_shared_early`/`late` and `lunco_shadow_camera_early`/`late` timestamps around the native shadow passes. Shared events correspond to individual point/spot views; camera events include that camera's directional cascades. Check all four names and their event counts before attributing total shadow cost. Late spans can contain only timestamp overhead. Use the early shared child spans `lunco_light_depth/<pass_name>` when attributing individual maps; native exports prefix them with `lunco_shadow_shared_early/`. Do not sum child and parent times. `lunco_shadow_view_work` supplies admitted viewport dimensions, optional phase emptiness and native bin/set counts. This brief CPU snapshot is not pass execution time; bins are not draw counts and stable counts do not prove static caster inputs. Native labels identify current render allocations, not authored lights. Close each child before its parent. Retain native dependency ordering, native-parameter admission before begin and render-context buffer order when changing this adapter. Reapply PBR's system-local early/late ordering rules after removing the original system; retaining its implicit type set alone preserves only dependencies targeting that set. Check the actual shadow image before admitting a capture as performance evidence. `SharedShadowView` uses the native single-threaded executor for its serial eight-system GPU chain or two CPU-mode shadow passes. Attribute its inclusive and self costs separately; frame-level Render and camera Core3d still use their existing executors. Verify native pass inventory and final buffer order before comparing executor costs. This render adapter does not change solver cadence or authoritative simulation ordering. Unsupported timestamp features or exhausted per-frame queries leave incomplete GPU evidence, not zero cost. - For intermittent long frames, export individual CPU zones and correlate them with perspective/window markers. Exclude screenshot delivery, authored test verdicts and perspective transitions from settled statistics. Inclusive render/extraction schedules can contain a native `queue_submit` wait; report the submission boundary separately from owner computation. A long submission span alone does not establish its driver, GPU or scheduling cause. Retain periodic GPU clocks/utilization, CPU pressure and concurrent process evidence, then run the same exact uninstrumented artifact separately. Failure to reproduce an earlier tail in a later run does not prove a fix. Record visible popup/UI state alongside camera and graphics settings. ## Architecture checks For synchronous USD edit stalls, inspect compound operation count and native composition lifetime. The document owner's `UsdEditSession` shares one current authoring stage across an ordered sequence; direct layer changes invalidate it. Preserve the private candidate and atomic rejection boundary described in [architecture 21](../../docs/architecture/21-domain-usd.md). Measure the actual command in a production run; a faster edit still occupies its calling thread. Also inspect `usd_native_reference_discovery`: native property resyncs prepare only their asset values, while prim resyncs scan the affected subtree. Asset types gate provenance and time-sample resolution. Domain live-edit owners consume one complete notice batch in place; label changes must preserve live child state. Modelica coupling holds `FixedMain`, while the pacing clock retains running demand in `Time<Fixed>::overstep`. Compare completed simulation time against monotonic wall time and inspect pending demand through `SimulationTimingProfile`; a short native physics service time does not certify realtime co-simulation. For scene-test diagnostics, `--tick-hz` varies manual update pacing; use the runtime's `Time<Fixed>` quantum and elapsed time when interpreting physics cost. Completed Modelica receipts have one reader in `SimulationCompletions`, serviced before clock projection, before admission of a held pending fixed cycle, and by the native driver on response readiness between application updates. A ready receipt can release another cycle in the same update; unfinished work yields without a wait. Full presentation isolation remains a separate requirement. The default communication period is one physics tick; longer periods must be authored explicitly. For deliberately frozen captures use `StepSimulation` and presentation-timed sequencing. Manual demand uses the same fixed runner as paced execution and still respects preparation and solver barriers. A native hold gates the entire simulation; compare `clock_snapshot().physics_elapsed_s` and `fixed_elapsed_s` at completed-cycle boundaries before interpreting throughput measurements. Attribute numerical service separately from transaction dispatch and result admission. Live workers pass the exact communication point to the existing `LiveStepper::advance_to` boundary; adaptive Rumoca sessions and fixed prediction own their internal steps. Preserve the fixed prediction lattice, event handling, input sampling and finite/completion validation when optimizing that path. Do not add another worker-side integration grid or catch-up planner. Keep communication-clock checks at floating point roundoff scale, with finite timestamps required at both request and completion admission. A solver's state tolerance must not loosen its communication endpoint validation. Validate the endpoint using `start + dt`; subtracting large absolute timestamps can reject a valid short interval through cancellation. UI exposure publication is paced by `Time<Real>`, independent of simulation pause and rate. Its dirty-state gate still coalesces unchanged facts. Attribute main-thread snapshot capture separately from `runtime_ui_policy_preparation` and owner publication. Native pure policy evaluation uses shared bounded worker admission, retaining captured hooks and caller context; one job plus one latest pending snapshot per surface bounds work. Source and identity changes fence completion. The wasm kernel is currently cooperative, not an isolated worker. Wait for ready surfaces and inspect preparation failures before taking a UI performance cohort. This boundary does not isolate the entire fixed runner from the presentation thread. Keep mission/timeline waits and telemetry deadlines on their declared simulation clocks; changing their timers to wall time changes simulation semantics. For script cost, attribute `rhai_native_task_tick` by stable actor gid and compare the same task-invocation range or simulation phase. Equal wall-time windows need not contain the same mission work when realtime pacing differs. Task callbacks borrow the persistent map through Rhai's bound receiver; see [the callback contract](../../docs/architecture/rhai-task-tree.md#leaf-callback-contract). Preserve captures, imports, state/error semantics and fixed cadence while removing copies at that boundary. For cost or memory that grows with runtime, check interpreter scope lifetime: initialized globals persist, while per-call constants and function locals must be released on both success and error. Use Rhai's scope-rewinding option at every scenario call boundary; do not periodically clear live scenario state. For Rhai presentation cost, inspect helper arguments and array iteration for copies of nested facts. Project the fields a helper consumes before calling it; indexed access can count participant statuses without copying their model input/output maps. Preserve the public hook facts and compare complete property outputs, including empty and unavailable states. Use paired real-owner spans for attribution; synthetic large-payload timings alone do not establish FPS. For typed Rhai boundary cost, use the shared `lunco-hooks-rhai` converter. It borrows input containers; embedding owners lower native leaves through `dynamic_to_hook_with_native`. Do not build a normalized Dynamic tree before calling it, clone containers to inspect their type, or add another recursive converter. Preserve native f64 math, unsigned integers, shared values and visible rejection of unsupported types. Check the interpreter resource seam with `typed_conversion_rejects_nested_native_values_without_cloning_them`, then exercise production typed command/query consumers, including a negative case. For port-exchange cost, inspect `BindingStatus.connections` and join targets to `ListPorts` owner metadata. The causal-state sink count is not the number of compiled wire targets: scene/shader inputs also participate in the exchange. Separate `cosim_exchange_write` from accumulation before changing routing. Preserve live metadata, bounds, ownership and stale-slot checks. For shader-name cost, use the shared borrowed converter described in [shader parameters](../../docs/architecture/shader-layers-and-params.md); canonical-name lookup must not allocate, and entities without `ShaderLook` must reject before conversion. Allocation probes and kernel timings do not certify whole-scene FPS. For native physics ordering investigations, enable `lunco_physics::order_audit=debug` in an owned diagnostic session. The continuous owner records native body and collider identities, poses, mass/inertia and velocities, plus contact-graph IDs, colours, manifold indices and prepared point geometry at the physics clock. Compare the first divergence before attributing a difference to pool size. This logging is diagnostic and must be disabled for performance acceptance. Partial pose checkpoints do not prove full-state replay. Compound audit rows include native scale and local part mass properties. If the first divergence is already in COM, compare admitted geometry and mass ownership before attributing later motion to the query dispatcher. For continuous-query dispatch, compare the CCD owner's bounded `minimum_query_batch_size` with its unconstrained zero setting using the same scene and ordered inputs. Small batches execute the same kernel directly; larger batches join before authoritative correction. Preserve native query results and compare complete physics time, including CCD and joints. The default minimum is eight queries per worker; joined chunks retain prepared order. Use `continuous_scoped_queries_preserve_order_geometry_and_errors` for bitwise witness/normal/contact-cache parity before production state replay. `ccd_query_dispatch` records bounded query and worker counts around the shared kernel and join. Match query population and simulation phase, retain power observations throughout each comparison, and separate dispatch duration from the enclosing sweep and complete physics tick. A changed worker distribution needs measured benefit in addition to numerical parity. When attributing native GPU preprocessing, trace allocation identity rather than only buffer capacity. Bevy's `collect_buffers_for_phase` exchanges per-phase and frame-level buffer cohorts each frame; equal sizes do not mean consecutive bindings agree. Native view groups must be present on current extracted views. Compare actual buffer identities, binding offsets/ranges, layout descriptors, occlusion textures, work modes/counts and bin-job parameters, and measure admission overhead and native rebuild frequency. Pipeline-cache change ticks alone are unsuitable: native queue processing mutably accesses that resource every frame. Preserve native deferred publication and every GPU preprocessing/draw pass. See the current handover for the owned binding-lifetime captures; they establish no product speedup. For authored image preparation, trace `lunco-materials` typed `PreparedShaderImage` loading: native decoding and owned RGBA8 filtering precede source/child publication. CPU filtering awaits the async compute pool with an owned image, without blocking an I/O worker or borrowing ECS. The renderer resolves `ShaderTexture` and reacts to source asset events; it must not snapshot resident pixels. The prepared loaders register no extensions, preserving native image/glTF settings and decoding. Prepared children use the native render-only extraction contract: pixels move into GPU preparation while the main asset retains metadata. Audit CPU readers before choosing that usage; sampler/descriptor edits must come through source reload with fresh data. Verify initial load and reload publish complete chains, independent color/scalar/ normal identities, native-image forwarding and invalid-pixel rejection at the asset seam. `load_raster` accepts physical paths; verify labeled requests reject before issuing a prepared-root load and importer-owned native image handles still load, bind and reload. Preserve exact RGBA8 transfer, sampler quality and role identity. Worker-time gains need separate loading/UI/FPS evidence before an app-level claim. For repeated analytic USD primitives, inspect reflected `Mesh3d` identities before inferring duplicate preparation or upload cost. `PrimitiveMeshAssets` in `lunco-usd-bevy-mesh` owns shared preparation and weak native mesh lifetime; source admission remains in `lunco-usd-bevy`. Preserve the [immutable mesh contract](../../docs/architecture/render-decoupling.md#immutable-primitive-mesh-assets), quality replacement and entity-specific edit isolation. Run the authored `primitive_mesh_sharing.rhai` sandbox gate for equal and unlike dimensions. Fewer asset IDs alone do not prove fewer GPU draws or faster frames. The retained `engine.frame_time` series samples raw app-frame values at the fixed 60 Hz ceiling and may repeat values; collect it before its 240-sample ring truncates the measurement window. Report it separately from once-per-rendered-frame data. Search the owning systems for unconditional writes, full-set topology scans, repeated observer registration, per-frame allocations, polling, and work that should be gated by a revision/change event. Structural edits should invalidate structural caches; transform propagation and telemetry output are not by themselves topology changes. Check both the Builder and View registration paths before fixing only one. For loading throughput, compare worker CPU duration with the complete job window and idle gaps while preparation is queued. `AsyncWorkAdmission` starts work in PostUpdate and refills released slots on completion; its global bound, priority service, cancellation and weak queue lifetime remain independent of frame rate. Verify refill without another host update and retirement with captured permits, then compare settled terrain readiness and replay the authoritative state. For physical solar visibility, attribute `publish_sun_visibility` separately from native physics. Distinguish terrain enclosure cache misses from actual height evaluations: a warm bounds cache can still repeat procedural samples at adjacent-cell and refinement endpoints. Ray-local sample reuse must use exact f64 coordinate bits and preserve traversal, interval budgets, unavailable data and fault behavior. Run the focused certified-occlusion mechanism checks and the production terrain solar visibility and invalid-admission gates; compare the unchanged solar-power observations and run a separate production Twin window. For procedural synthesis, separate noise, population generation and profile evaluation. Reuse input-constant preparation at the existing mathematical owner before adding a population cache. Preserve cell hashes, f64 operation order and draw independence; compare exact point bits as well as production terrain and simulation outputs. Keep math diagnostics separate from whole-app acceptance. For dataset consent, check `publish_dataset_provisioning_surface` separately from its Rhai policy. Diagnostic-outbox drains must not mark registry catalog facts changed. Bevy excludes a system's own writes from its next change check; trace other writers before attributing repeated work to a publication cursor. Preserve real registry/workspace/command edits, policy replacement and interactive-window transitions. Run the windowed `dataset_provisioning_surface.rhai` gate with a declared missing scope; confirm unrelated dismissal preserves the view and active dismissal clears retired properties without requesting a download. For the derived scene entity tree, immutable parent insertions use native lifecycle messages coalesced by entity at the Update gate. Compare current edge values with the cached ancestry; identical replacements must not rebuild. Separate change admission from rich candidate reads: the native changed query returns only entity identities; indexed candidate reads fetch label/visibility data for those identities. Preserve the candidate predicate and mutable metadata coverage. Direct mutable component edits must still invalidate the cached tree; insertion observers alone cannot detect them. Retain mutable-label and scene-boundary checks, removal handling, unnamed ancestor invalidation and active-Twin queue retirement. Native renderable additions cover marker admission; the metadata query also admits new names. Retain the native mutable metadata change query, including edits to unpublished worker members. Cover a new name on an already tracked unnamed ancestor. Compare indexed membership scans with native change filtering in the live owner before changing the scan strategy. Measure the complete gate and source observers separately from tree derivation and panel paint. The gate exposes `entity_tree_gate_named_changes`, `entity_tree_gate_removals` and `entity_tree_gate_parent_changes`; compare the complete gate as well as these phases, with equal instrumentation and cameras. For frame-contract gate costs, distinguish the full connectivity validator from its admission/fixed run conditions. The bridge observes native physical and hierarchy lifecycle events through one change-ticked resource; each consumer retains its own observation boundary. Preserve insertion, reparenting, removal, despawn and active-frame switch/removal detection without waking on ordinary pose values. Validate a disconnected body through the public owner diagnostic and stopped solver ticks, then verify a replacement scene resumes physics. For link-sweep costs, attribute `celestial_ephemeris_position` separately from pair geometry and verdict hooks. Use `link_collect_endpoints`, `link_snapshot_occlusion_inputs`, `link_evaluate_pair`, `link_terrain_line_of_sight` and `link_verdict_policy` to distinguish snapshot preparation, terrain marching and typed-policy marshalling/execution. Pair spans contain terrain and policy spans; do not add inclusive durations. The analytic provider's exact-epoch cache also shares native EMB/Earth VSOP operands across dependent bodies. Preserve native f64 values and formula order; a new epoch bit pattern invalidates final and intermediate samples together. Compare public `BodyPosition` results against the prior exact artifact at adjacent and revisited epochs before claiming a gain. Before increasing epoch retention, record exact body/epoch keys and cache hits. Distinguish first evaluations from repeated misses after eviction; extra slots cannot save unique sample work. Do not quantize epochs or duplicate a maintained analytical formula to create apparent reuse. For an exclusive system, check repeated `World::query` construction separately from iteration. Retain Bevy's native `QueryState` in the owning system when the query shape is stable; read current membership each pass and collect identities before structural mutation. Preserve that system's serial schedule position and lifecycle ordering. A settled-frame saving also needs live add/remove or replacement evidence, since queries must admit newly matched archetypes after startup. For USD Modelica source dispatch, inspect pending membership before attributing its exclusive span to initialization. Empty calls still flush the World. The native component/scene-transaction run conditions skip that boundary only when there is no admissible source work. Verify deferred source insertion, scene holds and replacement, while retaining the wiring/defaults chain, prim-path compile order and initialization sampling. A removed idle span proves avoided work; it does not by itself prove loading or whole-app FPS gains. The co-simulation endpoint lifecycle publisher uses this native exclusive query parameter. Validate its same-frame ready transition and run sandbox binding acceptance again after scene replacement; keep immediate endpoint insertion and the `PostUpdate` binding boundary intact. The neutral scenario driver shares its native model query across preparation, startup, fixed and visualization passes; preserve fresh model/scope/authority reads and stable actor sorting when changing that owner. For telemetry retention, separate due recording batches from cheap between-batch calls. `SignalRegistry::record_scalar_at_rate` admits and appends through one live history lookup; preserve backwards-time segments, retention, archived-source reactivation and catalog notifications. A registry benchmark isolates that owner, but production retention spans and raw physics/frame tails need separate evidence. Modelica and physics channel-limit checks read the live scalar count after append and only hash history identity for admission when the catalog is full. Preserve existing-channel recording above a lowered limit and rejection after history removal; a cached producer identity alone does not prove that history exists. For dynamic-body admission, compare `activate_dynamic_bodies` with its native eligibility gate. Paused or invalid assemblies retain `ShouldBeDynamic` for diagnostics but must not wake admission when its query has no eligible bodies. Share the exact archetype filter; retain preview-ancestry checks, stable identity faults, promotion order and joint holds inside admission. Verify paused poses and warnings through `sandbox_ramp_placement.rhai`, plus exact-state replay against the unchanged binary. A stale tracked Modelica reference is not passing replay evidence; capture a separate baseline and preserve the tracked reference. For articulated mass facts, separate `refresh_dynamic_joint_island_masses` from its `dynamic_joint_island_mass_rebuild` span. The physics owner retains lifecycle invalidation through pauses; native change detection handles mutable effective masses and joint endpoints. Normal and rollback exchange read the same derived resource at their existing boundaries. Verify live mass edits, rejected negative writes and island splitting through `joint_island_mass.rhai`, plus exact replay against the unchanged artifact. Quiet steps must not rebuild islands; marker removal, body removal and paused lifecycle edits must still invalidate them. Preserve native sums and the full-island invalid-mass result. For a system that queues many compatible ECS component changes, inspect its `system_commands` flush separately from the system body. Collect changed values and use the owning crate's existing batch command path where it preserves the same commit boundary; retain change filtering so a quiet fixed cycle queues nothing. In panel paint code, use `PanelCtx::resource` for reads. Its `resource_scope` temporarily removes and reinserts the resource, which marks it changed even when the closure only reads it. Scope a mutable borrow only around a real state transition; otherwise a steady Builder repaint can wake change-detection systems and full-scene reconciliation on the next Update. USD authored/composed text painting borrows `UsdViewportState` and its cached source strings. Check `usd_preview_render_layer_propagation` when diagnosing preview invalidation; report traversal cost separately from frame time. Opening several previews must not add bodies, colliders, or joints to the mounted scene. For SysML requirements rebuilds, inspect `sysml_requirements_rebuild` input flags. Domain notification publishers check `has_pending_events` before mutably draining their registry; an empty queue must not invalidate readers. Workspace document focus and USD editor open/close are not SysML inputs. The requirements producer compares the active Twin identity, root, manifest, and file index before reacting to workspace change detection. Verify both an unrelated editor change (no rebuild) and a Twin/source/evidence change (fresh projection); do not suppress domain registry invalidation. Source links use `DocumentRegistry::doc_for_file`, which checks all exact paths before resolving file aliases. Preserve symlink identity and dirty-document semantics; do not build a panel-local path registry. Inspect scenario preparation separately from lifecycle execution. Unchanged actors borrow their canonical source; only admitted compile/retry work copies worker inputs. Do not defer initialization or change actor commit order to reduce this preparation cost. For Modelica response retention, reuse observable-variable keys and move the worker's input/output buffers into the accepted record after transaction validation. Preserve detected-symbol/output precedence and verify reset isolation, signed-zero values and stale-result rejection at the owner seam. Modelica workers return current observations only. Retained samples belong to `lunco-modelica-telemetry` and the shared chunked `SignalRegistry`, installed through `TelemetryRetentionPlugin`. UI consumers read that same history and receive only a checked `ModelicaSessionStarted` lifecycle message when a new session requires binding cleanup. Verify retained history through `ListTelemetryChannels` and `QueryTelemetryHistory` in both hosts, and exercise the public accepted-step reader through production. Measure response latency separately from solver integration and fixed-step output publication. For loading, separate prepared-FMI lookup/lowering, live construction and ordered publication. `modelica_live_plan_admission` runs on the command owner; `modelica_live_construction_job` records queue wait and measures the native session, metadata and initial-observation children. `modelica_live_construction_commit` measures publication. Preparation and live sessions use separate captured bounded worker budgets. Scene and document actors have separate live-owner pools; each session retains its construction thread through stepping and retirement. Compare concurrent construction intervals and end-to-end readiness, not only summed worker time. A round transfers complete input buffers once, runs independent participants concurrently, and admits checked results in command order. Require exact replay, terminal observation-failure and scene replacement evidence before a scheduling gain claim. Preserve exact communication points, backend numerical profiles, metadata and generation retirement. The native compiler already shares its DAE and source map; additional metadata caches do not address dominant native construction cost. For mixed loading and live execution, inspect `modelica_live_step_job` queue wait and execution separately. Match its construction identity and thread to preparation/construction spans before attributing a response-latency rise to mailbox blocking; response latency also includes transport and main-thread admission. Preserve the fixed-tick backlog and barrier state alongside timings. Modelica and scripted snapshot publication use `ScalarPortMap::upsert_samples`. The destination retains slot hints, but validates each live layout and exact name on every copy. Name validation and the bit-exact update share one mutable slot borrow; measure that copy separately from solver response admission. `modelica_outputs_copy_variables` isolates the variable-map traversal and port update; `modelica_outputs_seed_inputs` isolates omitted-input seeding. Both are children of fixed-step output publication, so compare their total time with that owner over the same settled window. Their call counts are per participant, not per simulation tick. The required `ModelicaVariables.values` component owns the full native f64 reflected snapshot; `ModelicaModel` owns clocks, inputs, parameters and status. Serial worker admission marks the snapshot changed only when value bits change. Reflection writes also participate in native detection. Added models, USD participant markers and destination components force initial publication. Run the production `modelica_variable_projection` and `modelica_variables_missing` gates when changing this boundary, plus exact state replay and lifecycle resource checks for late results and retirement. Preserve reordering, same-size source replacement, target edits, clone/clear/compaction retirement and native-bit no-op detection when changing that mechanism. Do not infer unchanged source topology from map length or cached iteration order. Preserve the full reflected snapshot and fixed-step publication boundary, and measure both copying and total owner time; moving work to another phase is not sufficient evidence of a throughput gain. For port-write metadata, preserve the live validation boundary. `PortMetadata` borrows static source/authority text through native `Cow` and owns dynamic text; check both representations and content equality, then verify public metadata and collision diagnostics. Borrowing labels must not bypass owner precedence, stale-handle rejection, writability, bounds or atomic batch admission. For structural publication, use the existing `PortTopologyState` owner to observe expensive auxiliary fingerprints by their own component change ticks. `observe_if_changed` computes a cold key and recomputes changed owners; sample updates reuse the recorded key. A participant's new admission must refresh auxiliary facts that could have changed while it was absent. Verify metadata edits, same-size declaration replacement, removal and re-admission. Keep direct backend inspection and write validation on the live contract. For fixed-step port costs, the exchange exposes `cosim_exchange_topology`, `cosim_exchange_accumulate`, `cosim_exchange_holds`, `cosim_exchange_write` and `cosim_exchange_diagnostics` inside the single propagation owner. Attribute these phases before changing lookup or validation; do not add their nested duration to the parent. Backend `declare_ports` uses `PortDeclarationQuery` for both full inspection and exact-name, direction-constrained discovery. Map-backed owners query the requested name directly; named queries retain only the first matching direction without constructing owned rows. Preserve the same declaration order and live metadata checks; topology publication alone cannot guard an owner edit before its scheduled publication pass. Avian resolution, named declarations and metadata selection share immutable name candidates derived from `AVIAN`. Preserve candidate order and live group membership on removal, re-admission and mobility edits; full inspection retains table order. The index does not authorize a write or cache world membership. `write_resolved` shares its locator's `Arc<str>` with canonical input-write preparation, compares the live owner with its locator, then commits within the same exclusive World boundary without a name or single-element batch allocation. Registry clones share the immutable backend table; registration detaches it without changing existing snapshots or their precedence. Verify snapshot isolation and shared name identity when changing those allocation boundaries. Preserve live precedence, metadata, topology revision, slot, value checks, and rejection ordering. Separately prepared batches still revalidate every write before committing any of them. Ownership selection retains the winning backend's optional slot for the same World borrow. Handle creation, preparation and batch preflight consume that result without repeating the winner's resolver. Verify one resolver call per admission, declared owners without a slot, readable input-side sources, stale layouts and metadata edits; do not substitute a persistent ownership cache. The shell's steady `WorkbenchSnapshot` check compares borrowed dock and perspective iterators before materializing owned vectors; preserve that allocation-free stable path when changing layout publication. The top-level menu's unique label projection is built only when the menu registry changes. Width measurement borrows that projection and streams labels without collecting another vector; compute perspective-tab rows once per UI pass and reuse them for both width measurement and painting. Do not rebuild the same responsive menu inputs during steady repaint. For contributed top-level menus, defer collecting and sorting scripted contributions until the popup callback runs; a closed menu should only paint its row and publish its anchor. Use `workbench_custom_menus_render` to inspect that row path separately from the workbench aggregate. When a measured UI snapshot builds several indexes from the same entity population, combine compatible marker reads into the existing query and avoid another full-population traversal for each marker set. Keep queries over different populations separate unless measurements show that a broader scan costs less. For large Builder hierarchies, derive a lightweight row index from the cached
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub