FAILURE MAP
← Case archive

FA-96301 / Postal address normalization / Open access

Address display casing: two-letter directionals are title-cased · case 01

"NE" prints as "Ne".

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The keep set only lists single-letter directionals, PO, RR and HC.

VERIFIED REPAIR

Keep all directionals, including NE, NW, SE, SW, uppercase.

Unsuccessful approach: Keeping every token of two letters or fewer also leaves the suffix "ST" in capitals.

Case contract

Input a normalized uppercase line. Tokens in the keep set (PO, NE, NW, SE, SW, N, S, E, W, RR, HC) stay uppercase. Tokens starting with a digit keep the digits; an ordinal tail ST/ND/RD/TH is lowercased, any other tail (a unit letter) is kept. Other tokens are capitalized per hyphen part and per apostrophe part, and a part starting with MC is written Mc plus a capital.

Why this case matters

Normalized addresses are stored uppercase but printed on customer-facing documents; wrong casing of ordinals, directionals and unit letters looks like a different address.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    KEEP = {'PO', 'N', 'S', 'E', 'W', 'RR', 'HC'}
    def cap(p):
        if p.startswith('MC') and len(p) > 2:
            return 'Mc' + p[2:3] + p[3:].lower()
        return p[:1] + p[1:].lower()
    out = []
    for w in x.split():
        if w in KEEP:
            out.append(w)
        elif w[0].isdigit():
            n = 0
            while n < len(w) and w[n].isdigit():
                n += 1
            tail = w[n:]
            out.append(w[:n] + (tail.lower() if tail in ('ST', 'ND', 'RD', 'TH') else tail))
        else:
            parts = ["'".join(cap(q) for q in part.split("'")) for part in w.split('-')]
            out.append('-'.join(parts))
    return ' '.join(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['numeric ordinal', '21ST ST', '21st St'], ['unit identifier keeps its letter', 'APT 1B', 'Apt 1B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 12', 'PO Box 12'], ['standalone suffix', '5 FAKE ST', '5 Fake St']], [['numeric ordinal', '31ST ST', '31st St'], ['unit identifier keeps its letter', 'APT 2B', 'Apt 2B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 13', 'PO Box 13'], ['standalone suffix', '6 FAKE ST', '6 Fake St']], [['numeric ordinal', '41ST ST', '41st St'], ['unit identifier keeps its letter', 'APT 3B', 'Apt 3B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 14', 'PO Box 14'], ['standalone suffix', '7 FAKE ST', '7 Fake St']], [['numeric ordinal', '51ST ST', '51st St'], ['unit identifier keeps its letter', 'APT 4B', 'Apt 4B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 15', 'PO Box 15'], ['standalone suffix', '8 FAKE ST', '8 Fake St']], [['numeric ordinal', '61ST ST', '61st St'], ['unit identifier keeps its letter', 'APT 5B', 'Apt 5B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 16', 'PO Box 16'], ['standalone suffix', '9 FAKE ST', '9 Fake St']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
numeric ordinal21st St21st StPassed
unit identifier keeps its letterApt 1BApt 1BPassed
Mc surname street with directionalMcFake Ave NeMcFake Ave NEFailed
hyphenated street nameFake-Side RdFake-Side RdPassed
apostrophe street nameO'Fake LnO'Fake LnPassed
box linePO Box 12PO Box 12Passed
standalone suffix5 Fake St5 Fake StPassed

SHA-256 / 42bf9bd8338ad0c9feec29fdb2174331532b781b92430368be67a30da5367b07

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    KEEP = {'PO', 'NE', 'NW', 'SE', 'SW', 'N', 'S', 'E', 'W', 'RR', 'HC'}
    def cap(p):
        if p.startswith('MC') and len(p) > 2:
            return 'Mc' + p[2:3] + p[3:].lower()
        return p[:1] + p[1:].lower()
    out = []
    for w in x.split():
        if len(w) <= 2:
            out.append(w)
        elif w[0].isdigit():
            n = 0
            while n < len(w) and w[n].isdigit():
                n += 1
            tail = w[n:]
            out.append(w[:n] + (tail.lower() if tail in ('ST', 'ND', 'RD', 'TH') else tail))
        else:
            parts = ["'".join(cap(q) for q in part.split("'")) for part in w.split('-')]
            out.append('-'.join(parts))
    return ' '.join(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['numeric ordinal', '21ST ST', '21st St'], ['unit identifier keeps its letter', 'APT 1B', 'Apt 1B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 12', 'PO Box 12'], ['standalone suffix', '5 FAKE ST', '5 Fake St']], [['numeric ordinal', '31ST ST', '31st St'], ['unit identifier keeps its letter', 'APT 2B', 'Apt 2B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 13', 'PO Box 13'], ['standalone suffix', '6 FAKE ST', '6 Fake St']], [['numeric ordinal', '41ST ST', '41st St'], ['unit identifier keeps its letter', 'APT 3B', 'Apt 3B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 14', 'PO Box 14'], ['standalone suffix', '7 FAKE ST', '7 Fake St']], [['numeric ordinal', '51ST ST', '51st St'], ['unit identifier keeps its letter', 'APT 4B', 'Apt 4B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 15', 'PO Box 15'], ['standalone suffix', '8 FAKE ST', '8 Fake St']], [['numeric ordinal', '61ST ST', '61st St'], ['unit identifier keeps its letter', 'APT 5B', 'Apt 5B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 16', 'PO Box 16'], ['standalone suffix', '9 FAKE ST', '9 Fake St']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
numeric ordinal21st ST21st StFailed
unit identifier keeps its letterApt 1BApt 1BPassed
Mc surname street with directionalMcFake Ave NEMcFake Ave NEPassed
hyphenated street nameFake-Side RDFake-Side RdFailed
apostrophe street nameO'Fake LNO'Fake LnFailed
box linePO Box 12PO Box 12Passed
standalone suffix5 Fake ST5 Fake StFailed

SHA-256 / e6a07472c6cc33c89824e954012419b4666ffb89ad8ffa0fd6778c78444a0ca7

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    KEEP = {'PO', 'NE', 'NW', 'SE', 'SW', 'N', 'S', 'E', 'W', 'RR', 'HC'}
    def cap(p):
        if p.startswith('MC') and len(p) > 2:
            return 'Mc' + p[2:3] + p[3:].lower()
        return p[:1] + p[1:].lower()
    out = []
    for w in x.split():
        if w in KEEP:
            out.append(w)
        elif w[0].isdigit():
            n = 0
            while n < len(w) and w[n].isdigit():
                n += 1
            tail = w[n:]
            out.append(w[:n] + (tail.lower() if tail in ('ST', 'ND', 'RD', 'TH') else tail))
        else:
            parts = ["'".join(cap(q) for q in part.split("'")) for part in w.split('-')]
            out.append('-'.join(parts))
    return ' '.join(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['numeric ordinal', '21ST ST', '21st St'], ['unit identifier keeps its letter', 'APT 1B', 'Apt 1B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 12', 'PO Box 12'], ['standalone suffix', '5 FAKE ST', '5 Fake St']], [['numeric ordinal', '31ST ST', '31st St'], ['unit identifier keeps its letter', 'APT 2B', 'Apt 2B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 13', 'PO Box 13'], ['standalone suffix', '6 FAKE ST', '6 Fake St']], [['numeric ordinal', '41ST ST', '41st St'], ['unit identifier keeps its letter', 'APT 3B', 'Apt 3B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 14', 'PO Box 14'], ['standalone suffix', '7 FAKE ST', '7 Fake St']], [['numeric ordinal', '51ST ST', '51st St'], ['unit identifier keeps its letter', 'APT 4B', 'Apt 4B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 15', 'PO Box 15'], ['standalone suffix', '8 FAKE ST', '8 Fake St']], [['numeric ordinal', '61ST ST', '61st St'], ['unit identifier keeps its letter', 'APT 5B', 'Apt 5B'], ['Mc surname street with directional', 'MCFAKE AVE NE', 'McFake Ave NE'], ['hyphenated street name', 'FAKE-SIDE RD', 'Fake-Side Rd'], ['apostrophe street name', "O'FAKE LN", "O'Fake Ln"], ['box line', 'PO BOX 16', 'PO Box 16'], ['standalone suffix', '9 FAKE ST', '9 Fake St']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
numeric ordinal21st St21st StPassed
unit identifier keeps its letterApt 1BApt 1BPassed
Mc surname street with directionalMcFake Ave NEMcFake Ave NEPassed
hyphenated street nameFake-Side RdFake-Side RdPassed
apostrophe street nameO'Fake LnO'Fake LnPassed
box linePO Box 12PO Box 12Passed
standalone suffix5 Fake St5 Fake StPassed

SHA-256 / 310971a53c14fe1f3e01f1fda47108596d23567ecf03b5373aef58c8ceeb11e3

Verification & scope

A deterministic toy contract over synthetic, obviously fictitious addresses. The rules are stipulated for this model only and make no claim of conformance with any postal authority standard. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:52:21.530871+00:00.

Case digest / 4e286607660a85816b991fe556c9542f0e6f1fc8c998c4c643257ee6ca8049a0