1 reporting

reporting

Immutable scientific reports shared by Streamlit, CLI, and Typst.

The public interface is intentionally small: validate a ScientificReportConfig, construct its ScientificReportBuilder, build a ReportSnapshot once, and pass that exact snapshot to write_report_snapshot. Domain calculations remain in their rollout and W&B owners; the reporting module owns freezing, notation validation, canonical Plotly specifications, and publication.

1.1 Package guide

aria_nbv.reporting builds figures, tables, and named quantities once, seals them in an immutable ReportSnapshot, and gives the exact snapshot to Streamlit preview and static/Typst export. Export never receives a report recipe, so it cannot silently reacquire a changed W&B run or rollout store.

Code
flowchart LR
  C["Shared TOML recipes"] --> D["ConfigDocument and Pydantic"]
  R["Rollout Zarr stores"] --> S["Evidence snapshot"]
  W["Frozen W&B runs"] --> S
  M["Frozen measurement audit"] --> S
  Q["Frozen QH diagnostic assignment"] --> S
  N["symbols.typ to notation.yml"] --> B["ScientificReportBuilder"]
  D --> B
  S --> B
  B --> P["Immutable ReportSnapshot"]
  P --> A["Streamlit renderer"]
  P --> E["Static Plotly exporter"]
  E --> T["report.json and SVG or PNG to Typst"]

  classDef input fill:#D5E8D4,stroke:#82B366,color:#17202A,stroke-width:1.5px,rx:0,ry:0;
  classDef output fill:#F8CECC,stroke:#B85450,color:#17202A,stroke-width:1.5px,rx:0,ry:0;
  classDef compute fill:#E1D5E7,stroke:#9673A6,color:#17202A,stroke-width:1.5px,rx:8,ry:8;
  classDef data fill:#F5F5F5,stroke:#9E9E9E,color:#17202A,stroke-width:1.2px,rx:0,ry:0;
  class C,R,W,M,Q,N input;
  class D,S,B,E compute;
  class P data;
  class A,T output;

flowchart LR
  C["Shared TOML recipes"] --> D["ConfigDocument and Pydantic"]
  R["Rollout Zarr stores"] --> S["Evidence snapshot"]
  W["Frozen W&B runs"] --> S
  M["Frozen measurement audit"] --> S
  Q["Frozen QH diagnostic assignment"] --> S
  N["symbols.typ to notation.yml"] --> B["ScientificReportBuilder"]
  D --> B
  S --> B
  B --> P["Immutable ReportSnapshot"]
  P --> A["Streamlit renderer"]
  P --> E["Static Plotly exporter"]
  E --> T["report.json and SVG or PNG to Typst"]

  classDef input fill:#D5E8D4,stroke:#82B366,color:#17202A,stroke-width:1.5px,rx:0,ry:0;
  classDef output fill:#F8CECC,stroke:#B85450,color:#17202A,stroke-width:1.5px,rx:0,ry:0;
  classDef compute fill:#E1D5E7,stroke:#9673A6,color:#17202A,stroke-width:1.5px,rx:8,ry:8;
  classDef data fill:#F5F5F5,stroke:#9E9E9E,color:#17202A,stroke-width:1.2px,rx:0,ry:0;
  class C,R,W,M,Q,N input;
  class D,S,B,E compute;
  class P data;
  class A,T output;

1.2 Build, preview, and export

1.2.1 Generation post-hoc analysis

reporting.generation_posthoc writes a standalone, sealed HTML/table/SVG report from rollouts.inspection.generation_posthoc.GenerationPosthocEvidence. It consumes completed reductions and does not reacquire stores or fit a learner. The cold reader validates the exact files and returns recursively immutable tables and asset bytes. This standalone product has its own explicit schema; it is not a new ScientificReportBuilder section.

datasets.bundles.posthoc_context binds source-root statistics, the frozen scene assignment, complete disposition accounting, compatible worker clocks, TRAIN-only authored nominations, and optional archived Q1 validation states. Candidate masks, missing values, physical scenes, target tasks, prefix risk sets, and attempted costs retain distinct denominators. Conditional gain headroom and geometric redundancy are descriptive proxies, not proof of learning improvement or policy value.

The resumable CPU runner opens immutable stores in spawned workers and keeps source identities and derived cache receipts. For an explicit input catalog:

uv run --project aria_nbv --no-sync python scripts/analyze_generation_posthoc.py \
  --catalog /absolute/path/to/catalog.json \
  --master-events /absolute/path/to/frozen-master-events.jsonl \
  --stage train --workers 16 --output /absolute/path/to/new-analysis --render

Choose workers using the same fixed subset with --benchmark 1,2,4,8,12 and an explicit --limit; the runner seals exact serial/parallel comparisons, observes worker RSS/swap, and checks source-file fingerprints. Further worker counts are appropriate only after the measured resource guard passes. Resume reuses matching sealed cache products; a changed source, catalog, or stage binding receives a different identity. Source stores are never rewritten.

Verify the new interfaces with the generation post-hoc domain, VIN numeric evidence, report, context, and runner tests. Register retained static outputs through the existing figure gallery; gallery registration does not establish thesis inclusion or scientific promotion.

from aria_nbv.reporting import ScientificReportConfig, read_report_bundle, write_report_snapshot

# First replace the template's empty source selections with immutable stores
# and exact W&B run IDs.
recipe = ScientificReportConfig.from_toml(".configs/reports/qh-thesis.toml")
snapshot = recipe.setup_target(wandb_api=wandb_api).build()

# Streamlit reconstructs go.Figure from figure.plotly_json.
for figure in snapshot.figures:
    st.plotly_chart(plotly.io.from_json(figure.plotly_json.decode()))

# Static export consumes the exact previewed snapshot; it performs no source reads.
write_report_snapshot(snapshot, Path("build/qh-thesis-report"))

# Later consumers can reconstruct the exact snapshot without source access.
verified_snapshot = read_report_bundle(Path("build/qh-thesis-report"))

Static consumers that need the already-verified figure fallbacks can call read_report_bundle_with_assets(path). It returns the same snapshot, the manifest SHA-256, and immutable (relative_path, bytes) entries captured by the bundle reader’s single validation transaction. Consumers can copy those bytes without reopening evidence sources or trusting unverified asset paths. snapshot is the reconstructed typed report; manifest_sha256 hashes the captured manifest.json bytes. file_bytes is sorted by relative path and includes manifest.json, the report, recipe, Plotly specifications, and static assets as captured during that validation transaction.

nbv-report build --config ... --output ... is the same composition as the Python example. A bundle contains recipe.toml, report.json, canonical Plotly JSON under figures/, static assets under assets/, and an integrity manifest.json. Two-dimensional figures default to SVG; WebGL/3D figures use configured high-resolution PNG.

1.2.2 Broad-queue selected motion

nbv-report broad-scene --queue-root ... --output ... freezes the validated queue-prefix accounting and the successful-store selected-motion readout in one source-bound export. The Rollout Dataset page calls the same broad_scene_motion_summary and broad_scene_motion_figures producers, so its translation/rotation tails and revisit/occupancy view match the CSV/JSON/SVG/PNG export. Headline distributions reduce repeated stores and selected steps to one value per source root. Queue attempts, successful motion stores, source roots, and factual selected steps retain separate denominators; valid zero-step stores remain visible and conditional fractions are unavailable rather than zero.

This completes the general queue-wide motion/readout portion deferred from #504/#505: canonical queue composition, selected-step/store/root tables, shared motion figures, frozen CLI export, and Streamlit consumption. It does not add a new queue ledger parser, change the score-floor-specific matched comparison, or restore the broader historical #504/#505 experiment dashboard. Target-relative angular occupancy describes selected-camera direction cells. It is not occlusion-aware visible-surface coverage, and untimed pose increments do not measure speed, acceleration, jerk, or motion smoothness.

1.2.3 Bounded evidence catalog

The report CLI and Scientific Reporting page share one explicit-root catalog. Directory discovery stays inside the selected root. Before a domain reader runs, the catalog also inventories external paths named directly by a candidate recipe plan or QH assignment and charges that work against the same path and file ceilings. It rejects symlinks in candidate and referenced evidence; authoritative readers may then reopen the admitted exact paths. Familiar marker names are only candidates: report bundles, recipe plans, measurement summaries, and QH assignments enter the catalog only after their authoritative readers validate them. Invalid candidates remain visible with their validation error and without a fabricated digest. Typed foreign plans, summaries and assignments are skipped; malformed supported schemas stay visible for their authoritative reader error.

registration.json uses aria-nbv-experiment-registration-v1 to associate experiment evidence with distinct attempt IDs. reporting.discovery exposes read_experiment_registration and immutable registration DTOs in the same catalog’s separate registrations projection. Evidence paths are sidecar-relative and their SHA256 is freshly checked; store references are checkout-relative lexical declarations and may be unavailable. Registration validity certifies that byte association, not store payloads, scientific admission or promotion. Sidecar/evidence paths reject symlinks before resolution; relative declarations reject traversal. Duplicate experiment/attempt identities are rejected while distinct attempt aliases to the same store remain distinct. Experiments and nested attempts each consume one entry from the same global budget as report entries, across all sidecars. Defaults remain depth6/entries100; callers can explicitly request a larger finite budget. An oversized sidecar is not partially admitted. The direct reader limits sidecar bytes to 2 MB and defaults to 100 records.

cd aria_nbv
uv run nbv-report index --root /absolute/evidence/root \
  --max-depth 6 --max-paths 10000 --max-files 5000 --max-entries 100

The command prints deterministic aria-nbv-report-catalog-v2 JSON. The Streamlit page performs the same scan only after Index evidence is selected. A raw recipe, measurement, or QH entry is bound into the existing ScientificReportConfig interface and dispatched through ScientificReportBuilder; a published bundle is cold-read through the bundle validator. Neither path writes to the evidence root. QH assignment/receipt admission delegates to the Lightning-owned typed diagnostic reader; catalog and reporting code never parse or independently reduce those artifacts.

1.2.4 Recipe-experiment reports

Config-v2 adds a recipe source and section for one frozen Oracle experiment plan. Oracle remains the only owner that reads plans, receipts, and promoted stores or computes matched-prefix effects. Reporting freezes its typed attempt product, including every planned unit and missing/rejected dispositions, then reuses the rollout-owned matched-prefix figure. Missing factual endpoints stay unavailable rather than becoming zero reward.

Config-v1 still produces snapshot-v1/report-bundle-v2 byte semantics. A v2 recipe produces snapshot-v2/report-bundle-v3, whose report declares its exact snapshot schema. Cold readers dispatch only these two explicit combinations; historical bundles are read in place and never rewritten.

1.2.5 Measurement-sensitivity reports

Config-v2 also admits one Oracle-owned measurement source and section. The source names the frozen audit summary.json; the Oracle reader validates the assignment and raw artifact bytes once and returns their captured content digest. Reporting preserves that identity, the fixed raster/root/depth protocol, accuracy/completeness components, repeat and no-op controls, and the separate mesh-retessellation table. It reuses the rollout presentation figure without reopening the JSON artifacts:

[sources.measurement]
summary_path = "path/to/summary.json"

[[sections]]
kind = "measurement"
id = "measurement"

Each row remains qualified by its fixed audit case. Counts describe diagnostic support; they are not population estimates, and endpoint gains are not pooled across the two retained cases.

1.2.6 Finite-horizon diagnostic reports

Config-v2 admits one Lightning-owned qh_diagnostic source and section. The source names the frozen assignment directory; the diagnostic reader validates its cohort, held-out scene partitions, cell dispositions, fit/evaluation receipts before reporting receives a typed product:

[sources.qh_diagnostic]
root = "path/to/qh-diagnostic-assignment"

[[sections]]
kind = "qh_diagnostic"
id = "qh"

The snapshot keeps every planned cell, including missing and failed cells; supported H1 practical-regret values remain scene-held-out and seed-reduced. The figure describes prediction of the retained original labels, not calibrated reconstruction quality or policy return. Metric-history telemetry is separate and optional; no loss curve is inferred.

1.2.7 Rollout distribution figures

A rollout section can freeze complete-population figures from the same admitted report-v1 tables that it places in the snapshot:

[[sections]]
kind = "rollout"
id = "rollout"
distribution_figures = [
  "candidate_validity",
  "rejection_reasons",
  "selected_steps",
  "terminal_endpoints",
]

Candidate masks remain separate predicates rather than a sequential funnel. Selected-step panels retain missing-value support, and terminal endpoints are the greatest persisted factual steps rather than independent endpoint evaluations. Every figure names its complete canonical source table in the immutable ReportSnapshot. The Scientific Reporting page and static exporter consume those exact frozen Plotly specifications without recomputing the reductions.

1.2.8 Target-frame S² reports

The rollout_s2 section freezes the same target-frame movement, camera-forward, and calibrated proxy-frustum Plotly figures shown by the stored-rollout application:

[[sections]]
kind = "rollout_s2"
id = "s2"
channels = ["movement", "view_direction", "frustum"]

[sections.analysis]
azimuth_bins = 36
elevation_bins = 18
projection_limit = 2000

The complete equal-solid-angle histograms and scalar support quantities are computed from every admitted selected step. projection_limit bounds only the incidence overlay. Surface colour represents complete cell counts; incidence colour represents rollout-chain index and marker shape represents persisted step index. The frustum channel reports geometric potential support on a geometric-mean-scale target proxy, not observed target-mesh visibility.

.configs/reports/s2-thesis-pilot.toml is the exact pilot recipe used by the development thesis. Regenerate its immutable bundle with:

cd aria_nbv
uv run nbv-report build \
  --config ../.configs/reports/s2-thesis-pilot.toml \
  --output ../docs/typst/thesis/data/s2-rollout-pilot

Typst loads the resulting report.json and resolves figure paths through experiment_data.typ; it does not execute Python or reacquire rollout data.

The manifest fingerprints Plotly, Kaleido, Chrome, the resolved font files, template payloads, locale, timezone, and Plotly’s MathJax/TopoJSON defaults. Report execution never installs browser assets. Recipes intended for isolated publication must avoid map tiles, remote images, and other URL-backed traces; the exporter rejects explicit remote resources before launching Kaleido.

1.3 Ownership

  • aria_nbv.rollouts owns Zarr validation, evidence compatibility, rollout reductions, configured S² acquisition, and the shared Plotly builder used by Streamlit and this module. Reporting freezes those products without reimplementing geometry.
  • W&B remains an external evidence store. Confirmatory recipes name exact, finished run IDs and acquire complete scan_history rows.
  • docs/typst/shared/symbols.typ and equations.typ own notation and theory. Reports carry only validated canonical IDs.
  • This README owns the public workflow and architecture. Public Python docstrings own exact fields, invariants, failures, and lifecycle. Typst owns scientific claims, captions, equations, and interpretation.

See the tracked API reference index for the generated reporting interface. Report construction is explicitly dispatched; configuration inspection and ordinary Streamlit reruns do not read full rollout arrays or W&B histories.

1.3.1 Development collection readouts

reporting.score_floor validates the exact baseline/floor writer-config contrast and immutable successful stores, then reduces matched completed-store pairs to independent source roots. Its pandas tables and Seaborn figure factories are the same objects used by the versioned CSV/SVG export and the Rollout Dataset page’s explicit score-floor analysis; Streamlit does not reimplement the estimator or redraw the figures. The build is intentionally explicit because it scans all forty successful stores. Queue-wide attempt accounting remains unavailable, and the original stores stay read-only.

1.4 Immutable performance evidence

reporting.performance_evidence owns evaluator-result validation, the digest of the exact input bytes, and ordered publication to W&B and OMX. It is auxiliary experiment reporting; it does not define a learning objective or save model weights. The cohesive record_checkpoint operation hides the pending → publish/readback → final checkpoint sequence. A failed publication leaves the checkpoint blocked.

Validate a version-two evaluator result without publication:

from pathlib import Path
from aria_nbv.reporting.performance_evidence import record_checkpoint

outcome = record_checkpoint(Path("result.json"), dry_run=True)

The existing aria_nbv/scripts/record_performance_checkpoint.py CLI remains available. Its --dry-run option validates and hashes without W&B or OMX calls. Formal publication uses PathConfig().root for both OMX subprocesses, independently of the caller’s working directory. Result bytes, provenance and metric values remain evaluator-owned; publication never rewrites the result.

Python callers migrate from aria_nbv.performance_checkpoint to the explicit aria_nbv.reporting.performance_evidence leaf. The reporting root does not re-export this separate workflow.

Proof from the repository root:

cd aria_nbv
uv run pytest tests/test_performance_checkpoint.py

The tests cover exact-byte digests, invalid/nonfinite results, publication ordering and failure, W&B readback, and configured-root execution from an unrelated working directory. External services are mocked.

1.5 Nested surface-reference evidence

For a completed fixed-candidate 16,384/65,536 surface extension, run python -m aria_nbv.reporting.surface_reference --assignment ASSIGNMENT --run-dir RUN --output-dir NEW_OUTPUT. The Oracle reader verifies the historical v1 or current v3 assignment, receipt, source-attempt, and result-attempt bindings before returning matched scores. Mixed versions and changed aggregate verdicts fail admission. The new report-v2 summary records the producer comparison schema, source hashes, scene support denominators, and the Oracle’s independent top-set regret. Constant-score strata have undefined rank correlation and appear as null aggregates when unsupported. Use a new output directory for each reduction; retained measurements and earlier reports remain immutable. Scene means count physical scenes, not independent candidate rows or corpus admission.

1.6 Retained recipe-family evidence

For retained family opportunity, run python -m aria_nbv.reporting.recipe_families --manifest INPUTS --output-dir OUTPUT. The manifest names exact completed stores, source receipt elapsed times and chain lengths; the export records the manifest’s exact SHA-256 digest. The reader acquires one canonical typed recipe report per plan, scans the named stores, reacquires the report, and rejects any snapshot drift. Canonical plan, report and store identities are the evidence authority. Additional context fields in the input manifest are not treated as evidence and are not copied to the output. A display cohort must share measurement and evaluator identities, while each displayed arm must retain one exact generation cohort. The reader reuses rollouts.inspection.candidate_audit_rows. Scene-level validity, best finite labelled gain, invalidity reasons and factual H8/H12/H16 starts retain cohort boundaries. Removing a family from an already sampled shell is a diagnostic only; it does not redraw poses or estimate policy return. Tail-start rates condition on successful stores and their observed execution time; the export retains full plan dispositions so rejected, failed and unreached units remain visible. These static research figures are separate from the immutable ReportSnapshot path used by the scientific report builder.

1.7 W&B ownership

Run discovery, sampled history, local media, exploratory plots and the existing exact report acquisition transaction live in wandb. The report builder remains the public entrypoint for immutable scientific evidence.

1.8 Study consumers and reproduction

These standalone exports use admitted domain products; they have distinct output contracts from ReportSnapshot. Source docstrings own exact admission and failure rules, and experiment publications own frozen protocols, results and receipts. Create fresh output directories, hydrate any required LFS payloads, and use the current package implementation rather than archived producers. The complete pre-consolidation descriptions remain at this immutable revision.

1.8.1 Bounded generation-throughput evaluator

The evaluator consumes the Oracle-owned source-contrast reader:

python -m aria_nbv.reporting.generation_throughput assignment.json \
  --brief research-brief.md --output-dir NEW_OUTPUT \
  --goal-slug generation-throughput-roi-20261003

Schema-v2 evidence passes only the prospectively frozen three-scene, two-block log-cost contrast; missing costs stay unavailable. This engineering decision is not a population significance test or corpus admission. Captured per-step 48px causal equality differs from persisted float16 240px depth. Publication/readback through scripts/record_performance_checkpoint.py and independent review are separate gates; see the performance-evidence workflow above.

1.8.2 Portable throughput attribution profiles

python -m aria_nbv.reporting.generation_profiles inputs.json --output-dir NEW_OUTPUT

The profile exporter validates canonical recipe, renderer, phase and worker receipts. The E33 publication owns the six-attempt protocol, tables, reproduction and unchanged negative optimization decision. Recorded endpoint/observer audits are not recomputed by this exporter. Missing outcomes remain explicit; unsealed profiler probes and overlapping clocks establish neither additive attribution nor production gain.

1.8.3 Origin-aware E28 selector publication

The selector reader admits read_selector_bundle(bundle, expected_manifest_sha256=...) with an external manifest pin. The E28 publication and its terminal supplement own protocol, captured support and historical outcomes. Cold readback verifies consumed publication/plan/writer bytes; ancillary manifest entries remain explicitly unverified and are not admitted evidence. Historical capture and current readback identities stay separate. The live reader additionally checks canonical recipe admission and original stores.

python -m aria_nbv.reporting.selector_figures --bundle BUNDLE \
  --manifest-sha256 SHA256 --output NEW_OUTPUT
python -m aria_nbv.reporting.selector_geometry --bundle BUNDLE \
  --manifest-sha256 SHA256 --output NEW_OUTPUT

Both consumers use the admitted readout, without another reducer or sampler. Missing, failed and unreached arms retain intended denominators; factual states and shadows retain originating arms. Conditional survivor means are not all-attempt effects. Untimed geometry does not establish human naturalness or policy return. The separate E29 terminal-effect delta remains deferred under issue #433; these entrypoints do not revive its historical combined E28/E29 adapter.

1.8.4 Matched H16 renderer figures and physical paths

Rollout figures and trajectory figures consume the canonical renderer reader. The E31 publication preserves the failed checkpoint; E32 owns the later qualified recipe and its bounded descriptive cost evidence.

From the repository root:

PYTHONPATH=aria_nbv python aria_nbv/scripts/verify_renderer_h16_readback.py \
  --plan PLAN --bindings BINDINGS --output NEW_READBACK.json
PYTHONPATH=aria_nbv python aria_nbv/scripts/plot_renderer_h16_trajectories.py \
  --analysis NEW_READBACK.json --runtime-worktree "$PWD" --output NEW_FIGURES

Figures preserve intended attempts and unavailable measurements; seeds reduce within physical scenes before descriptive scene means. Qualified timing requires successful full-horizon arms and explicit domain qualification. Positions are metres in the initial target-aligned, world-Z-up frame; discrete bend/yaw/radius are geometric proxies, not timed motion or perceptual naturalness. Use --checkpoint-stopped for plan-bound genuinely unreached intentions. Exports create directories exclusively and record hashes; they add no acquisition, Streamlit consumer, whole-campaign efficiency claim or corpus promotion.

1.8.5 Transport retained H16 acquisition evidence

From the repository root, the transport adapter provides:

python aria_nbv/scripts/package_renderer_h16_evidence.py pack --source ROOT --output BUNDLE
python aria_nbv/scripts/package_renderer_h16_evidence.py hydrate --source BUNDLE --output ROOT

The E31 portability supplement owns its dated cold-readback proof. The adapter verifies inventory/member hashes, keeps original bytes and absolute identities, requires hash-bound relocated config copies, and admits through the canonical recipe reader. Inputs must remain immutable; digest/drift checks do not provide an atomic snapshot. Symlinks and special files fail closed. Twenty terminal intentions, or an explicit --checkpoint-stopped subset with terminal receipts and genuinely unreached intentions, are required; interrupted or receipt-less stores are not closure. Transport closure does not establish renderer equivalence, complete campaign accounting, corpus admission or promotion.

1.8.6 Consolidated scorer studies

Config-v2 scorer_study selects Q1 or continuing-QH evidence through an externally pinned archive. Use .configs/diagnostics/scorer-q1-report.toml or scorer-qh-report.toml with nbv-report build --config ... --output NEW_DIRECTORY; the reporting extra supplies static-export dependencies. Acquire once, then read_report_bundle reconstructs the frozen snapshot without reopening sources.

Scorer presentation owns current consumer/output contracts; Lightning study admission owns support, version and checkpoint-role validation. The scorer publication owns sealed identities, historical producer provenance and scientific qualifications. Relocation does not rewrite sealed configuration identities. Q1 retains physical-scene pairing, seed/checkpoint conditioning and intervals; interrupted QH retains failure/charge status with no fabricated completed comparisons. These exposed-development sources remain pilot-only.

1.8.7 Development generation thesis projection

generation_thesis.write_generation_thesis_projection consumes the immutable cold readback returned by read_generation_posthoc_report, plus an independently verified historical R1 member map. It writes a fresh closed projection and two 165 mm SVGs; the sibling .sha256 file is the external manifest trust anchor. read_generation_thesis_projection(..., expected_manifest_sha256=...) verifies all bytes without opening source stores. The schema remains a separate aria-nbv-generation-thesis-projection-v1 development product.

The family figure separates Q-train yield from actor-label exclusive-best state fraction. Ties remain non-exclusive; a scene with any state lacking finite actor-label gains has an unavailable exclusive-best fraction. The acquisition figure retains native scene-step Q-train means and finite actor/oracle-label p90–p10 spans, with explicit finite/missing state support. Both figures show physical-scene dots and equally weighted scene centers; acquisition IQRs are linear-quantile descriptive spread. Sparse reached/intended annotations use only the native H1/2/3/5/8/12/16 risk sets. Historical TRAIN, new-root TRAIN and exposed validation remain separate, while the Mac diagnostic remains in coverage only. Qualified lineage, unchanged nominations and limitations accompany the figures. No fit, resampling, recipe selection, causal claim or corpus promotion is added.

Verify this seam with tests/reporting/test_generation_thesis.py together with the native generation reporting and rollout post-hoc tests.

1.9 Sealed-file acquisition

Native bundles, generation post-hoc/thesis products and compact public Q1 publications share descriptor-relative ordinary-file acquisition. Each reader retains its manifest, JSON, scientific-source and external-pin rules. Native bundles reject aliases throughout the root path; generation and compact public readers preserve their supported ancestor aliases while rejecting a symlink at the terminal root. Authenticated products consume the captured bytes rather than reopening asset paths. Native Q1’s historical path-based reader remains a separate format and is not covered by this acquisition guarantee.

1.10 Scientific reading path

The experiment maintenance contract owns the report and mission outline. Producers use the private _presentation.render_document shell and adjacent report.css for standalone, responsive documents; these helpers do not admit evidence or compute statistics. Keep native measurements and scientific table/figure data stable across presentation revisions, with distinct authored-context and delivery identities. Historical sealed outputs remain unchanged.

Maintained benchmark and R1 presentation live in reporting.m5_benchmark and reporting.r1_supervision; their existing command-line entry points remain adapters.

1.11 Figure identity

figure_identity resolves callable CAP handles, semantic output keys and exact sealed-result FIG identities from the generated catalog projection. It imports no scientific plotting implementation and retains no figure, tensor, dataset or builder instance. figure_origins separately maps supported current-builder report outputs through their exact section/result contracts. It cannot recover unknown historical producer revisions from a retained recipe. Neither owner changes sealed report bytes or certifies scientific acceptance.

The gallery registration workflow owns metadata generation, source/consumer/asset coverage and handle-first lookup. Test the runtime at tests/reporting/test_figure_identity.py and current report-origin mappings at tests/reporting/test_figure_origins.py.

1.11.1 Archived Plotly display compatibility

plotly_decode.decode_frozen_plotly strictly decodes saved specifications first. For older Plotly templates, it may omit unsupported default trace families that are absent from both data and animation frames, and obsolete style-only Mapbox template defaults when no Mapbox trace or explicit Mapbox layout is used. It never removes active traces, used styles or explicit layout settings. Other validation errors remain errors. This adaptation affects an in-memory display copy; retained specifications and sealed bundle hashes remain unchanged.

Streamlit identifies omitted template paths beside the chart. Static rendering records the decoder policy/source in the exporter fingerprint, and gallery build logs identify the omitted paths. The exporter honours an explicit BROWSER_PATH before automatic browser discovery. Optional renderer/browser preparation is an explicit environment step; reading metadata never downloads or launches them.

1.12 Classes

Name Description
NamedQuantity One named scalar linked to provenance and optional canonical notation.
ReportColumn One ordered table column and its canonical notation binding.
ReportExplanation Presentation-free interpretation attached to one scientific result.
ReportFigure Canonical Plotly figure shared by Streamlit and static export.
ReportRequest Optional section/result selection for one explicit build dispatch.
ReportSnapshot Immutable transaction consumed by Streamlit and static/Typst export.
ReportTable Canonical immutable table with typed scalar cells.
ReportWriteReceipt Identity of one atomically published report directory.
ScientificReportBuilder Materialize one validated recipe into a sealed report snapshot.
ScientificReportConfig Build one immutable, provenance-closed scientific report snapshot.
ScientificReportError Contextual failure crossing the reporting interface.
SourceIdentity Frozen identity and provenance for one materialized evidence source.
VerifiedReportBundle A cold-verified snapshot and exact bundle bytes for static consumers.

1.12.1 NamedQuantity

reporting.NamedQuantity(id, value, unit, n, aggregation, source_ids, symbol_id)

One named scalar linked to provenance and optional canonical notation.

1.12.1.1 Attributes

Name Description
id Globally unique result identifier.
value Typed scalar; missing values remain None rather than fabricated zeroes.
unit Physical or reporting unit, when meaningful.
n Population size underlying the quantity, when available.
aggregation Code-owned aggregation name such as mean or count.
source_ids Source identities that support the value.
symbol_id Canonical Typst symbol ID; None is an explicit operational opt-out.

1.12.2 ReportColumn

reporting.ReportColumn(id, symbol_id)

One ordered table column and its canonical notation binding.

1.12.2.1 Attributes

Name Description
id Persisted column identifier.
symbol_id Canonical Typst symbol ID; None is an explicit operational opt-out.

1.12.3 ReportExplanation

reporting.ReportExplanation(
    metric_id,
    question,
    answer,
    narrative,
    evidence_role,
    population,
    unit,
    support_result_ids,
    source_fields,
    theory,
)

Presentation-free interpretation attached to one scientific result.

The explanation names supporting result IDs instead of rebuilding factual counts or reductions. Its theory field carries registry identifiers only; aria_nbv.reporting.notation.resolve_theory validates and projects those identifiers from the generated canonical notation owner.

1.12.3.1 Attributes

Name Description
metric_id Persisted metric identifier whose values the narrative interprets.
question Reader-facing question answered by the result.
answer Concise interpretation of the observed result.
narrative Ordered supporting paragraphs covering meaning and limitations.
evidence_role Information role of the interpreted values.
population Actual rows or entities summarized by the result.
unit Human-readable unit or dimensionless scale of the metric.
support_result_ids Report quantity or table IDs carrying factual support and missingness.
source_fields Persisted source fields from which the result was reduced.
theory Required canonical equation, symbol, and glossary identifiers.

1.12.4 ReportFigure

reporting.ReportFigure(
    id,
    plotly_json,
    source_ids,
    source_result_ids,
    symbol_ids,
    uses_webgl,
)

Canonical Plotly figure shared by Streamlit and static export.

1.12.4.1 Attributes

Name Description
id Globally unique result identifier.
plotly_json UTF-8 canonical Plotly JSON with sorted keys and no trace UIDs.
source_ids Source identities supporting the figure.
source_result_ids Snapshot quantity/table results consumed by the figure builder.
symbol_ids Canonical symbol IDs used by axes, legend, or explanation.
uses_webgl Whether static export must use the configured raster profile.

1.12.5 ReportRequest

reporting.ReportRequest(section_ids=(), result_ids=())

Optional section/result selection for one explicit build dispatch.

1.12.5.1 Attributes

Name Description
section_ids Selected section IDs; empty means every configured section.
result_ids Selected exact result IDs; empty means every result in selected sections.

1.12.6 ReportSnapshot

reporting.ReportSnapshot(
    schema_version,
    evidence_status,
    config_sha256,
    notation_sha256,
    source_identities,
    quantities,
    tables,
    figures,
    resolved_recipe,
    snapshot_sha256,
)

Immutable transaction consumed by Streamlit and static/Typst export.

Exporters accept this object, never a report config. Consequently an export cannot reacquire W&B history, reread a rollout store, or recompute a figure after the user has previewed it.

1.12.6.1 Attributes

Name Description
schema_version Closed snapshot schema version.
evidence_status Evidence class enforced during acquisition and publication.
config_sha256 Digest of the canonical validated recipe.
notation_sha256 Digest of the generated canonical notation registry.
source_identities Source identities sorted by stable ID.
quantities Named quantities sorted by result ID.
tables Tables sorted by result ID.
figures Figures sorted by result ID.
resolved_recipe Validated TOML recipe frozen at build time.
snapshot_sha256 Digest of all preceding snapshot fields.

1.12.6.2 Methods

Name Description
create Canonicalize ordering and seal a snapshot with its content digest.
result Return one result by stable ID or raise KeyError.
1.12.6.2.1 create
reporting.ReportSnapshot.create(
    evidence_status,
    config_sha256,
    notation_sha256,
    source_identities,
    quantities,
    tables,
    figures,
    resolved_recipe,
    schema_version='aria-nbv-report-snapshot-v1',
)

Canonicalize ordering and seal a snapshot with its content digest.

1.12.6.2.2 result
reporting.ReportSnapshot.result(result_id)

Return one result by stable ID or raise KeyError.

1.12.7 ReportTable

reporting.ReportTable(id, columns, rows, source_ids)

Canonical immutable table with typed scalar cells.

1.12.7.1 Attributes

Name Description
id Globally unique result identifier.
columns Ordered column contract.
rows Canonical row-major scalar values.
source_ids Source identities supporting the table.

1.12.8 ReportWriteReceipt

reporting.ReportWriteReceipt(
    destination,
    manifest_sha256,
    snapshot_sha256,
    assets,
)

Identity of one atomically published report directory.

1.12.8.1 Attributes

Name Description
destination Absolute promoted report directory.
manifest_sha256 Digest of the exact exported manifest bytes.
snapshot_sha256 Digest of the immutable input snapshot.
assets Sorted relative asset path and SHA-256 pairs.

1.12.9 ScientificReportBuilder

reporting.ScientificReportBuilder(
    config,
    *,
    wandb_api=None,
    root=None,
    _recipe_evidence=None,
    _measurement_evidence=None,
    _qh_evidence=None,
)

Materialize one validated recipe into a sealed report snapshot.

Construction stores configuration and injected clients only. Expensive W&B and rollout reads occur exclusively in :meth:build, which Streamlit and CLI callers invoke explicitly. Each configured source family is acquired at most once per build and reused by all selected sections.

1.12.9.1 Methods

Name Description
build Acquire selected evidence once and return a provenance-closed snapshot.
1.12.9.1.1 build
reporting.ScientificReportBuilder.build(request=None)

Acquire selected evidence once and return a provenance-closed snapshot.

1.12.10 ScientificReportConfig

reporting.ScientificReportConfig()

Build one immutable, provenance-closed scientific report snapshot.

The config is the durable recipe shared by CLI and Streamlit. Calling :meth:setup_target injects external clients and canonical-notation root; parsing or describing the config performs no W&B or rollout payload reads.

1.12.10.1 Attributes

Name Description
schema_version Closed recipe schema version.
evidence_status Scientific evidence class enforced by source and export gates.
sources Existing evidence-store selections; credentials and clients are excluded.
sections Closed, code-owned report products in author-selected order.
theme Shared interactive/static Plotly presentation settings.
export Static renderer settings recorded in the exported manifest.

1.12.10.2 Methods

Name Description
setup_target Construct a builder with late-bound external adapters.
bind_rollout_stores Return a validated recipe bound to an explicit rollout population.
rollout_s2_section Return one configured S2 section or fail before evidence acquisition.
validate_build_readiness Fail before client construction when selected source selectors are incomplete.
1.12.10.2.1 setup_target
reporting.ScientificReportConfig.setup_target(wandb_api=None, root=None)

Construct a builder with late-bound external adapters.

1.12.10.2.2 bind_rollout_stores
reporting.ScientificReportConfig.bind_rollout_stores(
    store_paths,
    *,
    sidecar_paths=(),
)

Return a validated recipe bound to an explicit rollout population.

This immutable composition helper is shared by interactive previews and report automation. It replaces only the rollout source selection; section analysis, Plotly theme, evidence status, export policy, and any configured W&B source remain unchanged.

1.12.10.2.3 rollout_s2_section
reporting.ScientificReportConfig.rollout_s2_section(section_id)

Return one configured S2 section or fail before evidence acquisition.

1.12.10.2.4 validate_build_readiness
reporting.ScientificReportConfig.validate_build_readiness(section_ids=())

Fail before client construction when selected source selectors are incomplete.

1.12.11 ScientificReportError

reporting.ScientificReportError(code, message, result_id=None, source_id=None)

Contextual failure crossing the reporting interface.

1.12.11.1 Attributes

Name Type Description
code ReportErrorCode Stable machine-readable category.
message str Human-readable failure detail.
result_id str | None Optional result whose construction or export failed.
source_id str | None Optional source whose acquisition or identity check failed.

1.12.12 SourceIdentity

reporting.SourceIdentity(id, kind, sha256, provenance)

Frozen identity and provenance for one materialized evidence source.

1.12.12.1 Attributes

Name Description
id Stable recipe-local source identifier.
kind Owning source family.
sha256 Digest of the normalized source identity and acquired evidence.
provenance Sorted non-secret provenance key/value pairs.

1.12.13 VerifiedReportBundle

reporting.VerifiedReportBundle(snapshot, manifest_sha256, file_bytes)

A cold-verified snapshot and exact bundle bytes for static consumers.

The file set is captured in the same read transaction that validates the manifest, paths, asset digests, and snapshot. Consumers can publish HTML and static fallbacks without reopening the source bundle or raw evidence.

1.12.13.1 Attributes

Name Description
snapshot Typed snapshot reconstructed from the validated bundle bytes.
manifest_sha256 SHA-256 of the exact manifest.json bytes in file_bytes.
file_bytes Sorted bundle-relative POSIX paths and captured bytes for every file.

1.13 Functions

Name Description
read_report_bundle Verify a current report bundle and reconstruct its sealed snapshot.
read_report_bundle_with_assets Read a verified report with its exact files for source-free publishing.
theory_for_initial_metric Return canonical references for the first reward/reconstruction metrics.
write_report_snapshot Atomically export the exact supplied snapshot without source access.

1.13.1 read_report_bundle

reporting.read_report_bundle(path)

Verify a current report bundle and reconstruct its sealed snapshot.

Verification rejects unknown schema versions, non-canonical JSON, unsafe or duplicate paths, symlinks and special files, undeclared or missing files, digest mismatches, and malformed report values. The reconstructed ReportSnapshot then verifies the report’s snapshot_sha256 against the exact recipe, quantities, tables, sources, and Plotly bytes.

1.13.1.1 Parameters

Name Type Description Default
path Path | str Directory produced by write_report_snapshot. required

1.13.1.2 Returns

Name Type Description
ReportSnapshot The immutable snapshot represented by the verified bundle.

1.13.1.3 Raises

Name Type Description
ScientificReportError If the path is not a complete current bundle.

1.13.2 read_report_bundle_with_assets

reporting.read_report_bundle_with_assets(path)

Read a verified report with its exact files for source-free publishing.

1.13.3 theory_for_initial_metric

reporting.theory_for_initial_metric(metric)

Return canonical references for the first reward/reconstruction metrics.

The identifiers select definitions from the generated registry. Formulas remain owned by docs/typst/shared and are never copied into Python.

1.13.4 write_report_snapshot

reporting.write_report_snapshot(
    snapshot,
    destination,
    *,
    width=1400,
    height=900,
    scale=2.0,
    two_dimensional_format='svg',
    webgl_format='png',
    transparent_background=False,
    renderer=None,
)

Atomically export the exact supplied snapshot without source access.

Ordinary 2D figures use SVG by default. WebGL/3D figures use high- resolution PNG because vector containers rasterize their WebGL layers. transparent_background applies a renderer-only transparent canvas to PNG assets while preserving the canonical Plotly specification verbatim. A render or validation failure removes only the staging directory and keeps the previously published destination intact. An existing corrupt bundle raises its admission error and remains untouched; it is never a cache miss.

Back to top