1 rollouts

rollouts

Target-conditioned replay transitions and persisted rollout stores.

aria_nbv.rollouts owns the multi-step thesis replay and persistence surface. Operational rollout-dataset generation lives in aria_nbv.oracle.pipelines; raw snippet access and immutable VIN offline stores remain in aria_nbv.data_handling.

The stable root exports replay and store entrypoints. Import validated finite-horizon chain reading from aria_nbv.rollouts.storage.qh_reader and pose composition from aria_nbv.rollouts.qh_geometry.

1.1 Package guide

aria_nbv.rollouts owns finite-candidate replay, standalone rollout Zarr stores, QH chain reading, manifests, audits, and presentation-free inspection projections. Dataset generation is composed by aria_nbv.oracle.pipelines; immutable actor roots remain in aria_nbv.data_handling.vin_store.

For available stores and cross-store discovery, see the dataset store overview.

1.2 Stored Contract

A rollout store contains factual tables for targets, rollout chains, realized steps, candidate rows, selected actions, source lineage, optional selected depth, and a validated derived q_h/ view. The factual tables remain authoritative; the QH view is a training-hot projection that readers validate against them.

Candidate support has several distinct meanings:

  • materialized candidate rows;
  • hard action-valid rows;
  • oracle-labelled rows;
  • selected transition rows;
  • storage padding.

Invalid targets or actions remain masks and reason codes. They are never fabricated low-RRI or zero-Q labels.

1.3 Controlled support diagnostics

inspection/support.py compares a declared finite proposal pool and actor continuation choices against oracle labels. The former support_diagnostics.py import remains as a bounded compatibility leaf for the published PR387 contract. The intended scene/root population is supplied independently of results, with exactly one success or explicit failure for every root. Unknown resource measurements remain None.

Proposal decomposition requires physically nested actions with matching poses, hard masks, measurement context, and shared rewards within the declared tolerance. Missing valid labels make exact maxima undefined. Actor choices are formed from actor-visible scores before oracle evaluation and are bound to the candidate table, history, ordering, and mask. Dense one-step labels do not imply factual successor experience.

The reducer averages within scenes first and reports attempted and defined denominators. Its mean remains conditional on defined comparisons; retaining failures does not remove selection bias. The finite reference is not a continuous optimum, and a gap to one actor is not an irreducible information gap. These library contracts do not yet connect production acquisition to a complete experiment receipt; that work remains in issue #277.

candidate_support/preflight.py owns the single candidate-family preflight reducer consumed by the info CLI, campaign admission, Plotly figures, and the stored-rollout panel. Its root floor is resolved and persisted as max(12, ceil(0.25 * Nq)); this total-support test is separate from the versioned family floor. Applicable families require selected support, while inapplicable cells remain visible and non-failing and unknown legacy applicability fails closed for deployment. Direct target-root-gain variation is state-conditional: it is tested only over eligible factual states with at least two compatible valid oracle labels, reports both label and eligible-state denominators, and uses the manifest-owned minimum-per-state-range aggregation revision. The Phase-A path has no reward labels, so flat_gain is unavailable rather than inferred from geometry. This remains a no-render, no-reward-label proposal-support audit with privileged GT target instruction and mesh validity, not an oracle-free audit. Passing it does not authorize broad generation: the later hash-bound issue-120/WP18 gate remains mandatory.

benchmark_from_sampling_result is the candidate-only Phase-A seam. It copies the generator’s full-shell component lineage, hard-valid mask, rule reason bitsets, and available continuous margins, while assigning no oracle labels or policy-selected transition. Candidate centres, target-relative vectors, and camera-forward directions use one target-aligned, world-Z-up basis: axis 0 is the horizontal expansion-to-target direction, axis 1 points left, and axis 2 is world up. Positions are divided by the current three-dimensional target distance; directions remain unit vectors. Its family selected counts mean compact final action-shell membership, exactly as in the store-backed reducer. The campaign preflight serializes these same benchmark records and reducer output into one content-hashed evidence JSON; it does not reinterpret support.

1.3.1 Current Phase-A evidence

The frozen 100-scene control is candidate_family_phase_a_wp02.json (artifact SHA-256 6d33e9e3d68737c8a6a5589ae5117c1e4d7fcaa89056fcfcaec1d315e4509c83; compact file SHA-256 843d1e6c41df7746db1187a92eb7b29f9f18263bb33cbb5e3b4efc9f1acea017). It covers all 100 reviewed source rows, scenes, and target states with no exclusions. Of 6,000 attempted rows, 3,146 entered the compact valid shell, but the gate is a no-go: 44 state/family cells collapsed, 24 states missed the non-forward target-family floor, and 8 states missed the root-support floor. flat_gain is explicitly unavailable with label and eligible-state denominators both zero because Phase A contains no reward labels. The full state-by-family heatmap and per-state funnels are derived from that same canonical reducer result. The artifact binds native source-store identity 605453ba11869e40, writer configuration SHA-256 4ae05a1e4066756a47f9ba00d914b8f4337321ae8dcd161a62228d02f71d0587, generation revision a2ae86b7463930c9, and the recorded CUDA runtime. It satisfies issue #54’s mechanism and all-100-scene evidence checklist: the fail-closed gate exists and produced the required bounded no-go. Sampler remediation and a later passing rerun remain separate follow-up work; this artifact does not admit broad generation. The stored shells, support counts, verdict, and execution revision are unchanged from the one real run. Transformation authenticated_target_frame_correction_no_candidate_rerun rotates only the stored candidate centres, target-relative vectors, and view directions into the canonical target-aligned Z-up basis. Geometry correction revision phase-a-target-aligned-z-up-v1 and predecessor artifact 60b271db515a5e665fcb7bbeeecb87e6acb4bac2ff8e28b26b7308911328759c bind that correction; no candidate generation or GPU population was rerun. The corrected 100-record payload has SHA-256 43a4fbba2e412c6a7d4b9a0c2a8b6f3d064dde4d9387566ea29f077365447c89.

The current record key is the composite (scene_key, state_key). This is sufficient for the historical one-root Phase-A artifact. WP03/WP06 must extend provenance with proposal/root/replica identity before repeated physical states are admitted; state labels alone must not merge those future repetitions.

1.4 Generate and Inspect

Run from aria_nbv/:

uv run nbv-build-rollouts \
  --config-path ../.configs/smoke/build_rollouts_v1_smoke.toml \
  --dry-run
uv run nbv-build-rollouts \
  --config-path ../.configs/smoke/build_rollouts_v1_smoke.toml

uv run nbv-rollouts-info \
  --store ../.data/offline_cache/rollouts_v1_smoke.zarr \
  --validate
uv run nbv-rollouts-info \
  --store ../.data/offline_cache/rollouts_v1_smoke.zarr \
  --json

For sharded campaigns, use nbv-plan-rollout-shards, nbv-status-rollout-shards, and nbv-rollout-campaign. Each completed shard must pass validation and carry its success/owner sidecars before it is treated as reusable input.

1.5 Read a Store

from aria_nbv.rollouts import RolloutZarrStoreReader

reader = RolloutZarrStoreReader("rollouts.zarr")
validation = reader.validate()
if not validation.ok:
    raise ValueError(validation.errors)

manifest = reader.manifest()
qh_arrays = reader.q_h_view()

Use storage/read_model.py for typed, presentation-free projections consumed by Streamlit and Rerun. Use QhRolloutReader when the consumer needs complete validated QH chains, target protocol identity, source references, and optional selected-depth evidence.

1.6 Replay and Online Scores

rollouts.replay owns in-memory rollout state, policy specifications, CandidateScores, and finite-candidate transition generation. Persisted Zarr encoding and trace lineage belong to storage/.

The online finite-horizon adapter lives in aria_nbv.oracle.pipelines.online_qh. It validates a bundle against the current decision context, evaluates raw conditional Q, then passes only hard-valid values into CandidateScores. Learned feasibility does not replace the policy mask.

1.7 Ownership Map

Module Responsibility
replay Policies, in-memory states, score DTOs, and transition engine.
storage/trace Normalize replay results into factual persisted rows.
storage Store schema, writer, strict reader, validation, and manifests.
storage/qh_reader Multi-store QH chain decoding and learning/data identity.
storage/_qh_contracts Stored relative-pose composition contract for actor tensors.
storage/read_model Presentation-free typed projections.
inspection/ Inventory, candidate, policy, invariant, geometry, audit, and S² evidence questions.
candidate_support/ Immutable candidate contracts, family preflight, and content-addressed bundle I/O.
presentation/ Report frames and deterministic Plotly encodings over reduced evidence.

Target-frame S² inspection separates three observables: selected camera displacement, selected optical-axis direction, and calibrated proxy-surface frustum support. inspection/geometry.py owns the complete equal-solid-angle reducer; inspection/s2.py owns configured store acquisition and evidence identity; presentation/s2.py owns only the deterministic Plotly encoding. The target OBB normalizer is the geometric mean of its semi-axis lengths, not an OBB-volume-equivalent sphere radius. Calibrated support uses the half-pixel continuous image rectangle and remains geometric potential visibility until depth or mesh intersection establishes true visible target surface.

Detailed table schemas, shapes, and validation failures live in source docstrings and the generated API reference. The shared scientific reporting module wraps these canonical frames into immutable cross-source snapshots; it does not own or reimplement rollout calculations, Zarr admission, or compatibility decisions.

1.8 Verification

cd aria_nbv
uv run ruff check aria_nbv/rollouts
uv run pytest tests/rollouts
uv run pytest tests/data_handling/test_qh.py

Include Oracle generation, Streamlit, or Rerun tests when changing their consumer boundary.

1.9 Classes

Name Description
CandidateScores Scores aligned to the hard-valid rows of one candidate table.
CounterfactualPoseGenerator Expand a multi-step counterfactual pose tree from the current generator.
CounterfactualPoseGeneratorConfig Configuration for multi-step finite-candidate rollout generation.
CounterfactualRolloutResult Retained replay leaves and tree controls for one physical root pose.
CounterfactualTrajectory One retained root-to-leaf path through the replay tree.
RolloutPolicySpec Immutable branching and action-selection policy for one rollout recipe.
RolloutZarrStoreConfig Filesystem, replay, and oracle-retention settings for one rollout store.
RolloutZarrStoreReader Open a completed standalone rollout replay store in read-only mode.

1.9.1 CandidateScores

rollouts.CandidateScores(values, action_mask, candidate_shell_indices, name)

Scores aligned to the hard-valid rows of one candidate table.

1.9.1.1 Attributes

Name Description
values Compact score vector in stable valid-candidate order.
action_mask Full-shell hard action mask; invalid rows are never selectable.
candidate_shell_indices Full-shell row ids corresponding one-to-one with values.
name Stable semantic name of the score used for action selection.

1.9.1.2 Methods

Name Description
from_valid_values Normalize compact scores and bind them to one hard-masked table.
validate_for Verify the hard mask and candidate-order link against candidates.
1.9.1.2.1 from_valid_values
rollouts.CandidateScores.from_valid_values(
    values,
    *,
    name,
    candidates,
    device,
    dtype,
)

Normalize compact scores and bind them to one hard-masked table.

1.9.1.2.2 validate_for
rollouts.CandidateScores.validate_for(candidates, *, device, dtype)

Verify the hard mask and candidate-order link against candidates.

1.9.2 CounterfactualPoseGenerator

rollouts.CounterfactualPoseGenerator(config)

Expand a multi-step counterfactual pose tree from the current generator.

The generator returns in-memory trajectories only. Callers such as RolloutDatasetWriter provide source samples and oracle evaluators, then decide which rollout records and diagnostics are retained in standalone replay stores.

1.9.2.1 Methods

Name Description
resolve_root Resolve the physical, rollout, and camera roots without rendering.
resolve_typed_sample_root Resolve the exact no-render root used by typed-sample replay.
generate_from_typed_sample Generate rollout trajectories directly from one typed snippet.
generate Generate multi-step counterfactual rollouts from one root pose.
1.9.2.1.1 resolve_root
rollouts.CounterfactualPoseGenerator.resolve_root(
    reference_pose,
    camera_calib_template,
    root_time_ns=None,
    root_trajectory_index=None,
    root_frame_index=None,
)

Resolve the physical, rollout, and camera roots without rendering.

1.9.2.1.2 resolve_typed_sample_root
rollouts.CounterfactualPoseGenerator.resolve_typed_sample_root(
    sample,
    *,
    reference_pose=None,
    device=None,
)

Resolve the exact no-render root used by typed-sample replay.

1.9.2.1.3 generate_from_typed_sample
rollouts.CounterfactualPoseGenerator.generate_from_typed_sample(
    sample,
    *,
    reference_pose=None,
    score_candidates=None,
    admit_root_candidates=None,
    candidate_runtime_context=None,
)

Generate rollout trajectories directly from one typed snippet.

When provided, admit_root_candidates observes the materialized seeded root shell exactly once. A returned rejection raises RootCandidateAdmissionError before zero-valid handling or candidate evaluation. Omitting the callback preserves ordinary replay.

1.9.2.1.4 generate
rollouts.CounterfactualPoseGenerator.generate(
    reference_pose,
    gt_mesh,
    mesh_verts,
    mesh_faces,
    camera_calib_template,
    occupancy_extent,
    score_candidates=None,
    admit_root_candidates=None,
    candidate_runtime_context=None,
    root_time_ns=None,
    root_trajectory_index=None,
    root_frame_index=None,
)

Generate multi-step counterfactual rollouts from one root pose.

Root admission runs after candidate metadata is attached to the first shell and before any evaluator call. Accepted shells continue through the unchanged zero-valid, scoring, selection, and branching sequence.

1.9.3 CounterfactualPoseGeneratorConfig

rollouts.CounterfactualPoseGeneratorConfig()

Configuration for multi-step finite-candidate rollout generation.

Candidate sampling stays in pose_generation: each rollout step regenerates a shell from the current pose/history, applies hard validity masks, and selects valid actions by the configured policy. Persistence, source-row lineage, and Q_H replay views are owned by aria_nbv.rollouts.

1.9.3.1 Attributes

Name Description
target_type Return the finite-candidate replay generator constructed by this config.
policy Complete immutable branching and action-selection policy.

1.9.4 CounterfactualRolloutResult

rollouts.CounterfactualRolloutResult(
    root_pose_world,
    root_camera_pose_world,
    trajectories,
    horizon,
    branch_factor,
    beam_width,
    selection_policy,
    score_label='score',
    root_time_ns=None,
    root_trajectory_index=None,
    root_frame_index=None,
)

Retained replay leaves and tree controls for one physical root pose.

H is maximum depth, B is base sibling expansion count, and L = len(trajectories) is the retained branch/beam axis after pruning. Each step retains its own variable-width candidate shell.

1.9.4.1 Attributes

Name Description
root_pose_world World-from-corrected-reference pose shared by all trajectories; fixes the root frame after the local-Z rig-basis twist.
root_camera_pose_world Physical world-from-camera anchor at depth zero.
trajectories Retained root-to-leaf paths on the branch/beam axis L.
horizon Maximum number of selected transitions H per path.
branch_factor Base sibling expansion count B before beam pruning.
beam_width Maximum retained partial paths per depth, or None for no cap.
selection_policy Action-selection policy shared by the replay call.
score_label Stable semantic name for per-action selection scores.
root_time_ns Source capture timestamp in nanoseconds, when available.
root_trajectory_index Source trajectory index used to reconstruct root evidence.
root_frame_index Source frame index associated with the root pose.

1.9.5 CounterfactualTrajectory

rollouts.CounterfactualTrajectory(
    root_pose_world,
    root_time_ns=None,
    root_trajectory_index=None,
    root_frame_index=None,
    steps=list(),
    cumulative_score=0.0,
    terminated_early=False,
    termination_reason=None,
)

One retained root-to-leaf path through the replay tree.

A trajectory has at most H transitions and T = len(steps) + 1 poses: the root reference rig followed by selected camera endpoints. Update helpers return new records so sibling branches do not share step lists.

1.9.5.1 Attributes

Name Description
root_pose_world World-from-corrected-reference pose at depth zero. The fixed local-Z rig-basis twist is already applied; no camera extrinsic is implied.
root_time_ns Source capture timestamp in nanoseconds, when available.
root_trajectory_index Source trajectory-sample index used to reconstruct root evidence.
root_frame_index Source frame index associated with the root camera pose.
steps Selected transitions in increasing zero-based horizon order.
cumulative_score Sum of policy selection scores along this retained path.
terminated_early Whether expansion stopped before the configured horizon.
termination_reason Explicit replay-owned reason when expansion stops before the horizon.

1.9.5.2 Methods

Name Description
final_pose_world Return the root pose or final selected pose.
pose_chain_world Return root and selected poses in trajectory order.
history_centers_world Return camera centres as Tensor["T 3", float32] in world metres.
selected_shell_path Return the stable full-shell action history identifying this state.
reference_pose_world Return the pose from which step_index expands.
with_appended_step Return a new trajectory with one selected transition appended.
mark_terminated Return an immutable-style copy marked as terminated before the horizon.
1.9.5.2.1 final_pose_world
rollouts.CounterfactualTrajectory.final_pose_world()

Return the root pose or final selected pose.

1.9.5.2.2 pose_chain_world
rollouts.CounterfactualTrajectory.pose_chain_world()

Return root and selected poses in trajectory order.

1.9.5.2.2.1 Returns
Name Type Description
PoseTW Batched PoseTW backed by Tensor["T 12", float32], where
PoseTW T = len(steps) + 1.
1.9.5.2.3 history_centers_world
rollouts.CounterfactualTrajectory.history_centers_world()

Return camera centres as Tensor["T 3", float32] in world metres.

1.9.5.2.4 selected_shell_path
rollouts.CounterfactualTrajectory.selected_shell_path()

Return the stable full-shell action history identifying this state.

1.9.5.2.5 reference_pose_world
rollouts.CounterfactualTrajectory.reference_pose_world(step_index)

Return the pose from which step_index expands.

1.9.5.2.6 with_appended_step
rollouts.CounterfactualTrajectory.with_appended_step(step)

Return a new trajectory with one selected transition appended.

1.9.5.2.7 mark_terminated
rollouts.CounterfactualTrajectory.mark_terminated(
    reason='no_selectable_candidate',
)

Return an immutable-style copy marked as terminated before the horizon.

1.9.6 RolloutPolicySpec

rollouts.RolloutPolicySpec()

Immutable branching and action-selection policy for one rollout recipe.

1.9.6.1 Attributes

Name Description
horizon Maximum number of selected transitions.
branch_factor Default number of child actions expanded per non-terminal state.
beam_width Maximum retained partial trajectories; None keeps every branch.
branch_factor_schedule Optional deterministic per-step branch counts; the final value repeats.
stochastic_branch_factors Optional seeded branch-count choices sampled per expanded state.
stochastic_branch_probabilities Optional probabilities aligned with stochastic_branch_factors.
selection_policy Policy used to rank or sample admitted candidate actions.
selection_temperature Temperature used by stochastic score-based selection.
robust_temperature_logits Normalize finite scores by median and IQR before temperature scaling.
robust_logit_iqr_floor Minimum robust scale in target-root-gain units; zero preserves historical selection and lineage.
min_history_distance_m Minimum distance from poses already selected in the current trajectory.
min_sibling_distance_m Minimum translation separation between sibling branches, in metres.
min_sibling_yaw_deg Minimum sibling heading separation in world-XY degrees.
min_sibling_target_bearing_deg Minimum target-bearing separation between sibling branches, in degrees.
require_sibling_strategy_diversity Prefer distinct candidate strategy families among sibling branches.
seed Root seed for action selection; None uses zero for deterministic replay.
proposal_seed Independent proposal-stream root; None falls back to seed for compatibility.
proposal_replica Independent candidate-shell replica for the same physical rollout state.
orbit_direction Required persistent direction for either directed-orbit selection mode.

1.9.7 RolloutZarrStoreConfig

rollouts.RolloutZarrStoreConfig()

Filesystem, replay, and oracle-retention settings for one rollout store.

The destination is independent of the immutable VIN offline cache. Direct writes own and replace store_dir; validated completed stores should be treated as immutable inputs. Cluster jobs obtain crash-safe lifecycle semantics through temporary shard writes and atomic final promotion.

1.9.7.1 Attributes

Name Description
paths Repository path defaults used to resolve cache artifact destinations.
store_dir Standalone destination replaced by a direct write; never the VIN source store.
return_semantics Versioned return family recorded for the derived finite-candidate view.
discount_gamma Discount applied only to non-terminal selected TD transitions.
target_protocol_version Contract version separating target task inputs from oracle labels.
reason_code_version Version of persisted candidate-invalidity bit positions.
field_retention_policy Named policy describing which heavy oracle/audit payloads are retained.
source_offline_store_version Immutable VIN source-cache version copied into rollout provenance.
split_manifest_hash Hash binding the source split and ordered row ownership records.
q_h_chunk_states Number of state rows per chunk in the persisted derived q_h/ view.
target_eval_crop_max_points Fixed row width for oracle/eval target crop point payloads.
target_eval_crops_enabled Persist oracle/eval target crop point payloads for sampled audit shards.
oracle_query_mode Persisted hard-oracle candidate-query profile for Q_H supervision.
label_support_semantics Persisted relation between actor-valid rows and finite Q labels.

1.9.8 RolloutZarrStoreReader

rollouts.RolloutZarrStoreReader(store_dir)

Open a completed standalone rollout replay store in read-only mode.

The reader never repairs, migrates, or backfills arrays. Canonical factual tables remain the source of truth; q_h/ is a validated derived cache.

1.9.8.1 Methods

Name Description
candidate_shell_index Return the immutable shell-ordered candidate-row lookup for this reader.
array Read an array, returning -1 for supported unavailable provenance.
array_rows Read only selected first-axis rows from one canonical Zarr array.
validate Validate persisted contracts, optionally skipping unconsumed depth payloads.
manifest Read root attrs and the top-level sidecar manifest without payload arrays.
acquisition_row_context Resolve a chain or step to its authenticated, original generation context.
q_h_view Return the padded finite-candidate Q_H training view.
1.9.8.1.1 candidate_shell_index
rollouts.RolloutZarrStoreReader.candidate_shell_index()

Return the immutable shell-ordered candidate-row lookup for this reader.

The index is reader-local and derived only from canonical candidate columns. Reusing it prevents repeated whole-table scans in consumers that project several rollout steps from the same completed store.

1.9.8.1.2 array
rollouts.RolloutZarrStoreReader.array(path)

Read an array, returning -1 for supported unavailable provenance.

1.9.8.1.3 array_rows
rollouts.RolloutZarrStoreReader.array_rows(path, positions)

Read only selected first-axis rows from one canonical Zarr array.

1.9.8.1.4 validate
rollouts.RolloutZarrStoreReader.validate(validate_selected_depth_payload=True)

Validate persisted contracts, optionally skipping unconsumed depth payloads.

1.9.8.1.5 manifest
rollouts.RolloutZarrStoreReader.manifest()

Read root attrs and the top-level sidecar manifest without payload arrays.

1.9.8.1.6 acquisition_row_context
rollouts.RolloutZarrStoreReader.acquisition_row_context(table, row_id)

Resolve a chain or step to its authenticated, original generation context.

Physical packing renumbers rows but archives the source manifest and a hashed row mapping. Follow those bindings through repeated packing; return the acquisition manifest digest, original row ID and generation context. Missing, ambiguous or altered bindings fail rather than borrowing another chain’s configuration. Metadata is cached for this immutable reader.

1.9.8.1.7 q_h_view
rollouts.RolloutZarrStoreReader.q_h_view(discount_gamma=None)

Return the padded finite-candidate Q_H training view.

Let S be the number of materialized step/state rows and A the maximum step-local full-shell width. Candidate ids, masks, positions, one-step labels, and reason bitsets are ndarray["S A", ...]; source/target ids, selected-action indices, and TD linkage are ndarray["S", ...]. Shorter shells are padded with id -1, false masks, and NaN labels.

valid_action_mask is the hard actor-selectable mask. q_train_mask is stricter: it also requires a label-valid target/GT state and a finite explicit target-root-gain label. Finite target RRI remains an independent diagnostic-availability predicate. Invalidity is represented by masks and versioned reason bitsets, never by a low score. TD reward/linkage describes the factual selected action only; unselected action labels remain one-step oracle supervision.

1.9.8.1.7.1 Parameters
Name Type Description Default
discount_gamma float | None When None, read the persisted q_h/ cache. Otherwise rebuild the view from canonical factual tables using this discount for non-terminal selected transitions. None
1.9.8.1.7.2 Returns
Name Type Description
dict[str, np.ndarray] Mapping containing all :data:Q_H_ARRAY_NAMES, preserving the
dict[str, np.ndarray] S state axis and padded A full-shell action axis.
Back to top