Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ uv run python -m paxman email "user@example.com" # CLI smoke test
Full pre-PR gate: `uv run ruff check . && uv run ruff format --check . && uv run pyright && uv run import-linter lint && uv run pytest`

## NOTES
- `paxman/capabilities/__init__.py` exports all twenty-eight shipped capabilities (BIC, ChemicalElement, Coordinates, Country, CreditCard, Currency, Date, DOI, Domain, Email, GTIN, IBAN, IP, ISBN, ISIN, ISNI, ISSN, Language, LEI, MacAddress, Money, ORCID, Phone, SI Unit, Timezone, URL, UtcOffset, UUID); export completeness is enforced by `tests/unit/test_capability_exports.py`.
- CONTEXT.md is the domain glossary for the full shipped set (twenty-eight capabilities). It is kept in sync with the code; when adding a capability, update its Notation/table entries there too.
- `paxman/capabilities/__init__.py` exports all thirty shipped capabilities (BIC, ChemicalElement, Coordinates, Country, CreditCard, Currency, Date, DOI, Domain, Email, GTIN, IBAN, IP, ISBN, ISIN, ISNI, ISSN, Language, LEI, MacAddress, MinorPlanet, Money, ORCID, Phone, SI Unit, Timezone, UNSPSC, URL, UtcOffset, UUID); export completeness is enforced by `tests/unit/test_capability_exports.py`.
- CONTEXT.md is the domain glossary for the full shipped set (thirty capabilities). It is kept in sync with the code; when adding a capability, update its Notation/table entries there too.
- No `pyrightconfig.json` — pyright config is inline `[tool.pyright]` in pyproject.toml. No `.editorconfig`.
- Data modules live under `rules/data/` and `grammar/data/` — plain module-level tables separating data from logic. Generated modules (edit via snapshot + regenerate, never by hand): ISBN range message (`tools/regenerate_isbn_range_data.py`), URL IDNA UTS #46 mapping (`tools/regenerate_idna_uts46_data.py`), SIUnit prefixed-unit and grammar token tables (`tools/regenerate_si_prefix_data.py`), the Currency + Money data set (`tools/regenerate_currency_data.py`, from `paxman/shared_data/currency_snapshot.json`), BIC data (`tools/regenerate_bic_data.py`), IBAN registry data (`tools/regenerate_iban_registry_data.py`), Language tables (`tools/regenerate_language_data.py`; `tools/regenerate_iana_language_data.py` now guards removed generated modules), Unicode property ranges (`tools/regenerate_unicode_property_data.py`), Domain IDNA mapping (`tools/regenerate_domain_idna_data.py`), and Domain root-zone TLDs (`tools/regenerate_root_zone_tld_data.py`). Unmarked data files are edited directly.
- Library + CLI: `[project.scripts] paxman = "paxman.cli:main"` and `python -m paxman`; CLI supports `--list`, `--json`, stdin input. Version 0.5.0.
- Library + CLI: `[project.scripts] paxman = "paxman.cli:main"` and `python -m paxman`; CLI supports `--list`, `--json`, stdin input. Version 0.6.0.
- Publishing: `.github/workflows/publish.yml` uses PyPI Trusted Publishing (OIDC) with a Git-tag ↔ `pyproject.toml` version safety check; `paxman/py.typed` ships PEP 561 conformance.
- Coverage: global `fail_under = 95`; `paxman/cli.py` and `paxman/__main__.py` are omitted from coverage (smoke-tested via e2e).
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.6.0] - 2026-10-09

### Added

- **MinorPlanet — Minor-planet designations:** new capability with one grammar (`minor_planet_recognition`: unpacked provisional incl. retrospective `A8xx`/`A9xx` and `A/` lanes with space/`_` separators, case-sensitive packed 7-char, extended `_` base-62, survey unpacked + packed, parenthesized and packed numbers, ASCII-only) and five structure-only rules backed by the Minor Planet Center DesDoc (`Section 1-unpacked-provisional-structure` — year/order/cycle, PARSER), PackedDes (`Section 3-packed-provisional` — packed/extended/survey-packed decode coherence, PARSER; `Section 4-packed-number` — 5-char/letter/tilde decode coherence, PARSER), and HowNamed (`Section 2-survey-designation` — P-L/T-1/T-2/T-3, PARSER; `Section 5-permanent-number` — parenthesized positive integer, PARSER; no registry). Canonical form is the unpacked designation (`1995 XA` / `(433)` / `2040 P-L`); offered output format `packed` (case-exact wire re-encoding, re-enters as a fixed point; the `A/` lane and non-20xx extended range fall back to the designation). Bare 5-digit packed numbers collide with ordinary numbers (ZIPs, phone fragments — caller segments these contexts); degenerate cycles (`XA0`), zero/leading-zero numbers (`(0)`) → `INVALID`; over-long years (`19955 XA`) → `MISSING`; two distinct designations in one call → `MultipleMentionsError`.

- **UNSPSC — Product/service codes:** new capability with one grammar (`unspsc_recognition`: bare 8-digit, zero-padded parents, 6-digit class alias, `UNSPSC`-labelled, `UNSPSC000.` MDM IDs, 10-digit +BFI, ASCII-only, longest-first 10/8/6) and four rules backed by the UNGM UNSPSC Code Structure article (`Section 1-hierarchy-structure` — 6/8/10 lanes, PARSER; `Section 2-level-padding` — `00`-pair lattice, PARSER), the UNDP codeset (UNGM live export 2026-09-30, 13,482 live stems plus 8 synthesized family ancestors (ancestor-walk only); `Section 3-codeset-membership` — stem plus live ancestors, always-active LOOKUP_TABLE; partial — UNDP v26.0801 XLSX gated 403) and the UNECE Classification Guidelines v2.04 (`Section 4-business-function-suffix` — informative-only, PARSER gated by `include_business_function=True`, default on; gating drops the suffix candidate, not the verdict). Canonical form is the 8-digit zero-padded wire stem; offered output formats `labeled` and `native` (both re-enter as fixed points; pair-hyphenated `segmented` display deliberately unoffered — hyphens never re-enter by design). Space/dot/hyphen-grouped, truncated 2/4-digit, and 7/9/11-digit runs → `MISSING`; mid-zero padding, unissued stems, Wikidata-cited-but-unexported codes (e.g. `11101803`) → `INVALID` under the pinned snapshot; two distinct codes in one call → `MultipleMentionsError`.

- **Domain — Hostnames:** new capability with two grammars (`ascii_hostname`: LDH shapes, case-neutral, trailing-dot runs; `idn_hostname`: any script with reserved-ASCII excluded, ASCII overlap dedups by span) and five rules backed by RFC 1034 (`Section-3.1-name-syntax` — ≥2 labels, no empty label, PARSER), RFC 1035 (`Section-2.3.4-label-length` — 63 octets/label, 253 chars/name post-encode, PARSER), UTS #46 (`UTS46-statuses` — statuses with STD3 rules, D13 hyphen checks, ACE round trip, PARSER; shipped table 15.1.0), RFC 5893 (`Section-2-bidi-context` — §2 six conditions plus ContextJ join-control rejection, PARSER), and the IANA Root Zone Database v2026092300 (`root-zone-membership` — encoded-TLD membership ANDed with the other four, LOOKUP_TABLE; no corroboration → `INVALID`). Canonical form is the lowercase ASCII A-label dotted name with no trailing dot; offered output format `unicode` (per-label Punycode decode, re-enters as a fixed point). Single labels (`localhost`) and undelegated TLDs → `INVALID`; containers (`user@example.com`, URLs, `*.example.com`) → `MISSING` (boundary kills); two distinct hostnames in one call → `MultipleMentionsError`.
Expand Down
2 changes: 1 addition & 1 deletion CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ for candidate in result.candidates:

### Capability Versioning
- Capabilities do **not** declare their own versions — the `Capability` surface carries only `name`, grammars, rules, and the presentation seam.
- Library version is resolved in `paxman/engine/orchestrator.py` — `PAXMAN_VERSION = _resolve_version()` reads the installed `paxman` package version via `importlib.metadata` (falling back to `"0.2.1"`); source of truth is `version = "0.5.0"` in `pyproject.toml`.
- Library version is resolved in `paxman/engine/orchestrator.py` — `PAXMAN_VERSION = _resolve_version()` reads the installed `paxman` package version via `importlib.metadata` (falling back to `"0.2.1"`); source of truth is `version = "0.6.0"` in `pyproject.toml`.
- Referenced in `VersionStamp.paxman_version`

### Contract Protocol
Expand Down
3 changes: 2 additions & 1 deletion docs/development/MILESTONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **Purpose:** Roadmap guidance for capabilities to bring into Paxman, ordered by priority.
> This table is a planning aid — details need not be exactly accurate in terms of implementation.
> 29 capabilities are shipped (BIC, ChemicalElement, Coordinates, Country, CreditCard, Currency, Date, DOI, Domain, Email, GTIN, IBAN, IP, ISBN, ISIN, ISNI, ISSN, Language, LEI, MacAddress, Money, ORCID, Phone, SIUnit, Timezone, UNSPSC, URL, UtcOffset, UUID) and are listed in §1 only — they are excluded from the future roadmap in §2.
> 30 capabilities are shipped (BIC, ChemicalElement, Coordinates, Country, CreditCard, Currency, Date, DOI, Domain, Email, GTIN, IBAN, IP, ISBN, ISIN, ISNI, ISSN, Language, LEI, MacAddress, MinorPlanet, Money, ORCID, Phone, SIUnit, Timezone, UNSPSC, URL, UtcOffset, UUID) and are listed in §1 only — they are excluded from the future roadmap in §2.

---

Expand Down Expand Up @@ -41,6 +41,7 @@ Verified against `paxman/capabilities/__init__.py` + `paxman/api/bootstrap.py:_S
| 27 | **LEI** | ISO 17442-1:2020, GLEIF LOU prefix list | "5493000IBP32UQZ0KL24" → "5493000IBP32UQZ0KL24" | `research/2026-09-22-lei-canonicalization.md`, `plans/2026-09-22-lei-capability.md` |
| 28 | **ISNI** | ISO 27729:2024 (MOD 11-2) | "ISNI 0000 0001 2103 2683" → "0000 0001 2103 2683" | `research/2026-09-26-isni-canonicalization.md`, `plans/2026-09-26-isni-capability.md` |
| 29 | **UNSPSC** | UNDP UNSPSC (UNGM structure, UNGM live-export snapshot, UNECE BFI) | "UNSPSC 44103103" → "44103103" | `research/2026-09-30-unspsc-canonicalization.md`, `plans/2026-09-30-unspsc-capability.md` |
| 30 | **MinorPlanet** | MPC DesDoc, MPC PackedDes, MPC HowNamed | "J95X00A" → "1995 XA" | `research/2026-10-07-minor-planet-designation-canonicalization.md`, `plans/2026-10-07-minor-planet-capability.md` |

Notes on §1:

Expand Down
Loading
Loading