BreveCoreControllerDate: 2026-06-22 · Status: DONE,
byte-identical (5/5 baselines 0.000e+00)
The structural-clone detector
(validation/ast_duplication.py) flagged
GNC/base_controller.py (BaseController) and
GNC/breve_controller.py (BreveController) as
carrying ~12 byte-identical method bodies (Jaccard
J=1.00 — compute_tau_b_oplus shared 125 subtrees,
all_control_terms 85, _apply_step_state_update
94, J_xb, x_b_tilde, …). Two controllers
maintained in lock-step by hand is where a fix lands in one and silently
not the other. The remedy: hoist the shared bodies into one place.
Both classes already inherit the same root,
CC_Controller (GNC/com_controller.py). So the
duplication has a clean home: a new intermediate base both classes
inherit.
Reading all three files method-by-method partitioned the surface into three groups:
Byte-identical twins (13) → hoist to the shared
base. _loop_sync_uses_update_views,
_build_base_desired_for_step (+ the base-path
build_desired_for_step), x_b_tilde,
x_b_tilde_dot, J_xb, x_tilde,
J_x, v_breve_damping_error,
conditioning_scale, compute_tau_b_oplus,
all_control_terms, _apply_step_state_update.
Identical computations in both classes.
Genuinely forked leaves → leave in place. The
hoisted methods call self.x_e_rhs(),
self.J_xe(), self.omega_b_damping_error(),
self.nu_e_damping_error(),
self.arm_breve_gains(),
self.rhs_feedforward(), self.v_breve_dot(),
self.RHS34b(), self.calc_posture(). These
differ between the two controllers (Base zeroes the EE/arm path; Breve
runs the full coordinated law with implicit damping, velocity
feed-forward, CHAIN-5 posture, null-space reconstruction).
Dynamic dispatch resolves each call to the subclass’s
own version, so the one shared template produces two
behaviours. This is the Template Method pattern — and it is why hoisting
the identical methods is safe without touching the forks.
Redundant parent-overrides → delete.
BaseController._sync_loop_state and
._update_breve_views were byte-identical to
CC_Controller’s own versions (verified against
com_controller.py:316-326). Pure dead overrides; deleted so
Base inherits the parent’s identical implementations.
GNC/breve_core_controller.py —
class BreveCoreController(CC_Controller) holds the 13
shared methods. ~120 lines, stdlib + the existing geometry/quaternion
helpers only.BaseController(BreveCoreController)
shrinks to its __init__, the zeroed EE/arm leaves, and its
own
RHS34b/calc_posture/v_breve_dot/reconstruct_generalized_velocity
(the base-path forks). The 13 twins and the 2 redundant overrides are
gone.BreveController(BreveCoreController)
keeps its __init__, the full
build_desired_for_step, every EE method, and its forked
RHS34b/calc_posture/v_breve_dot/reconstruct.
The 12 hoisted twins are deleted.Base/Breve → BreveCoreController → CC_Controller), so
every super().all_control_terms(...) /
super()._apply_step_state_update(...) still resolves to
CC_Controller exactly as before.
analysis/runner.py::make_controller constructs both classes
unchanged.A pure relocation of byte-identical method bodies along the existing
dispatch graph cannot change the closed-loop trajectory. The certificate
is the five method-level baselines, checked, not
re-pinned (per .claude/rules/GNC.md): an unchanged
closed loop must reproduce max_abs_diff = 0.000e+00 at ATOL
1e-9.
| baseline | controller | regime | max_abs_diff |
|---|---|---|---|
validate_base_baseline |
BaseController | base-only | 0.000e+00 |
validate_ee_initial_baseline |
BreveController | INITIAL | 0.000e+00 |
validate_ee_targeting_baseline |
BreveController | TARGETING | 0.000e+00 |
validate_ee_coverage_baseline |
BreveController | COVERAGE | 0.000e+00 |
validate_ee_tracking_baseline |
BreveController | TRACKING (40 s) | 0.000e+00 |
The detector re-run on GNC/ confirms the elimination:
0 pairs ≥ 0.85. The highest remaining Base↔︎Breve pairs
are the deliberately forked methods — calc_posture
(0.83), reconstruct_generalized_velocity (0.82),
RHS34b (0.75) — which score below threshold precisely
because they genuinely differ. The lock-step copy-paste is gone; the
real differences between the diagnostic and the full controller now read
as intentional.
This removes Type-1/2 duplication (identical bodies). It does
not attempt to unify the forked methods
(RHS34b, calc_posture,
v_breve_dot, reconstruct) — those are real
behavioural differences and a further Template-Method refactor of them
is a separate design decision, not a byte-identical move.