Doctoral Research · Space Robotics Inspection with a Free-Flying Space Manipulator
A Doctoral Research Journal Aerospace Engineering

Investigation — blast radius of the boresight + omega-ripple figure work

Generated: 2026-06-25 23:52 EDT Question: Did the boresight + omega-ripple figure work change any load-bearing code (new logged fields, GNC/sim changes, analyzer/logger changes), or did it stay contained to the analysis/ figure scripts? “New fields to be logged, or worse?” Mode: investigator (report-only; no code modified).


Answer first


Scope


What changed, by commit (call order = chronological)

The figure work spans three commits, not one:

  1. bd7d0e6 (Jun 23) — feat(diag): log realized floor + EE frame angle — the load-bearing one.
  2. e06c2d2 (Jun 24) — feat(analysis): harvest boresight + omega_b ripple figures into analysis/ — contained.
  3. 8f73e08feat(controller): adopt implicit-damping integration -- cures the omega_b ripplelegitimate, not figure cruft.

The gate (why baselines survived)

build_diagnostics(...)            # breve_controller.py, per-step diagnostics
  └─ if getattr(full_cfg, "log_cruise_lag_floor", False)   # :568  ← DEFAULT False
       and des and dyn and isfinite(s_min_G):              # :570-572
         floor_pe, floor_pe_coriolis = x_ss_floor(des)     # :574  (pre-existing)
         floor_pe_realized  = x_ss_floor(des, v_breve_override=v_real)[0]   # :584  ← bd7d0e6
         floor_pe_consistent = x_ss_floor(des, v_breve_override=v_consistent)[0] # :588 ← bd7d0e6
         ee_angle = degrees(norm(so3_log(R_ed.T @ R_te)))  # :600-604  ← bd7d0e6
         diag.frame = Package(ee_angle=ee_angle)           # :605

Default config never enters this branch ⇒ default NPZ schema unchanged ⇒ baselines byte-identical.


Findings

Finding 1 — The only controller change is gated diagnostics; it is correct and safe. Evidence: breve_controller.py:568-605; gate default parameters.yaml:4 (false); bd7d0e6 message (“baselines byte-identical, no re-pin”); gold gate 3 passed today. Impact: No risk to the science or baselines. The figure work did not corrupt the control path. Next step: None required for correctness.

Finding 2 — Orphan-risk cruft exists IF the figures are retired. Evidence: The boresight figure is the primary consumer of ee_angle + the realized/consistent floors. Other consumers are themselves figure/readout artifacts: analysis/analysis_YAMLs/frame_angle_diag.yaml, validation/frame_angle_readout.py:37-39, and analysis/data_analyzer.velocity_error (used only by the boresight figure). Impact: If you decide the boresight figure isn’t worth keeping, ~41 lines of gated controller code, 17 catalog lines, a run-spec, a readout script, and velocity_error become dead weight. Note floor_pe/floor_pe_coriolis (the base cruise-lag floor) are part of the broader, still-relevant cruise-lag investigation (memory cruise-lag-floor-resolved) and should NOT be removed — only the _realized/_consistent/ee_angle extensions are figure-specific. Next step: Decide keep-vs-retire on the boresight figure (Task A). Omega figure is independently deletable (Task B).

Finding 3 — validation/run_mission.py:66 is the lone code path that enables the gate. Evidence: run_mission.py:64-66 (if floor: mapping["log_cruise_lag_floor"] = True); the floor run-specs (full_control_floor_an.yaml, floor_consistent_an.yaml, frame_angle_diag.yaml, …) override it. Impact: The diagnostics are reachable only through an explicit opt-in, never in a bare mission/baseline. Next step: None — this is the intended design.


Proposed next tasks

TASK A — Decide keep-or-retire the boresight (frame-angle) figure. - Body: The boresight figure is the only real consumer of the bd7d0e6 controller diagnostics. If retired, remove the figure-specific extensions; if kept, leave as-is (it’s gated and harmless). - Modify (only if retiring): GNC/breve_controller.py (drop floor_pe_realized/floor_pe_consistent/ee_angle + _v_breve_consistent + the v_breve_override param if unused elsewhere), YAMLs_by_domain/metrics.yaml (cruise_lag.floor_realized, frame.angle), analysis/data_analyzer.py (velocity_error). - Delete (only if retiring): analysis/boresight_roll_figure.py, analysis/analysis_YAMLs/frame_angle_diag.yaml, validation/frame_angle_readout.py. - Keep regardless: floor_pe/floor_pe_coriolis base floor (broader cruise-lag work); the log_cruise_lag_floor gate itself. - Validation: pytest validation/tests/test_gold_standard.py must stay max_abs_diff 0.000e+00; pytest validation -m "not slow" green; re-run any retained floor run-spec.

TASK B — Delete the omega-ripple figure (zero-cleanup). - Body: analysis/omega_ripple_figure.py adds nothing load-bearing and (per user) doesn’t prove its point. Deleting it touches no other code. - Delete: analysis/omega_ripple_figure.py. - Do NOT touch: the implicit-damping integrator (8f73e08) — the legitimate cure, unrelated to the figure. - Validation: git grep confirms no importer; pytest validation -m "not slow" green.

TASK C — (process) The figure investigation edited GNC/ without loading GNC.md rules. - Body: Root cause was the orchestrating agent delegating to subagents that never inspected files, so path-scoped rules never loaded (matches memory read-rules-before-delegating). The byte-identity rule survived only because the author gated the block. Worth a guardrail so GNC edits from sub-agents always carry the GNC hard-rules. - Inspect-not-modify: .claude/rules/GNC.md, the dispatch/delegation flow.