FAILURE MAP
← Case archive

FA-80831 / Bidirectional text layout / Open access

Paragraph separation and direction: default level per paragraph · case 01

A paragraph with no letters inherits the previous paragraph direction.

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

ROOT CAUSE

The level variable is initialised once for all paragraphs.

VERIFIED REPAIR

Reset to the default level for every paragraph.

Unsuccessful approach: Resetting to 0 ignores the caller default.

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 = []
    level = default
    for p in paras:
        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 = [[('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', ['22 \n\nY!!ab1\u2029Z\n\n', 0], [['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]), ('regression: default level per paragraph', ['2 X\u2029Yb\ra\n\n', 1], [['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]), ('regression: default level per paragraph', ['bXY.b\n ', 1], [['bXY.b\n', 0], [' ', 1]]), ('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\n !Z', 0], [['b\n', 0], [' !Z', 1]]), ('control layout', ['.ZY,', 1], [['.ZY,', 1]])], [('regression: default level per paragraph', ['.a,2cbY\n2', 1], [['.a,2cbY\n', 0], ['2', 1]]), ('regression: default level per paragraph', ['1 a!.\u2029\nc1X 1YZa1', 1], [['1 a!.\u2029', 0], ['\n', 1], ['c1X 1YZa1', 0]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', [',a\r\n\r\nab.\r,a\rYb,', 1], [[',a\r\n', 0], ['\r\n', 1], ['ab.\r', 0], [',a\r', 0], ['Yb,', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('control layout', ['.\n.bZ\n1Z ', 0], [['.\n', 0], ['.bZ\n', 0], ['1Z ', 1]]), ('control layout', ['Zb!b\n', 0], [['Zb!b\n', 1]])], [('regression: default level per paragraph', ['!!c,XaZ c2\u2029,\r', 1], [['!!c,XaZ c2\u2029', 0], [',\r', 1]]), ('regression: default level per paragraph', ['a2bY\r\n\u20291', 1], [['a2bY\r\n', 0], ['\u2029', 1], ['1', 1]]), ('partial-repair probe', ['X\n\n\nZa\r.\u2029X\nZXbZ', 1], [['X\n', 1], ['\n', 1], ['\n', 1], ['Za\r', 1], ['.\u2029', 1], ['X\n', 1], ['ZXbZ', 1]]), ('partial-repair probe', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 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', ['1acX1X!, \r\nXY', 1], [['1acX1X!, \r\n', 0], ['XY', 1]]), ('control layout', ['bb\n.Z. ', 1], [['bb\n', 0], ['.Z. ', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('partial-repair probe', [' \n.X,!,2,\r\n2\n.', 1], [[' \n', 1], ['.X,!,2,\r\n', 1], ['2\n', 1], ['.', 1]]), ('regression: default level per paragraph', ['aX\n,1c\n.\ncX!a', 1], [['aX\n', 0], [',1c\n', 0], ['.\n', 1], ['cX!a', 0]]), ('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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['ZZ,a', 0], [['ZZ,a', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z!Y\u2029X\n,\nc\n! b!', 0], [['Z!Y\u2029', 1], ['X\n', 1], [',\n', 0], ['c\n', 0], ['! b!', 0]]), ('partial-repair probe', ['\r\n.! 12\u2029\n', 1], [['\r\n', 1], ['.! 12\u2029', 1], ['\n', 1]]), ('partial-repair probe', ['!\r\n \nXX1.b', 1], [['!\r\n', 1], [' \n', 1], ['XX1.b', 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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['1c\nbb\r\nbZY\r\na\nc,XY', 0], [['1c\n', 0], ['bb\r\n', 0], ['bZY\r\n', 0], ['a\n', 0], ['c,XY', 0]])]]
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
separator only paragraph[['a\n', 0], ['\n', 0], ['Z', 1]][['a\n', 0], ['\n', 1], ['Z', 1]]Failed
regression: default level per paragraph[['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 1]][['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]Failed
regression: default level per paragraph[['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 0]][['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]Failed
regression: default level per paragraph[['bXY.b\n', 0], [' ', 0]][['bXY.b\n', 0], [' ', 1]]Failed
CRLF is one separator[['ab\r\n', 0], ['XY', 1]][['ab\r\n', 0], ['XY', 1]]Passed
digits then letter[['12 X\n', 1]][['12 X\n', 1]]Passed
control layout[['b\n', 0], [' !Z', 1]][['b\n', 0], [' !Z', 1]]Passed
control layout[['.ZY,', 1]][['.ZY,', 1]]Passed

SHA-256 / abdd4dce781f99c155de066957ca38cd278246b8a4d7c0bc02cd856a8129ec76

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 = 0
        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 = [[('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', ['22 \n\nY!!ab1\u2029Z\n\n', 0], [['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]), ('regression: default level per paragraph', ['2 X\u2029Yb\ra\n\n', 1], [['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]), ('regression: default level per paragraph', ['bXY.b\n ', 1], [['bXY.b\n', 0], [' ', 1]]), ('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\n !Z', 0], [['b\n', 0], [' !Z', 1]]), ('control layout', ['.ZY,', 1], [['.ZY,', 1]])], [('regression: default level per paragraph', ['.a,2cbY\n2', 1], [['.a,2cbY\n', 0], ['2', 1]]), ('regression: default level per paragraph', ['1 a!.\u2029\nc1X 1YZa1', 1], [['1 a!.\u2029', 0], ['\n', 1], ['c1X 1YZa1', 0]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', [',a\r\n\r\nab.\r,a\rYb,', 1], [[',a\r\n', 0], ['\r\n', 1], ['ab.\r', 0], [',a\r', 0], ['Yb,', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('control layout', ['.\n.bZ\n1Z ', 0], [['.\n', 0], ['.bZ\n', 0], ['1Z ', 1]]), ('control layout', ['Zb!b\n', 0], [['Zb!b\n', 1]])], [('regression: default level per paragraph', ['!!c,XaZ c2\u2029,\r', 1], [['!!c,XaZ c2\u2029', 0], [',\r', 1]]), ('regression: default level per paragraph', ['a2bY\r\n\u20291', 1], [['a2bY\r\n', 0], ['\u2029', 1], ['1', 1]]), ('partial-repair probe', ['X\n\n\nZa\r.\u2029X\nZXbZ', 1], [['X\n', 1], ['\n', 1], ['\n', 1], ['Za\r', 1], ['.\u2029', 1], ['X\n', 1], ['ZXbZ', 1]]), ('partial-repair probe', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 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', ['1acX1X!, \r\nXY', 1], [['1acX1X!, \r\n', 0], ['XY', 1]]), ('control layout', ['bb\n.Z. ', 1], [['bb\n', 0], ['.Z. ', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('partial-repair probe', [' \n.X,!,2,\r\n2\n.', 1], [[' \n', 1], ['.X,!,2,\r\n', 1], ['2\n', 1], ['.', 1]]), ('regression: default level per paragraph', ['aX\n,1c\n.\ncX!a', 1], [['aX\n', 0], [',1c\n', 0], ['.\n', 1], ['cX!a', 0]]), ('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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['ZZ,a', 0], [['ZZ,a', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z!Y\u2029X\n,\nc\n! b!', 0], [['Z!Y\u2029', 1], ['X\n', 1], [',\n', 0], ['c\n', 0], ['! b!', 0]]), ('partial-repair probe', ['\r\n.! 12\u2029\n', 1], [['\r\n', 1], ['.! 12\u2029', 1], ['\n', 1]]), ('partial-repair probe', ['!\r\n \nXX1.b', 1], [['!\r\n', 1], [' \n', 1], ['XX1.b', 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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['1c\nbb\r\nbZY\r\na\nc,XY', 0], [['1c\n', 0], ['bb\r\n', 0], ['bZY\r\n', 0], ['a\n', 0], ['c,XY', 0]])]]
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
separator only paragraph[['a\n', 0], ['\n', 0], ['Z', 1]][['a\n', 0], ['\n', 1], ['Z', 1]]Failed
regression: default level per paragraph[['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]][['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]Passed
regression: default level per paragraph[['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 0]][['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]Failed
regression: default level per paragraph[['bXY.b\n', 0], [' ', 0]][['bXY.b\n', 0], [' ', 1]]Failed
CRLF is one separator[['ab\r\n', 0], ['XY', 1]][['ab\r\n', 0], ['XY', 1]]Passed
digits then letter[['12 X\n', 1]][['12 X\n', 1]]Passed
control layout[['b\n', 0], [' !Z', 1]][['b\n', 0], [' !Z', 1]]Passed
control layout[['.ZY,', 1]][['.ZY,', 1]]Passed

SHA-256 / 4eea371a4bf149c51dfa39b64d6774d36d4826dc87927abd62bc641cdec0ef0f

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 = [[('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', ['22 \n\nY!!ab1\u2029Z\n\n', 0], [['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]), ('regression: default level per paragraph', ['2 X\u2029Yb\ra\n\n', 1], [['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]), ('regression: default level per paragraph', ['bXY.b\n ', 1], [['bXY.b\n', 0], [' ', 1]]), ('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\n !Z', 0], [['b\n', 0], [' !Z', 1]]), ('control layout', ['.ZY,', 1], [['.ZY,', 1]])], [('regression: default level per paragraph', ['.a,2cbY\n2', 1], [['.a,2cbY\n', 0], ['2', 1]]), ('regression: default level per paragraph', ['1 a!.\u2029\nc1X 1YZa1', 1], [['1 a!.\u2029', 0], ['\n', 1], ['c1X 1YZa1', 0]]), ('separator only paragraph', ['a\n\nZ', 1], [['a\n', 0], ['\n', 1], ['Z', 1]]), ('regression: default level per paragraph', [',a\r\n\r\nab.\r,a\rYb,', 1], [[',a\r\n', 0], ['\r\n', 1], ['ab.\r', 0], [',a\r', 0], ['Yb,', 1]]), ('digits then letter', ['12 X\n', 0], [['12 X\n', 1]]), ('CRLF is one separator', ['ab\r\nXY', 0], [['ab\r\n', 0], ['XY', 1]]), ('control layout', ['.\n.bZ\n1Z ', 0], [['.\n', 0], ['.bZ\n', 0], ['1Z ', 1]]), ('control layout', ['Zb!b\n', 0], [['Zb!b\n', 1]])], [('regression: default level per paragraph', ['!!c,XaZ c2\u2029,\r', 1], [['!!c,XaZ c2\u2029', 0], [',\r', 1]]), ('regression: default level per paragraph', ['a2bY\r\n\u20291', 1], [['a2bY\r\n', 0], ['\u2029', 1], ['1', 1]]), ('partial-repair probe', ['X\n\n\nZa\r.\u2029X\nZXbZ', 1], [['X\n', 1], ['\n', 1], ['\n', 1], ['Za\r', 1], ['.\u2029', 1], ['X\n', 1], ['ZXbZ', 1]]), ('partial-repair probe', ['Z.,\n\n2Y\r!b,', 1], [['Z.,\n', 1], ['\n', 1], ['2Y\r', 1], ['!b,', 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', ['1acX1X!, \r\nXY', 1], [['1acX1X!, \r\n', 0], ['XY', 1]]), ('control layout', ['bb\n.Z. ', 1], [['bb\n', 0], ['.Z. ', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z\u2029\r\n Z', 0], [['Z\u2029', 1], ['\r\n', 0], [' Z', 1]]), ('partial-repair probe', [' \n.X,!,2,\r\n2\n.', 1], [[' \n', 1], ['.X,!,2,\r\n', 1], ['2\n', 1], ['.', 1]]), ('regression: default level per paragraph', ['aX\n,1c\n.\ncX!a', 1], [['aX\n', 0], [',1c\n', 0], ['.\n', 1], ['cX!a', 0]]), ('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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['ZZ,a', 0], [['ZZ,a', 1]])], [('regression: default level per paragraph', ['Z\r\r\n\rcX!X12.!.c\u2029', 0], [['Z\r', 1], ['\r\n', 0], ['\r', 0], ['cX!X12.!.c\u2029', 0]]), ('regression: default level per paragraph', ['Z!Y\u2029X\n,\nc\n! b!', 0], [['Z!Y\u2029', 1], ['X\n', 1], [',\n', 0], ['c\n', 0], ['! b!', 0]]), ('partial-repair probe', ['\r\n.! 12\u2029\n', 1], [['\r\n', 1], ['.! 12\u2029', 1], ['\n', 1]]), ('partial-repair probe', ['!\r\n \nXX1.b', 1], [['!\r\n', 1], [' \n', 1], ['XX1.b', 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', ['Zbb\na1', 0], [['Zbb\n', 1], ['a1', 0]]), ('control layout', ['1c\nbb\r\nbZY\r\na\nc,XY', 0], [['1c\n', 0], ['bb\r\n', 0], ['bZY\r\n', 0], ['a\n', 0], ['c,XY', 0]])]]
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
separator only paragraph[['a\n', 0], ['\n', 1], ['Z', 1]][['a\n', 0], ['\n', 1], ['Z', 1]]Passed
regression: default level per paragraph[['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]][['22 \n', 0], ['\n', 0], ['Y!!ab1\u2029', 1], ['Z\n', 1], ['\n', 0]]Passed
regression: default level per paragraph[['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]][['2 X\u2029', 1], ['Yb\r', 1], ['a\n', 0], ['\n', 1]]Passed
regression: default level per paragraph[['bXY.b\n', 0], [' ', 1]][['bXY.b\n', 0], [' ', 1]]Passed
CRLF is one separator[['ab\r\n', 0], ['XY', 1]][['ab\r\n', 0], ['XY', 1]]Passed
digits then letter[['12 X\n', 1]][['12 X\n', 1]]Passed
control layout[['b\n', 0], [' !Z', 1]][['b\n', 0], [' !Z', 1]]Passed
control layout[['.ZY,', 1]][['.ZY,', 1]]Passed

SHA-256 / 8778f221863ee2a8fc11dd4bb76bdf262806e9993776e5bdfe91ab3521746eaf

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.396226+00:00.

Case digest / 1fdcbe30160c7214ce85016d0ebf4f1edf4661e5b42a1d49f02a5dc46ea05732