Skip to content
Merged
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
20 changes: 0 additions & 20 deletions .changeset/neat-readme-shape.md

This file was deleted.

22 changes: 0 additions & 22 deletions .changeset/quiet-docs-decisions.md

This file was deleted.

40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
# naija-id

## 0.5.1

### Patch Changes

- e7030ef: Restructure the README for scanning. Documentation only — no code, no API change.

The README had grown to 437 lines across 16 sections with no table of contents, and 69% of it was prose. The qualities it was optimised for — stating every limit plainly, never overclaiming — had made it unscannable: every honest caveat was a paragraph, and the paragraphs accumulated. `Format for display` started around line 250, so anyone asking "how do I format a phone number" scrolled past 107 lines of identifier-specific caveats first.

Four changes:

- **A capability table up front**, listing all 14 identifiers against their `is*` / `format*` / `generate*` / `detect()` name and whether redaction covers them by default. This is what most readers actually want, and it replaces a lot of scattered prose. Generated from the real exports, not from memory.
- **Reordered so the shape of the library comes first**: Install → capability table → Quick start → Format → Generate → Mask → Redact → per-identifier notes → integrations. Identifier-specific caveats no longer sit between a reader and the core API.
- **A table of contents.** All 10 anchors verified against the actual headings.
- **The deep reasoning moved into four collapsed `<details>` blocks** — 109 lines of it: why validators cannot be detectors, the redaction false-positive measurements, the NUBAN residue proof behind `inferBanks`, the voter-VIN evidence table, and the fixed-line letter guard. Nothing is deleted; it is one click away instead of in the scroll path.

Kept in the README rather than moved to a separate file so no link can rot and nothing depends on a doc that might not be published.

**437 → 226 lines**, with the rendered default view at ~198. Prose that explained _why_ now links to `docs/design-decisions.md` instead of repeating it, so the README carries what you need to call the API and one line of caveat per identifier — the reasoning is one click away rather than in the scroll path.

Per-identifier caveats became a table rather than six prose blocks. Every snippet was extracted and compiled against the project's own tsc, every claimed output was executed and checked, and all 9 internal and cross-file anchors were verified against real headings.

- 162eeb0: Add `docs/design-decisions.md` — a published record of the decisions that are easy to reverse incorrectly. Documentation only.

Until now, the reasoning behind the load-bearing choices lived only in JSDoc comments and commit messages. A contributor asking "why is redaction anchored on written shape rather than on the validators?" had no findable answer, and the honest answer is a measurement, not an opinion.

Eight entries, each with the evidence it rests on:

1. **Format only, never existence** — NUBAN's check digit is the sole real checksum.
2. **A validator cannot be a detector** — `parseX` normalizes before testing, so `isPhone("Total: NGN 8,031,234,567")` is `true`. Redaction anchors on shape and uses the validator only to veto.
3. **Confidence is evidence, not type** — measured false-positive rates per detector (100% for bare digit counts, 30% for `isPhone`, 0.4% for plate/passport).
4. **NUBAN is undetectable without a bank code** — the residue proof, and why the same fact makes `inferBanks` useful while making a silent detector dishonest.
5. **A replaced or tokenized identifier gets its own module** — the `python-stdnum` precedent (`de.idnr`/`de.stnr`, `in.aadhaar`/`in.vid`) behind Tax ID vs TIN and vNIN vs NIN.
6. **Cite a source, or leave it out** — with the full list of what that rule has excluded: prefix `0917`, Yoruba labels, Pidgin labels, plate LGA decoding, VIN hex enforcement, historic area codes.
7. **`detect()` ordering is load-bearing** — including the measured 0.09% trade behind placing fixed-line ahead of NIN.
8. **Subpaths keep the main entry small** — the bundle measurements, and the constraint that `redact.ts` must not import the bank dataset.

Plus a sources list and the known follow-ons. Linked from `CONTRIBUTING.md`.

`docs/` adds nothing to the published package — `files` is `["dist"]`, verified with `npm pack --dry-run`.

## 0.5.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "naija-id",
"version": "0.5.0",
"version": "0.5.1",
"description": "Zero-dependency validators, formatters and PII redaction for Nigerian identifiers — phone (E.164), NIN, vNIN, BVN, Tax ID, TIN, CAC, NUBAN, plate, passport, driver's licence and RSA PIN.",
"keywords": [
"nigeria",
Expand Down