/** * @copyright Sister Software * @license AGPL-3.0 * @author Teffen Ellis, et al. * * `street-affix` slice recipe — the US street-affix coverage slice (the v0-parity `street_prefix` / * `street_suffix` gap — both ~0% F1 in the #15 assessment, collapsed into `street`). Raises * PREVALENCE of affix-split streets with format diversity so the model learns to split "N Main * St" → street_prefix="N" + street="Main" + street_suffix="St", and (negative space) sharpens * `street` itself. Ported from scripts/build-street-affix-slice.mjs. * * Reads REAL US OpenAddresses tuples and SPLITS the OA `street` field via the codex: * `matchLeadingDirectional` (USPS Pub-28 C1) for the prefix, `matchTrailingSuffix` (Pub-28 C2 * street suffixes) for the suffix. OA streets nearly all carry a suffix; only ~10-20% carry a * directional, so we INJECT a directional prefix onto a fraction of prefix-less streets to give * `street_prefix` real signal. Each row varies surface form per affix — abbreviated ("N", "St") * vs expanded ("North", "Street") — and varies the layout (full address / bare / street-only / * venue-prefixed). * * LEAKAGE-SAFE EVAL (`--golden`): held-out eval uses the VERMONT source only (the corpus * defaultHoldout), a different seed, and emits {raw, components} for per-locale-f1. Train uses * every NON-Vermont US source. * * Multi-locale BALANCE (`--multilocale-count`, opts.multilocaleCount > 0): appends NO-affix * native-order rows (FR/DE/IT/NL) AFTER the US affix rows, riding the same source weight, purely * to keep the postcode-ORDER distribution multi-locale so a US-heavy affix slice doesn't dilute * FR/DE postcode (the v0.9.8 blemish). */ import type { ComponentTag } from "@mailwoman/codex/component"; import { type CorpusRecipe } from "#recipes/scaffold"; /** * A real US skeleton tuple read from a cached OA zip. */ interface USTuple { house_number: string; street: string; locality: string; region: string; postcode: string; base_source_id: string; } export type SuffixBoundaryClass = "terminal-only" | "terminal-contrast"; /** * Classify a real street surface for #1569. `terminal-only` has an ambiguous suffix-eligible name word immediately * before a different terminal type (`Blue Hill Rd`); `terminal-contrast` ends at the ambiguous word itself (`Sutton * Hollow`). The contrast check intentionally wins when both final words are name-prone: only the LAST token is the * suffix under the canonical rule. */ export declare function classifySuffixBoundaryStreet(street: string): SuffixBoundaryClass | null; /** * Layout-shell options for {@link renderRow}. `cutoffs` are the cumulative random() boundaries for [full, bare, * street-only] — the remainder is the venue shell. Defaults reproduce the original street-affix distribution * (40/25/20/15) with the six template venues. */ interface RenderRowOpts { venues?: readonly string[]; cutoffs?: readonly [number, number, number]; } /** * Embed the rendered street in a RANDOM layout so the model recognizes affixes wherever the street sits: full address, * bare house+street, street-only (pure affix parse), or venue-prefixed. */ export declare function renderRow(random: () => number, base: USTuple, street: string, streetComponents: Partial>, opts?: RenderRowOpts): { fmt: string; raw: string; components: Partial>; }; /** * Slice recipe registered with the corpus builder — see the file header for the parse behaviour it exists to exercise, * and `description` below for the surface form it generates. */ export declare const streetAffixRecipe: CorpusRecipe; /** * #1569 root-fix slice. Both classes come from real non-Vermont OA streets and use the affix recipe's existing layout * diversity. v4.3.1 makes terminal-only 80% of the mix: the first 40/60 run moved a 100-row TRAIN sample only 4→11 * while contrast was already 95/100 before training (93/100 after). Post-run audit found that the global affix relabel * pass corrupts many already-decomposed target rows into double suffixes; do not retrain this recipe until relabel is * idempotent over a decomposed street family. The 20% contrast leg remains explicit, additive to the already-strong * base distribution, and B2 still checks it unchanged. * * V2 (corpus 0.19.0, 2026-08-10 recipe review): the v4.3.3 board split (rich venue-led rows 5/43 vs bare 53/65) showed * the model separating template rows from real ones, and the venue shell was the giveaway — six fixed venue strings. v2 * draws the venue shell from thousands of REAL HRSA facility names and raises its share (venue 30%, full 35%, bare 20%, * street-only 15%). Dose policy moved to the recipe's config side: weight ≤4 effective passes per run (Muennighoff * 2023's repetition knee) and the source is excluded from the augmentation pool — see the v4.4.0 config. */ export declare const suffixBoundaryRecipe: CorpusRecipe; export {}; //# sourceMappingURL=affix.d.ts.map