FAILURE MAP
← Case archive

FA-80821 / Bidirectional text layout / Open access

Paragraph separation and direction: per-paragraph first strong · case 01

All paragraphs get the direction of the first paragraph.

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

ROOT CAUSE

The first-strong scan reads the whole text instead of the paragraph.

VERIFIED REPAIR

Scan each paragraph separately.

Unsuccessful approach: Scanning only the first character misses leading digits and spaces.

Case contract

Input [text, default level]. Paragraph separators (\n, \r, U+2029; \r\n counts once) end a paragraph and stay with it. A trailing non-empty remainder is a paragraph. Each paragraph takes level 1 if its first letter is uppercase (stand-in for RTL), 0 if lowercase, else the default. Return [[paragraph, level]].

Why this case matters

Mixed right-to-left and left-to-right text must resolve levels and visual order exactly, or words, numbers and carets land in the wrong place.

1 / The failure

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

N = 1
observations = []
def solve(x):
    text, default = x
    paras = []
    cur = ''
    i = 0
    while i < len(text):
        ch = text[i]
        if ch == '\r' and text[i + 1:i + 2] == '\n':
            cur += '\r\n'
            paras.append(cur)
            cur = ''
            i += 2
            continue
        cur += ch
        if ch in '\n\r\u2029':
            paras.append(cur)
            cur = ''
        i += 1
    if cur:
        paras.append(cur)
    out = []
    for p in paras:
        level = default
        for ch in text:
            if ch.isalpha():
                level = 1 if ch.isupper() else 0
                break
        out.append([p, level])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('regression: per-paragraph first strong', ['bX12\nYX\r\n2\u2029b\nXa', 1], [['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]), ('regression: per-paragraph first strong', ['XX\r\nc!,,1\n.1,Y', 0], [['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]), ('regression: per-paragraph first strong', ['\ncZ2.\na..X!\n!Z,.', 0], [['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['cZZ2\n1\u2029!', 0], [['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]), ('control layout', ['2\n,,.1!', 0], [['2\n', 0], [',,.1!', 0]])], [('regression: per-paragraph first strong', ['1Xab,X,\r21\u2029!c', 0], [['1Xab,X,\r', 1], ['21\u2029', 0], ['!c', 0]]), ('regression: per-paragraph first strong', ['Xa!cZ!,\n22\u2029Za', 0], [['Xa!cZ!,\n', 1], ['22\u2029', 0], ['Za', 1]]), ('partial-repair probe', [' !.Yb!X,a', 0], [[' !.Yb!X,a', 1]]), ('regression: per-paragraph first strong', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['a1!X!', 1], [['a1!X!', 0]]), ('control layout', ['2,\r\n\n\u2029.', 1], [['2,\r\n', 1], ['\n', 1], ['\u2029', 1], ['.', 1]])], [('regression: per-paragraph first strong', ['\n\na', 1], [['\n', 1], ['\n', 1], ['a', 0]]), ('regression: per-paragraph first strong', ['b\n\n\u2029..\r\na.!bZ\nXc1', 0], [['b\n', 0], ['\n', 0], ['\u2029', 0], ['..\r\n', 0], ['a.!bZ\n', 0], ['Xc1', 1]]), ('partial-repair probe', ['1 2a,\n', 1], [['1 2a,\n', 0]]), ('regression: per-paragraph first strong', ['\r\nZ\r\nZ\n,!!.X\r\nb!YZ', 0], [['\r\n', 0], ['Z\r\n', 1], ['Z\n', 1], [',!!.X\r\n', 1], ['b!YZ', 0]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['\n ..Y\n.,2\nY', 1], [['\n', 1], [' ..Y\n', 1], ['.,2\n', 1], ['Y', 1]]), ('control layout', ['bY\r \r\nb', 0], [['bY\r', 0], [' \r\n', 0], ['b', 0]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['cX1 \nXX', 1], [['cX1 \n', 0], ['XX', 1]]), ('partial-repair probe', ['X\u20291Y..\u2029!2Z', 0], [['X\u2029', 1], ['1Y..\u2029', 1], ['!2Z', 1]]), ('regression: per-paragraph first strong', ['!c\n\n\r\naY', 1], [['!c\n', 0], ['\n', 1], ['\r\n', 1], ['aY', 0]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['b!X!2Y', 0], [['b!X!2Y', 0]]), ('control layout', [' Y,1Y\n\r\n', 1], [[' Y,1Y\n', 1], ['\r\n', 1]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 0]]), ('regression: per-paragraph first strong', ['\r\n.\n!!Y2c', 0], [['\r\n', 0], ['.\n', 0], ['!!Y2c', 1]]), ('regression: per-paragraph first strong', ['.bca\n \n\r\n \n\r2', 1], [['.bca\n', 0], [' \n', 1], ['\r\n', 1], [' \n', 1], ['\r', 1], ['2', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['bZY!\n! cc\n', 0], [['bZY!\n', 0], ['! cc\n', 0]]), ('control layout', ['\n\r,YX12Y.\r\n\n', 1], [['\n', 1], ['\r', 1], [',YX12Y.\r\n', 1], ['\n', 1]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), 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
CRLF is one separator[['ab\r\n', 0], ['XY', 0]][['ab\r\n', 0], ['XY', 1]]Failed
regression: per-paragraph first strong[['bX12\n', 0], ['YX\r\n', 0], ['2\u2029', 0], ['b\n', 0], ['Xa', 0]][['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]Failed
regression: per-paragraph first strong[['XX\r\n', 1], ['c!,,1\n', 1], ['.1,Y', 1]][['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]Failed
regression: per-paragraph first strong[['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 0]][['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]Failed
separator only paragraph[['a\n', 0], ['\n', 0], ['Z', 0]][['a\n', 0], ['\n', 1], ['Z', 1]]Failed
digits then letter[['12 X\n', 1]][['12 X\n', 1]]Passed
control layout[['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]][['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]Passed
control layout[['2\n', 0], [',,.1!', 0]][['2\n', 0], [',,.1!', 0]]Passed

SHA-256 / eea4c4c81114ee60589ef2ee99f39ed15b32cb22832fdf2ffcbb88c49e62c7d1

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    text, default = x
    paras = []
    cur = ''
    i = 0
    while i < len(text):
        ch = text[i]
        if ch == '\r' and text[i + 1:i + 2] == '\n':
            cur += '\r\n'
            paras.append(cur)
            cur = ''
            i += 2
            continue
        cur += ch
        if ch in '\n\r\u2029':
            paras.append(cur)
            cur = ''
        i += 1
    if cur:
        paras.append(cur)
    out = []
    for p in paras:
        level = default
        for ch in p[:1]:
            if ch.isalpha():
                level = 1 if ch.isupper() else 0
                break
        out.append([p, level])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('regression: per-paragraph first strong', ['bX12\nYX\r\n2\u2029b\nXa', 1], [['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]), ('regression: per-paragraph first strong', ['XX\r\nc!,,1\n.1,Y', 0], [['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]), ('regression: per-paragraph first strong', ['\ncZ2.\na..X!\n!Z,.', 0], [['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['cZZ2\n1\u2029!', 0], [['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]), ('control layout', ['2\n,,.1!', 0], [['2\n', 0], [',,.1!', 0]])], [('regression: per-paragraph first strong', ['1Xab,X,\r21\u2029!c', 0], [['1Xab,X,\r', 1], ['21\u2029', 0], ['!c', 0]]), ('regression: per-paragraph first strong', ['Xa!cZ!,\n22\u2029Za', 0], [['Xa!cZ!,\n', 1], ['22\u2029', 0], ['Za', 1]]), ('partial-repair probe', [' !.Yb!X,a', 0], [[' !.Yb!X,a', 1]]), ('regression: per-paragraph first strong', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['a1!X!', 1], [['a1!X!', 0]]), ('control layout', ['2,\r\n\n\u2029.', 1], [['2,\r\n', 1], ['\n', 1], ['\u2029', 1], ['.', 1]])], [('regression: per-paragraph first strong', ['\n\na', 1], [['\n', 1], ['\n', 1], ['a', 0]]), ('regression: per-paragraph first strong', ['b\n\n\u2029..\r\na.!bZ\nXc1', 0], [['b\n', 0], ['\n', 0], ['\u2029', 0], ['..\r\n', 0], ['a.!bZ\n', 0], ['Xc1', 1]]), ('partial-repair probe', ['1 2a,\n', 1], [['1 2a,\n', 0]]), ('regression: per-paragraph first strong', ['\r\nZ\r\nZ\n,!!.X\r\nb!YZ', 0], [['\r\n', 0], ['Z\r\n', 1], ['Z\n', 1], [',!!.X\r\n', 1], ['b!YZ', 0]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['\n ..Y\n.,2\nY', 1], [['\n', 1], [' ..Y\n', 1], ['.,2\n', 1], ['Y', 1]]), ('control layout', ['bY\r \r\nb', 0], [['bY\r', 0], [' \r\n', 0], ['b', 0]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['cX1 \nXX', 1], [['cX1 \n', 0], ['XX', 1]]), ('partial-repair probe', ['X\u20291Y..\u2029!2Z', 0], [['X\u2029', 1], ['1Y..\u2029', 1], ['!2Z', 1]]), ('regression: per-paragraph first strong', ['!c\n\n\r\naY', 1], [['!c\n', 0], ['\n', 1], ['\r\n', 1], ['aY', 0]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['b!X!2Y', 0], [['b!X!2Y', 0]]), ('control layout', [' Y,1Y\n\r\n', 1], [[' Y,1Y\n', 1], ['\r\n', 1]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 0]]), ('regression: per-paragraph first strong', ['\r\n.\n!!Y2c', 0], [['\r\n', 0], ['.\n', 0], ['!!Y2c', 1]]), ('regression: per-paragraph first strong', ['.bca\n \n\r\n \n\r2', 1], [['.bca\n', 0], [' \n', 1], ['\r\n', 1], [' \n', 1], ['\r', 1], ['2', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['bZY!\n! cc\n', 0], [['bZY!\n', 0], ['! cc\n', 0]]), ('control layout', ['\n\r,YX12Y.\r\n\n', 1], [['\n', 1], ['\r', 1], [',YX12Y.\r\n', 1], ['\n', 1]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), 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
CRLF is one separator[['ab\r\n', 0], ['XY', 1]][['ab\r\n', 0], ['XY', 1]]Passed
regression: per-paragraph first strong[['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]][['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]Passed
regression: per-paragraph first strong[['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 0]][['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]Failed
regression: per-paragraph first strong[['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 0]][['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]Failed
separator only paragraph[['a\n', 0], ['\n', 1], ['Z', 1]][['a\n', 0], ['\n', 1], ['Z', 1]]Passed
digits then letter[['12 X\n', 0]][['12 X\n', 1]]Failed
control layout[['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]][['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]Passed
control layout[['2\n', 0], [',,.1!', 0]][['2\n', 0], [',,.1!', 0]]Passed

SHA-256 / dd9b302c6acf23f944e4df433a7047483a706bdd36c61755d4163d5323193753

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    text, default = x
    paras = []
    cur = ''
    i = 0
    while i < len(text):
        ch = text[i]
        if ch == '\r' and text[i + 1:i + 2] == '\n':
            cur += '\r\n'
            paras.append(cur)
            cur = ''
            i += 2
            continue
        cur += ch
        if ch in '\n\r\u2029':
            paras.append(cur)
            cur = ''
        i += 1
    if cur:
        paras.append(cur)
    out = []
    for p in paras:
        level = default
        for ch in p:
            if ch.isalpha():
                level = 1 if ch.isupper() else 0
                break
        out.append([p, level])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('regression: per-paragraph first strong', ['bX12\nYX\r\n2\u2029b\nXa', 1], [['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]), ('regression: per-paragraph first strong', ['XX\r\nc!,,1\n.1,Y', 0], [['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]), ('regression: per-paragraph first strong', ['\ncZ2.\na..X!\n!Z,.', 0], [['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['cZZ2\n1\u2029!', 0], [['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]), ('control layout', ['2\n,,.1!', 0], [['2\n', 0], [',,.1!', 0]])], [('regression: per-paragraph first strong', ['1Xab,X,\r21\u2029!c', 0], [['1Xab,X,\r', 1], ['21\u2029', 0], ['!c', 0]]), ('regression: per-paragraph first strong', ['Xa!cZ!,\n22\u2029Za', 0], [['Xa!cZ!,\n', 1], ['22\u2029', 0], ['Za', 1]]), ('partial-repair probe', [' !.Yb!X,a', 0], [[' !.Yb!X,a', 1]]), ('regression: per-paragraph first strong', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['a1!X!', 1], [['a1!X!', 0]]), ('control layout', ['2,\r\n\n\u2029.', 1], [['2,\r\n', 1], ['\n', 1], ['\u2029', 1], ['.', 1]])], [('regression: per-paragraph first strong', ['\n\na', 1], [['\n', 1], ['\n', 1], ['a', 0]]), ('regression: per-paragraph first strong', ['b\n\n\u2029..\r\na.!bZ\nXc1', 0], [['b\n', 0], ['\n', 0], ['\u2029', 0], ['..\r\n', 0], ['a.!bZ\n', 0], ['Xc1', 1]]), ('partial-repair probe', ['1 2a,\n', 1], [['1 2a,\n', 0]]), ('regression: per-paragraph first strong', ['\r\nZ\r\nZ\n,!!.X\r\nb!YZ', 0], [['\r\n', 0], ['Z\r\n', 1], ['Z\n', 1], [',!!.X\r\n', 1], ['b!YZ', 0]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('control layout', ['\n ..Y\n.,2\nY', 1], [['\n', 1], [' ..Y\n', 1], ['.,2\n', 1], ['Y', 1]]), ('control layout', ['bY\r \r\nb', 0], [['bY\r', 0], [' \r\n', 0], ['b', 0]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['cX1 \nXX', 1], [['cX1 \n', 0], ['XX', 1]]), ('partial-repair probe', ['X\u20291Y..\u2029!2Z', 0], [['X\u2029', 1], ['1Y..\u2029', 1], ['!2Z', 1]]), ('regression: per-paragraph first strong', ['!c\n\n\r\naY', 1], [['!c\n', 0], ['\n', 1], ['\r\n', 1], ['aY', 0]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['b!X!2Y', 0], [['b!X!2Y', 0]]), ('control layout', [' Y,1Y\n\r\n', 1], [[' Y,1Y\n', 1], ['\r\n', 1]])], [('regression: per-paragraph first strong', ['!c\r\n2bb\n22', 1], [['!c\r\n', 0], ['2bb\n', 0], ['22', 1]]), ('regression: per-paragraph first strong', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 0]]), ('regression: per-paragraph first strong', ['\r\n.\n!!Y2c', 0], [['\r\n', 0], ['.\n', 0], ['!!Y2c', 1]]), ('regression: per-paragraph first strong', ['.bca\n \n\r\n \n\r2', 1], [['.bca\n', 0], [' \n', 1], ['\r\n', 1], [' \n', 1], ['\r', 1], ['2', 1]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('control layout', ['bZY!\n! cc\n', 0], [['bZY!\n', 0], ['! cc\n', 0]]), ('control layout', ['\n\r,YX12Y.\r\n\n', 1], [['\n', 1], ['\r', 1], [',YX12Y.\r\n', 1], ['\n', 1]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), 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
CRLF is one separator[['ab\r\n', 0], ['XY', 1]][['ab\r\n', 0], ['XY', 1]]Passed
regression: per-paragraph first strong[['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]][['bX12\n', 0], ['YX\r\n', 1], ['2\u2029', 1], ['b\n', 0], ['Xa', 1]]Passed
regression: per-paragraph first strong[['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]][['XX\r\n', 1], ['c!,,1\n', 0], ['.1,Y', 1]]Passed
regression: per-paragraph first strong[['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]][['\n', 0], ['cZ2.\n', 0], ['a..X!\n', 0], ['!Z,.', 1]]Passed
separator only paragraph[['a\n', 0], ['\n', 1], ['Z', 1]][['a\n', 0], ['\n', 1], ['Z', 1]]Passed
digits then letter[['12 X\n', 1]][['12 X\n', 1]]Passed
control layout[['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]][['cZZ2\n', 0], ['1\u2029', 0], ['!', 0]]Passed
control layout[['2\n', 0], [',,.1!', 0]][['2\n', 0], [',,.1!', 0]]Passed

SHA-256 / 1461836bceab72d0e903ad8444ae8cc89204958314958a231a8b7b65e811350c

Verification & scope

A deterministic toy bidi model over stipulated class labels and integer levels; it is inspired by, but does not claim conformance to, any published algorithm. 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:49:57.371382+00:00.

Case digest / 41fbe3b8edcf9d22f39dfb9d6478d983a0a045c92d2d5f0a3f34b24dbb1ce724