Phase 0 fragility study — pre-registered criteria (written before any run)

Design

  • System: unmodified nominal, Mission-1 adopted config (orbit_path ON), full 1100 s helix.
  • Sources injected SEPARATELY (one source per cell), magnitudes per source below, seeds 0-4 (N=5).
  • Nominal reference cell: uncertainty disabled, seeds vacuous (deterministic) -> single run.

Cells

sourceknobslomidhi
camerapos_std (m) / angle_std (deg)0.01 / 0.50.03 / 2.00.10 / 5.0
statepos_std (m) / vel_std (m/s)0.005/0.0050.02 / 0.020.05 / 0.05
actuationforce_std (N)0.52.05.0

Metrics (per run; aggregated mean +/- 95% CI across seeds)

  • area_coverage_frac (final) - the realized coverage under perturbed marking
  • p_e error p99 (m) - ||p_e_actual - p_e_desired|| 99th percentile
  • cumulative |f_c| - control effort
  • completion: progress at t_end (or time of orbit completion if reached)

Pre-registered expectations (the gate)

  • E1: each metric degrades monotonically with magnitude within a source (non-monotone => injection or metric is wrong; STOP and investigate).
  • E2: nominal cell reproduces the adopted headline (coverage 0.999, pe_p99 0.165). NOTE (pre-registered Jun 11, before the campaign): Phase 00’s verdict re-pins the frozen baseline (phase00.md T9); E2’s numbers and the Design config line update to the winner BEFORE any fragility run — the campaign measures the post-verdict baseline.
  • E3 (scope): state noise = COM localization only; EE estimated-state and arm actuation noise are Phase B/C scope and get fragility columns then.

Outputs

  • generated_reports/analysis/fragility_table.md (the yardstick table)
  • saved NPZ log per run under logs/fragility/ (provenance: regen via validation/fragility_study.py)