- Moved the `AuthorityFrontier` discovery-state vocabulary into `opencontractserver/enrichment/constants.py` as a single source of truth (`DISCOVERY_STATE_*` constants, `DISCOVERY_STATE_CHOICES`, and `DISCOVERY_SUCCESS_STATES`). The model field (`opencontractserver/annotations/models.py`), the frontier service transition verbs, the discovery orchestrator, the crawl driver, and the verify/license gate's `GATE_*` verdicts now reference these constants instead of bare string literals, so a rename is a one-line edit and the parallel definitions cannot drift (CLAUDE.md item 4; issue #2020 finding 7). The model's `DISCOVERY_STATE_CHOICES` is re-exported from the constants with identical values, so no migration is generated.
- Renamed `enrichment.constants._USC_PREFIX_RE` / `_CFR_PREFIX_RE` to `USC_PREFIX_RE` / `CFR_PREFIX_RE` (no leading underscore). They are imported cross-module by the USC/CFR authority source providers' `can_handle` overrides, so the underscore (signalling module-private) was misleading; updated both providers' imports (issue #2020 finding 3).
- Optimised `AuthorityDiscoveryService._provider_for` (`opencontractserver/enrichment/services/authority_discovery_service.py`) to instantiate each enabled provider once per call and reuse the instances across every candidate key, instead of re-instantiating every provider for each candidate. `can_handle` is pure given the key, so the prior per-candidate instantiation was wasted work that grew with the candidate-key fan-out (issue #2020 finding 6).
- Expanded the `dequeue_for_provider` docstring to document its crash-recovery purpose (freshly-seeded rows carry `provider=None` and are intentionally skipped; the primary dispatch path is the provider-agnostic `dequeue_queued`) and clarified the `AuthorityKeyEquivalence` model docstring that its direction convention is documentation-only because callers query both columns (issue #2020 findings 9, 10).
