Comet Analyzer / WLightCurves architecture

R144–R154 define one WLightCurves production runtime, one compute/formula/view pipeline, one target-aware formula transaction and one immutable GUI capability projection.

Canonical route: kopr.py → wlightcurves.WLightCurves → one compute/formula/view pipeline → WLIGHTCURVES_POLICY; formula documents are parsed by light_curve_formula_document.py and committed to MagParams.dat only through the R149 atomic Save transaction.

One production runtime

Comet Analyzer tab
  → wlightcurves.WLightCurves
  → one typed 1..N target/dataset state
  → one compute/formula/view pipeline
  → one WLIGHTCURVES_POLICY

R187 is the current cumulative authority. R144 remains the historical cutover marker.

Canonical implementation ownership

ModuleCurrent ownership
wlightcurves.pyCanonical Comet Analyzer GUI and runtime.
typed target/dataset modulesImmutable target identity, order and committed observation state.
legacy_comparison_import.pyOne-way migration-only parser; never active runtime state.
wanalyzer.py, wcomparison.pyDeprecated aliases only.

The production route contains no active type_codes, no active self.script and no second Comparison worker, renderer or cache.

Current 1..N pipeline

  • immutable typed targets and datasets;
  • target-scoped returns and formula documents;
  • global channel visibility and Fit Groups;
  • Independent fit for 1..N targets and Shared n only for 2+ compatible targets;
  • active-target formula navigation with all-target atomic validation;
  • observation-defined automatic X and model/formula/Bortle automatic Y inside it;
  • cached Auto range view command;
  • portable transactional .kopr-lc.json scenarios;
  • existing compute-once/render-many, display, Multi-colour and worker-transaction contracts.

R149/R179 formula and persistence boundary

R149 defines the complete target-aware documents and exact-designation atomic file replacement. R179 separates their application paths:

  • typing updates draft text only;
  • Refresh validates and atomically commits both documents to runtime state;
  • Save atomically persists a valid draft without applying it to the graph;
  • Analyse commits a typed result immediately and starts one render.

Only Refresh and Analyse advance runtime formula state. Save remains a file transaction. Valid physical geometry and observation data remain reusable.

Formula transaction architecture

R154 immutable control-state projection

CometAnalyzerControlState and resolve_comet_analyzer_control_state(...) are the sole primary-control policy above the R151 capability model. _refresh_gui_capabilities() maps the current EMPTY, SINGLE_TARGET, MULTI_TARGET or BUSY projection to Qt widgets.

The projection owns selection, dataset/source/settings/formula actions, Editing target, Multi-colour, Break windows, Analyse, committed-view controls, Refresh, toolbar availability, Fixed slope/fixed n, Shared n and adaptive completeness. Event handlers must not independently recreate these rules.

Worker terminal-state resolution

_analysis_set_busy() must not snapshot and later replay widget isEnabled() values. Success, failure, cancellation and finish resolve capabilities from the current committed dataset, selected-target topology, fit mode and current worker state.

Job-identity guards remain mandatory for every terminal callback. An incomplete result, stale job, failure or cancellation cannot replace the previous committed graph or result dictionary.

Canonical ephemeris policy identity

EphemerisClient.WLIGHTCURVES
WLIGHTCURVES_POLICY

Historical names are strict aliases:

WANALYZER_POLICY is WLIGHTCURVES_POLICY
WCOMPARISON_POLICY is WLIGHTCURVES_POLICY

APPROVED_WIDGET_POLICIES contains only the canonical analytical client. policy_for_client() normalizes legacy client names before routing, so they cannot create a second execution identity, physical cache or scientific behaviour.

Legacy isolation

The old formula parser island remains removed and formula compatibility conversion remains outside the typed runtime. R187 adds the same hard boundary for historical Comparison data: only legacy_comparison_import.py may parse it, and only as one-way migration.

Deprecated wanalyzer.py/wcomparison.py aliases may route imports, but they cannot restore active script state, type_codes, a second scenario schema or a second analytical identity.

Current cumulative release gate

wlightcurves_merger_release_gate.py remains callable by historical R136–R149 tests but now checks the current architecture. Its compatibility result retains release = R144 and adds qualified_through = R187.

The current integration authority is r187_comet_analyzer_final_integration_release_gate.py, which composes the R181–R186 gates and verifies current terminology and compatibility isolation.

Complete R187 gate contract

R154 interactive qualification

The Qt-free matrix is platform-neutral, but release qualification also requires the real widget:

QT_QPA_PLATFORM=offscreen \
python3 r154_comet_analyzer_interactive_release_gate.py --require-qt

PASS_HEADLESS is explicitly non-release-ready. A valid release record requires PASS, release_ready: true and the native GUI visual checklist.

Complete state-machine and gate contract

Source-reported validation

Current R135–R187 Analyzer regression: 384 passed, 3 skipped, 0 failed. All headless gates R150–R187 passed. The real PyQt5 R154, R161 and R179 modules remain skipped, so the qualification is PASS_HEADLESS.

Deprecated alias boundary

Analyzer2, Comparison, ScrollAnalyzer2 and ScrollComparison may remain import aliases for compatibility, but current documentation and release gates must not describe them as workflows. Any later deletion remains an external import-compatibility decision.

R163/R164 range and artist boundary

The canonical runtime now separates three identities: committed scientific arrays, AUTO/USER range ownership, and display artists. A range identity changes only when rendered rows or coordinates can change. Display identity changes only colour/marker/size/legend composition. R164 requires exact observation coordinate invariance across display modes.

Range state · Artist invariance

R161/R169 display-style layer

The canonical WLightCurves renderer consumes a dedicated style resolver that can swap comet/channel colour and marker ownership and set a global observation Point size without changing typed observation rows or formula results.

  • default mode: comet colour, channel marker;
  • reverse mode: channel colour, comet marker;
  • perihelion side: marker face;
  • observation Point size: 1.0–12.0, default 3.0;
  • formula markers and legend keys: not resized by Point size;
  • legend membership: actual rendered artists only;
  • persistence: atomic light_curve_display_styles.json for confirmed overrides and Point size;
  • capacity: 15 comet markers, then deterministic fallback.

The style layer is downstream of compute, formula, filter and range selection. Its actions are render-only and cannot create a second physical cache or scientific execution identity.

R187 final integration boundary

R187 closes the Comparison/1..N remediation plan and makes the final integration page the current developer authority.

R187 final integration · Light Curve Scenarios