Skip to main content

v0.5.0 — as shipped

A single landing page for anyone catching up on the v0.5.0 fresh-slate work.

The v0.5.0 plan (PHASE_8_v0_5_0_fresh_slate.md) split the work into six threadsthreadA parallel workstream within a release. Threads compose; they are not sequential milestones like phases. (A through F). All six landed in main by 2026-05-24. This article catalogues what is now in the tree, how the piecesECE (Expected Calibration Error). A metric that measures how well a model's confidence scores align with its actual accuracy. Lower is better. Mailwoman's held-out ECE drops from 0.067 (raw) to 0.0035 (calibrated). fit together, and what is still cooking on the trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. side.

Why v0.5.0 exists

The v0.4.0 ablation campaign retrospective ended with three structural ceilings that small recipe tweaks could not clear:

  1. The v0.1.0 tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses.'s byte-fallback rate on non-Latin scripts (the cause of 92% of countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. FN in the golden evalevalRunning the model against a held-out golden dataset and computing per-component F1, exact-match, calibration, and resolved-coordinate error.).
  2. The classifier doing boundary discovery and type classification at the same time via BIO labelsBIO tagging (Begin-Inside-Outside). A token-level labeling scheme where each token is tagged as B-X (beginning of an entity of type X), I-X (inside an entity of type X), or O (outside any entity). Mailwoman uses BIO over SentencePiece tokens to annotate address components. (the cause of the bio_slip slice on ", 22220" for 22220).
  3. StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 5 reconcile only sorting spansspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. — it could not catch joint-incoherent parsesaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. like NY-NY Steakhouse, Houston, TX.

Patching each ceiling individually meant three medium iterations. v0.5.0 bundles them into one fresh-slate ship — pay the cost once, clear all three at once.

The "fresh-slate" framing is described in the operator's sharpen-the-axe note — it is the right shape when several improvements share a common cost (a retrain, an interface change) and bundling avoids paying that cost three times.

The six threads

ThreadthreadA parallel workstream within a release. Threads compose; they are not sequential milestones like phases.NameWhat it addsPR
A0TokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. harness + A0 weightsparameterA single learned number inside a model — one weight or bias. Mailwoman's encoder has roughly 30 million of them; training is the search for good values.SentencePieceSentencePieceA language-independent subword tokenizer that splits text into pieces using a unigram language model. Mailwoman uses a SentencePiece tokenizer with a 48,000-token vocabulary and byte-fallback, trained on address data rather than general text. trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. pipelinestaged pipelineMailwoman's runtime architecture: a sequence of pure-function stages (normalize → query-shape → locale-gate → kind-classifier → phrase-grouper → classifier → decoder) connected by typed handoffs. Each stage is published as its own npm package.; A0 trained on corpus-v0.3.0 as a byte-fallback baseline. A1 will retrain on corpus-v0.4.0 once B + B2 are both in.#129
BKryptonite catalogue4,771 adversarial address rows generated via DeepSeek — NY-NY Steakhouse, Paris, Texas, Saint Petersburg, FL, etc. Each annotated with the correct parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates..#130
B2TransliterationtransliterationConverting a name from one writing system to another while preserving pronunciation (Cyrillic → Latin, for instance). Needed for multilingual address handling and corpus synthesis. pairs~73K US/FR addresses transliterated into CJK / Cyrillic / Hangul / Han / Armenian script via DeepSeek. Validated by substring-match aligner (~1.1% reject ratereject rateThe fraction of generated or harvested rows that fail validation and are excluded from the corpus — a quality gauge for a synthesis source.). Included in corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus.-v0.4.0.#119
C-sClassifier code pathTop-k inferenceinferenceRunning the trained model on new input to get predictions, as opposed to training, which produces the model. In Mailwoman that means a small transformer encoder reads an address string and classifies every token — house number, street, locality, region, postcode, and the rest. A Who's On First gazetteer can feed soft location hints into the pass, but the model makes the final call on every label. Where a generative model writes text token by token, Mailwoman's output is a retrieval-augmented token classification: one label per input piece. (returns ranked sequences, not just argmax) + phrase-prior input featuresfeatureAn input signal a model conditions on. Beyond the raw tokens, Mailwoman feeds soft features — gazetteer-membership channels and the postcode anchor — that inform predictions without overriding them. that condition on StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 2.7's proposed spansspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree.. No trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. run in this PR — that lands once A1 + corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus.-v0.4.0 are ready.#128
D-sStagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 5 reconcilereconcile.ts joint decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs.beam searchbeam searchA decoding search that keeps the top-k partial candidates at each position. Used in Stage-5 reconciliation to explore the (phrase, tag, resolver) space with controlled pruning. over (spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. × tag × resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon. candidate) with concordanceconcordanceA joint-decode signal that rewards a parse whose spans form a consistent Who's On First parent-child chain and vetoes contradictory ones — a hard veto for conflicts, a log-space bonus for full agreement. scoring via WOFWOF (Who's On First). An open-source gazetteer of places maintained by Mapzen/whosonfirst. Mailwoman builds a custom SQLite database from WOF GeoJSON repos, extended with postcode data, importance scores, and coincident-role relations. parent-id chains. Catches the kryptonite cases at runtime.#131
EPhrase grouperphrase grouperStage 2.7 of the runtime pipeline: proposes coherent input units (street phrase, locality phrase, postcode, etc.) with structural kind hypotheses. Decouples boundary discovery from type classification so the classifier answers 'what type?' not 'where?'New @mailwoman/phrase-grouper workspace — StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 2.7 proposes coherent input spansspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. (streetstreetThe named linear feature along which house numbers are ordered. Decomposes into a name plus street affixes; one of the Tier 2 fine labels., postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one., localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy., …) before StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 3 runs. Rule-based v1 only; learned spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. proposer scoped for v0.5.1 (PHASE_8_E).#126
FVerdict-smokeverdict-smokeA short diagnostic training run (≈1,500–3,000 steps) that must match the full run's gradient-noise profile, used to catch recipe instability before committing to a full 50k-step launch. disciplineNew VERDICT_SMOKES.md + --smoke-mode {constant,long-tail} flag, so the cosine-LR mask that hid v0.4.0's divergencedivergenceA training failure where loss descends through warmup, plateaus low for a while, then climbs catastrophically back to its starting magnitude — the model unlearns everything despite no obvious component failure. cannot reoccur.#125

How the threads compose

The threadsthreadA parallel workstream within a release. Threads compose; they are not sequential milestones like phases. were designed to be parallel where possible and stacked where unavoidable. The actual data dependencies look like this:

Solid boxes are merged. The A1 tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. was retrained on corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus.-v0.4.0 and halved byte-fallback (36.7% → 18.2%). The C-train (full classifier trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. run) is the remaining item — CE-only trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. in progress as of 2026-05-25.

The single biggest schedule reframe was A0 — the plan originally said "A is blocked by B" because the tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. trains on the same corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. as the classifier. We split that into:

  • A0 trains on corpus-v0.3.0 immediately to validate the harness and establish a byte-fallback baseline.
  • A1 retrains on corpus-v0.4.0 (= v0.3.0 + B + B2) when the corpuscorpusThe BIO-labeled training data used to train Mailwoman's neural classifier. Assembled from real sources (OpenAddresses, National Address Database) and synthetic shards (boundary stress, order variants, negative space). Managed by @mailwoman/corpus. is complete.

That way A0 could ship in parallel with B + E + the scaffolds, instead of waiting for B + B2 to finish.

The other parallel-friendly move was C-s and D-s as scaffolds. The plan had C and D as serial trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input./integration work that needed real classifier output to validate. We pulled the code portion to t0 (forward-pass tests against stub data, mocked top-k for StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 5) and deferred only the actual trainingtrainingThe process of adjusting a model's parameters so its predictions match labeled examples, by repeatedly measuring error and nudging the weights to reduce it. Distinct from inference, when the trained model is run on new input. run. That left the only mandatory serial portion as B → A1 → C-train.

What is still cooking

ItemStateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.ETA
CE-only full 50K C-trainIn progress. Smoke passed: val_macro_f1=0.444, no divergencedivergenceA training failure where loss descends through warmup, plateaus low for a while, then climbs catastrophically back to its starting magnitude — the model unlearns everything despite no obvious component failure. past step 2000. Full 50K run targeting first stable v0.5.0 weightsparameterA single learned number inside a model — one weight or bias. Mailwoman's encoder has roughly 30 million of them; training is the search for good values..~6-8h from launch.
C-train full classifier runBlocked on A1 + corpus-v0.4.0. Estimated single H100-day on rented compute per the plan.After A1 lands.

Three smaller follow-ups carried over from postmortemsexpectation-maximizationAn iterative algorithm that estimates model parameters when some variables are unobserved. In Mailwoman's matcher, EM learns the Fellegi-Sunter m and u parameters from unlabeled data — no training labels needed.:

  • Wire reconcileSpans as the default StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 5 in runPipeline (currently behind an explicit call). Lands once the classifier emits real top-k. Tracked in D-s's PR body.
  • Learned phrase-grouper variant (1-2M-param spanspanA contiguous range of characters or tokens in the input string, tagged with an address component type (street, locality, postcode, etc.). Parsed addresses are represented as collections of spans, possibly nested in a tree. proposer). Scope written in PHASE_8_E_learned_span_proposer.md. v0.5.1 stretch.
  • Reservoir-sampling parallelisation in the tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. harness (~5× speedup possible per A0's session notes). Out-of-scope until A1 turnaround time becomes a real cost.

If you are catching up on the architecture, read in this order:

  1. The knowledge ladder — the conceptual framing for why the two new layerslayerOne transformer block — attention plus a feed-forward network, with normalization and residual connections — applied to every position. Stacking layers lets the model build up richer representations; Mailwoman's encoder has 6. (StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 2.7 phrase grouperphrase grouperStage 2.7 of the runtime pipeline: proposes coherent input units (street phrase, locality phrase, postcode, etc.) with structural kind hypotheses. Decouples boundary discovery from type classification so the classifier answers 'what type?' not 'where?', expanded StagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). 5 reconcile) exist.
  2. The staged pipeline — the runtime composition end-to-end.
  3. STAGES.md — formal per-stagestageOne of the dataflow stages in the runtime pipeline (normalize, locale gate, kind classify, phrase group, token classify, sequence correct, reconcile, resolve). Distinct from tier (model vocabulary) and phase (plan milestone). type contracts.
  4. VERDICT_SMOKES.md — the process discipline that kept v0.5.0 from repeating v0.4.0's cosine-LR mask bug.

If you want the line-by-line technical history, the v0.4.0 retrospective (retrospectives/v0-4-0-ablation-campaign.md) is what motivated v0.5.0; this article is the bookend.