Skip to content

feat: lintle dedup — latest-re-issue-only import list (#142)#160

Merged
elfensky merged 3 commits into
developfrom
feature/dedup
Jul 10, 2026
Merged

feat: lintle dedup — latest-re-issue-only import list (#142)#160
elfensky merged 3 commits into
developfrom
feature/dedup

Conversation

@elfensky

Copy link
Copy Markdown
Owner

lintle dedup — latest-re-issue-only import list (#142)

Adds lintle dedup <out-dir>: reads a clean run's cleaned/ (never mutating it) and writes a
single ingest-ready import list under <out-dir>/dedup — one card per (catalog, epoch),
keeping the latest re-issue (highest element-set number).

Closes #142.

Behaviour

  • Collapse benign re-issues — same (catalog, epoch), a bumped element-set or revolution
    number but an identical parsed orbital state → keep the highest element-set, drop the rest.
  • Never resolve a real conflict in silence — a group with >1 distinct orbital state (same
    satellite + epoch, different orbit) keeps the latest but is flagged in notes.jsonl, and the
    run exits 1 so a human reviews it.
  • Exclude hard suspects — when <out-dir>/verify/suspects.jsonl exists, every hard suspect
    is dropped from the import list by (src_file, index) first; dedup still runs (collapse only)
    when no verify run exists.
  • Constant memory & deterministic — records stream through verify's ExternalSorter; only
    one (catalog, epoch) group is held at a time; import.txt streams out sorted by
    (catalog, epoch). Outputs (import.txt, notes.jsonl, summary.json) are byte-deterministic.

Realises the output tiering source/cleaned/ (immutable archive) → import.txt
(verified + deduped, ready to ingest)
. Exit codes: 0 clean, 1 genuine contradiction arbitrated
(review), 2 no cleaned output.

One definition of "same orbit" / "latest"

Promotes verify.checks._orbital_state/_element_set to public orbital_state/element_set
so dedup shares them — not a divergent second orbital mask. dedup is a second read-only
consumer of the verify/ package (cli → dedup → verify.{checks,grouping,records}), one-way and
equally barred from the clean path.

Verification

  • 767 passed (14 new dedup tests: collapse/conflict/exclusion/determinism/immutability/
    sorting/cli); ruff check clean; ruff format --check clean.
  • Real bytes: on a 20,000-record sample of the real tle2006 cleaned output, dedup collapsed
    30 (catalog, epoch) groups, 0 conflicts — matching the issue's documented finding
    (catalog 2864 kept element-set 956 over 955), and the cleaned slice was byte-identical after.

🤖 Generated with Claude Code

elfensky and others added 3 commits July 10, 2026 23:14
…dedup

These two helpers define "the orbital identity of a record" and "which re-issue
is latest" — exactly what `dedup` (#142) needs, and it must agree with `verify`
byte-for-byte on both. Promote them from `_orbital_state`/`_element_set` to
public `orbital_state`/`element_set` so dedup shares the one definition rather
than re-implementing a divergent orbital mask. Pure rename; the two call sites in
find_conflicts follow. No behaviour change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `lintle dedup <out-dir>`: reads a clean run's cleaned/ (never mutating it)
and writes a single ingest-ready import list under <out-dir>/dedup — one card
per (catalog, epoch), keeping the latest re-issue (highest element-set number).

- **Collapse** benign re-issues: same (catalog, epoch), a bumped element-set or
  revolution number but an identical parsed orbital state → keep the highest
  element-set, drop the rest. Shares verify's orbital_state/element_set so the
  two passes agree on "same orbit" and "which is latest".
- **Never resolve a real conflict in silence**: a group with >1 distinct orbital
  state (same satellite+epoch, different orbit) keeps the latest but is flagged
  in notes.jsonl, and the run exits 1 so a human reviews it.
- **Exclude hard suspects**: when <out-dir>/verify/suspects.jsonl exists, every
  hard suspect is dropped from the import list by (src_file, index) first; dedup
  still runs (collapse only) when no verify run exists.
- **Constant memory**: records stream through verify's ExternalSorter; only one
  (catalog, epoch) group is held at a time. import.txt streams out sorted by
  (catalog, epoch). Outputs (import.txt, notes.jsonl, summary.json) are
  byte-deterministic.

cleaned/ is immutable — the archive is a reproducible function of (source,
clean-code); dedup is a separate, re-derivable artifact. Exit codes: 0 clean,
1 genuine contradiction(s) arbitrated (review), 2 no cleaned output.

Verified on a 20,000-record sample of the real tle2006 cleaned output: 30
(catalog, epoch) groups collapsed, 0 conflicts — matching the issue's finding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#142)

README: a "latest only import list" usage subsection (the collapse/conflict/
suspect-exclusion behaviour, `<out-dir>/dedup/` outputs, exit codes 0/1/2) plus
`lintle dedup` in the command block; states the source/ → cleaned/ → import.txt
output tiering.

ARCHITECTURE §2: `dedup.py` in the module tree and table, and the acyclic-import
paragraph — `cli → dedup → verify.{checks,grouping,records}`, one-way, barred
from the clean path, reusing verify's one definition of "same orbit"/"latest".

CHANGELOG: an unreleased `lintle dedup` bullet. CLAUDE.md: the layout line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@elfensky
elfensky merged commit 6c33f86 into develop Jul 10, 2026
1 check passed
@elfensky
elfensky deleted the feature/dedup branch July 10, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant