Skip to content

Shared grid validator: replace the two private Maidenhead regexes #53

Description

@watson-ionis

Two ingesters carry their own Maidenhead regex and they disagree. One of them is correct by accident.

  • cmd/pskr-collector/main.go:81 — ^[A-R]{2}[0-9]{2}([a-x]{2})?$. Requires a lowercase subsquare and caps the locator at 6 characters. On a non-match it sets the field to "" (lines 208-213), so a rejection is indistinguishable from a station that sent nothing.
  • cmd/contest-ingest/main.go:55 — ^[A-R]{2}[0-9]{2}([A-X]{2})?$. Requires an uppercase subsquare. It works only because line 330 calls strings.ToUpper() first. It also drops a failing header grid silently.

Measured impact of the PSKR pattern: 6,746,970,499 rows hold no usable grid pair. Valid input it discarded includes uppercase subsquares, 8- and 10-character locators, and lowercase fields. Collection began 2026-02-10 and the erasure ran the whole time.

What to build: one shared validator package, called by both ingesters and by the reference-tier editor. Per ADIF 3.1.7:

  • GridSquare is 4, 6 or 8 characters; GridSquareExt carries the 2 or 4 beyond that; GridSquareList is comma-delimited.
  • Validation is case-insensitive on input; normalise on store.
  • Never drop, never blank. A failing locator is stored as received with a validity flag and a reason, so an audit can count failures by cause. This rule is what turns a regression into a visible metric instead of seven months of silent loss.
  • Store at full precision; derive grid_4/grid_6 from the stored value rather than storing a truncated one.

Blank-on-invalid is the part that made this unrecoverable, so the flag/reason columns need a coordinated schema change alongside the validator.

Design: the ADIF-Anchored Dimensions record, "Future-proofing grids — one contract, both paths".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions