# KOPR R107 – Comet designation enforcement and cleanup report

**Base:** `KOPR_CLEAN_BUILD_20260728_R106_MULTI_COMET_DESIGNATION_WORKFLOWS`  
**Date:** 2026-07-28  
**Scope:** final R103–R107 designation-input enforcement, compatibility cleanup and documentation.  
**Scientific scope:** no change to ephemeris, astrometry, calibration, stacking, photometry or FITS products.

## 1. Result

The designation-input migration is complete across:

- WCCD;
- WStack;
- WVisual;
- WAnalyzer;
- WPlanner;
- WComparison;
- AddComet.

All GUI surfaces now use the shared syntax, canonicalisation, repository validation and Qt presentation contract introduced in R103 and migrated in R104–R106.

## 2. Final ownership

### `comet_designation.py`

Single headless owner of:

- final designation syntax;
- canonicalisation;
- incomplete/intermediate typing states;
- shared examples and validation messages;
- FITS `OBJECT` hint parsing;
- local-element lookup through `CometElementRepository`;
- multi-designation parsing and canonical deduplication.

The historical `ephemeris_position.normalize_comet_designation` symbol remains only as a compatibility re-export of the same function.

### `comet_designation_widgets.py`

Single Qt owner of:

- `Comet designation` label;
- placeholders and help copy;
- status colours and line-edit styling;
- embedded, table, single-dialog and list-dialog components;
- explicit `Add or update comet elements…` action.

## 3. Compatibility cleanup

The following functions remain as thin adapters for compatibility:

- `wccd._designation_hint_from_object()`;
- `wccd._local_comet_elements_available()`;
- `wstack_functions.stack_kopr_ephemeris_available()`.

They contain no local regex, no direct scan of `Elements.txt` or `CustomElements.dat`, and no independent error-message policy.

The following unreferenced legacy GUI code was removed:

- `koprhand.showdialogCom()`;
- `koprhand.showdialogImg()`;
- unused `loadcometid()` call in WAnalyzer data import;
- unused `loadcometid()` call in the COBS comparison dialog.

`koprhand.loadcometid()` itself remains for external compatibility, but is no longer used as a designation GUI validator.

## 4. Static release enforcement

Added QA tool:

```bash
python3 comet_designation_inventory.py --enforce .
```

It performs an AST-only scan and therefore does not require PyQt5. The release fails if it finds:

- a comet/designation `QInputDialog.getText()`;
- GUI validation through `loadcometid()` or `FindElements()`;
- a non-allowlisted GUI `LoadComet()` validation path;
- a designation regex outside `comet_designation.py`;
- `Comet name`, `Comet short name` or `destignation` UI terminology;
- duplicated shared examples or status messages in GUI modules;
- a required widget that no longer imports its shared component.

Synthetic negative tests verify that each major violation category is detected.

The one allowlisted WAnalyzer `LoadComet()` call occurs after shared validation and loads scientific/magnitude data; it is not used to decide syntax or local-element availability.

## 5. Documentation

Added:

- `docs/COMET_DESIGNATION_USER_GUIDE.md`;
- `docs/developer/COMET_DESIGNATION_R107_ENFORCEMENT_CLEANUP.md`;
- `RUN_R107_FOCUSED_QA.md` in the QA archive.

Updated:

- `README.md`;
- `docs/CHANGELOG.md`.

## 6. Production changes against R106

Changed production modules:

```text
comet_designation.py
comet_designation_widgets.py
koprdial.py
koprhand.py
wanalyzer.py
wccd.py
wstack.py
wstack_functions.py
wvisual.py
```

QA-only addition:

```text
comet_designation_inventory.py
```

WPlanner, WComparison and their R106 parser remain bit-identical because their multi-designation migration was already complete.

## 7. Scientific invariants

R107 does not alter:

- orbit-element selection or source precedence;
- the unified ephemeris service;
- N-body model selection, integration, cache or fallback;
- observer and coordinate-frame conversion;
- WStack calibration, astrometry, stacking or provenance;
- WCCD photometry, scale conversion or ICQ output;
- Planner ephemerides and altitude curves;
- Analyzer/Comparison model curves;
- FITS pixel data or headers.

The R101 ephemeris enforcement remains green with exactly one application-facing `compute_application()` call inside the unified service and zero direct widget engine calls.

## 8. QA

Focused R103–R107 designation suite:

```text
67 passed
0 failed
```

Extended designation/ephemeris/legacy compatibility gate:

```text
95 passed
0 failed
```

Non-manifest full regression groups:

```text
1547 passed
5 skipped
0 failed
```

Final release/manifest group:

```text
42 passed
1 skipped
0 failed
```

Final total:

```text
1589 passed
6 skipped
0 failed
```

The six skips require a complete optional Astropy FITS/time runtime. PyQt5 and a graphical display were not available in the build environment, so live visual spacing and interaction were not exercised; the Qt structure, transactional contracts and headless static gates were tested.

## 9. Conclusion

R107 completes the R103–R107 plan. New comet-designation inputs must use the shared headless validator and shared Qt components, and the release gate now prevents the previous parallel-dialog architecture from returning.
