│ Suggestion 3: Enforce Construction Ordering via Phase State │
│ │
│ Problem: Analysis has an implicit three-phase construction sequence: add_dataset() → construct_services() → construct_llhratio(). Calling │
│ construct_llhratio() before construct_services() raises AttributeError: object has no attribute '_src_detsigyield_weights_service' — no guidance on what to │
│ do. The ordering is documented only in a docstring (analysis.py:1240-1261). │
│ │
│ Solution: Add an AnalysisPhase enum (CONFIGURING, SERVICES_BUILT, LLH_BUILT, READY). Set self._phase = AnalysisPhase.CONFIGURING in __init__. Add │
│ _require_phase(expected, method_name) helper. Wrap each construct method to check and advance phase: │
│ │
│ def construct_services(self, ...): │
│ self._require_phase(AnalysisPhase.CONFIGURING, 'construct_services') │
│ ... │
│ self._phase = AnalysisPhase.SERVICES_BUILT │
│ │
│ Files: │
│ - skyllh/core/analysis.py — Analysis.__init__, construct_services, construct_llhratio (both concrete subclasses), construct_signal_generator, llhratio │
│ property getter │
│ │
│ Benefit: Users get "call construct_services() before construct_llhratio()" instead of AttributeError on an internal attribute. │
│ │
│ Risk: Low. Tests that construct partial Analysis objects out of order need updating. │