FAILURE MAP
← Case archive

FA-80571 / Bidirectional text layout / Open access

Mirrored glyph rendering: reversal grouping key · case 01

Higher-level runs nested inside a reversal are left in place.

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

ROOT CAUSE

Runs are grouped by level equality rather than level >= current.

VERIFIED REPAIR

Group characters at the current level or higher.

Unsuccessful approach: Grouping strictly higher levels skips the current level.

Case contract

Input [text, resolved levels]. Characters at odd levels with a mirror pair ( ) [ ] { } < > « » are replaced by their mirror, decided per logical character; then runs are reversed from the highest level to the lowest odd level. Return the visual string.

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
import itertools
N = 1
observations = []
def solve(x):
    text, levels = x
    M = {'(': ')', ')': '(', '[': ']', ']': '[', '{': '}', '}': '{', '<': '>', '>': '<', '«': '»', '»': '«'}
    n = len(text)
    glyphs = [M.get(ch, ch) if levels[i] % 2 == 1 else ch for i, ch in enumerate(text)]
    order = list(range(n))
    odd = [l for l in levels if l % 2]
    if odd:
        for lev in range(max(levels), min(odd) - 1, -1):
            runs = []
            for key, grp in itertools.groupby(order, key=lambda i: levels[i] == lev):
                g = list(grp)
                runs.extend(g[::-1] if key else g)
            order = runs
    return ''.join(glyphs[i] for i in order)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: reversal grouping key', ['{]x(x«}[<[ab', [4, 4, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4]], '<[ab]{»x)x{]'), ('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['a»>»)b«', [1, 4, 4, 1, 1, 1, 1]], '»b(«»>a'), ('partial-repair probe', ['ba', [3, 3]], 'ab'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<', [2]], '<'), ('control layout', ['by>»', [4, 4, 4, 4]], 'by>»')], [('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['}«<)<yya<[y(', [1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1]], ')y]>yay>(>»{'), ('regression: reversal grouping key', ['«»«[yx{', [1, 1, 1, 2, 2, 2, 2]], '[yx{»«»'), ('regression: reversal grouping key', ['(»x({}(]}»', [2, 2, 2, 2, 2, 2, 2, 2, 1, 1]], '«{(»x({}(]'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['><', [2, 2]], '><'), ('control layout', ['xx}yb[}x>', [2, 2, 2, 2, 2, 2, 2, 4, 4]], 'xx}yb[}x>')], [('regression: reversal grouping key', ['abx«>x)x{x', [2, 2, 2, 2, 2, 1, 1, 2, 1, 1]], 'x}x(xabx«>'), ('regression: reversal grouping key', ['»«a<b(«)>', [3, 3, 4, 4, 2, 2, 2, 2, 1]], '<a<»«b(«)'), ('partial-repair probe', [']){b', [3, 3, 3, 3]], 'b}(['), ('partial-repair probe', ['{«x[<b', [1, 1, 1, 0, 0, 0]], 'x»}[<b'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<<', [3, 3]], '>>'), ('control layout', ['a', [2]], 'a')], [('regression: reversal grouping key', ['>«>>([[»[', [1, 1, 1, 1, 2, 2, 2, 4, 2]], '([[»[<<»<'), ('regression: reversal grouping key', ['«b[a)}', [4, 4, 4, 1, 1, 4]], '}(a«b['), ('regression: reversal grouping key', [')by{}[][', [1, 1, 1, 1, 2, 2, 2, 2]], '}[][}yb('), ('partial-repair probe', ['»))<)[«', [0, 0, 1, 1, 1, 1, 1]], '»)»](>('), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['y', [0]], 'y'), ('control layout', ['x[]', [2, 2, 1]], '[x[')], [('regression: reversal grouping key', ['by)bb}»)[', [4, 4, 3, 2, 2, 2, 2, 1, 1]], ']((bybb}»'), ('regression: reversal grouping key', ['ax{]b>b)', [0, 0, 0, 0, 0, 3, 3, 1]], 'ax{]b(b<'), ('partial-repair probe', [')]y))»>', [0, 0, 0, 0, 1, 1, 1]], ')]y)<«('), ('partial-repair probe', ['<)«>>»»)»', [3, 3, 3, 3, 0, 1, 1, 1, 1]], '<»(>>«(««'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['yxb][<<[<', [0, 0, 0, 0, 0, 2, 2, 0, 0]], 'yxb][<<[<'), ('control layout', ['<<', [3, 3]], '>>')]]
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
regression: reversal grouping key]{]{»x)xba[<<[ab]{»x)x{]Failed
regression: reversal grouping key{x<>(xb{>><x{xb{(>Failed
regression: reversal grouping keya>»»b(«»b(«»>aFailed
partial-repair probeababPassed
bracket in RTL run(b)a(b)aPassed
bracket at level two(x)(x)Passed
control layout<<Passed
control layoutby>»by>»Passed

SHA-256 / 729bc32ae753d3118ef35e247884e5d72e7bc30617e163cfec2269241c31859b

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(x):
    text, levels = x
    M = {'(': ')', ')': '(', '[': ']', ']': '[', '{': '}', '}': '{', '<': '>', '>': '<', '«': '»', '»': '«'}
    n = len(text)
    glyphs = [M.get(ch, ch) if levels[i] % 2 == 1 else ch for i, ch in enumerate(text)]
    order = list(range(n))
    odd = [l for l in levels if l % 2]
    if odd:
        for lev in range(max(levels), min(odd) - 1, -1):
            runs = []
            for key, grp in itertools.groupby(order, key=lambda i: levels[i] > lev):
                g = list(grp)
                runs.extend(g[::-1] if key else g)
            order = runs
    return ''.join(glyphs[i] for i in order)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: reversal grouping key', ['{]x(x«}[<[ab', [4, 4, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4]], '<[ab]{»x)x{]'), ('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['a»>»)b«', [1, 4, 4, 1, 1, 1, 1]], '»b(«»>a'), ('partial-repair probe', ['ba', [3, 3]], 'ab'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<', [2]], '<'), ('control layout', ['by>»', [4, 4, 4, 4]], 'by>»')], [('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['}«<)<yya<[y(', [1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1]], ')y]>yay>(>»{'), ('regression: reversal grouping key', ['«»«[yx{', [1, 1, 1, 2, 2, 2, 2]], '[yx{»«»'), ('regression: reversal grouping key', ['(»x({}(]}»', [2, 2, 2, 2, 2, 2, 2, 2, 1, 1]], '«{(»x({}(]'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['><', [2, 2]], '><'), ('control layout', ['xx}yb[}x>', [2, 2, 2, 2, 2, 2, 2, 4, 4]], 'xx}yb[}x>')], [('regression: reversal grouping key', ['abx«>x)x{x', [2, 2, 2, 2, 2, 1, 1, 2, 1, 1]], 'x}x(xabx«>'), ('regression: reversal grouping key', ['»«a<b(«)>', [3, 3, 4, 4, 2, 2, 2, 2, 1]], '<a<»«b(«)'), ('partial-repair probe', [']){b', [3, 3, 3, 3]], 'b}(['), ('partial-repair probe', ['{«x[<b', [1, 1, 1, 0, 0, 0]], 'x»}[<b'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<<', [3, 3]], '>>'), ('control layout', ['a', [2]], 'a')], [('regression: reversal grouping key', ['>«>>([[»[', [1, 1, 1, 1, 2, 2, 2, 4, 2]], '([[»[<<»<'), ('regression: reversal grouping key', ['«b[a)}', [4, 4, 4, 1, 1, 4]], '}(a«b['), ('regression: reversal grouping key', [')by{}[][', [1, 1, 1, 1, 2, 2, 2, 2]], '}[][}yb('), ('partial-repair probe', ['»))<)[«', [0, 0, 1, 1, 1, 1, 1]], '»)»](>('), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['y', [0]], 'y'), ('control layout', ['x[]', [2, 2, 1]], '[x[')], [('regression: reversal grouping key', ['by)bb}»)[', [4, 4, 3, 2, 2, 2, 2, 1, 1]], ']((bybb}»'), ('regression: reversal grouping key', ['ax{]b>b)', [0, 0, 0, 0, 0, 3, 3, 1]], 'ax{]b(b<'), ('partial-repair probe', [')]y))»>', [0, 0, 0, 0, 1, 1, 1]], ')]y)<«('), ('partial-repair probe', ['<)«>>»»)»', [3, 3, 3, 3, 0, 1, 1, 1, 1]], '<»(>>«(««'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['yxb][<<[<', [0, 0, 0, 0, 0, 2, 2, 0, 0]], 'yxb][<<[<'), ('control layout', ['<<', [3, 3]], '>>')]]
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
regression: reversal grouping key]{x)x»{]ba[<<[ab]{»x)x{]Failed
regression: reversal grouping key>({bx{x<>><x{xb{(>Failed
regression: reversal grouping keya>»«(b»»b(«»>aFailed
partial-repair probebaabFailed
bracket in RTL runa)b((b)aFailed
bracket at level two(x)(x)Passed
control layout<<Passed
control layoutby>»by>»Passed

SHA-256 / e1dbea1583fb24654727d45bce6b3b76746d1f531a38221d29d7149fba80bbc1

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(x):
    text, levels = x
    M = {'(': ')', ')': '(', '[': ']', ']': '[', '{': '}', '}': '{', '<': '>', '>': '<', '«': '»', '»': '«'}
    n = len(text)
    glyphs = [M.get(ch, ch) if levels[i] % 2 == 1 else ch for i, ch in enumerate(text)]
    order = list(range(n))
    odd = [l for l in levels if l % 2]
    if odd:
        for lev in range(max(levels), min(odd) - 1, -1):
            runs = []
            for key, grp in itertools.groupby(order, key=lambda i: levels[i] >= lev):
                g = list(grp)
                runs.extend(g[::-1] if key else g)
            order = runs
    return ''.join(glyphs[i] for i in order)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: reversal grouping key', ['{]x(x«}[<[ab', [4, 4, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4]], '<[ab]{»x)x{]'), ('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['a»>»)b«', [1, 4, 4, 1, 1, 1, 1]], '»b(«»>a'), ('partial-repair probe', ['ba', [3, 3]], 'ab'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<', [2]], '<'), ('control layout', ['by>»', [4, 4, 4, 4]], 'by>»')], [('regression: reversal grouping key', ['<x{(>}bx<', [2, 2, 2, 4, 4, 3, 3, 3, 1]], '><x{xb{(>'), ('regression: reversal grouping key', ['}«<)<yya<[y(', [1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1]], ')y]>yay>(>»{'), ('regression: reversal grouping key', ['«»«[yx{', [1, 1, 1, 2, 2, 2, 2]], '[yx{»«»'), ('regression: reversal grouping key', ['(»x({}(]}»', [2, 2, 2, 2, 2, 2, 2, 2, 1, 1]], '«{(»x({}(]'), ('bracket in RTL run', ['a(b)', [1, 1, 1, 1]], '(b)a'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['><', [2, 2]], '><'), ('control layout', ['xx}yb[}x>', [2, 2, 2, 2, 2, 2, 2, 4, 4]], 'xx}yb[}x>')], [('regression: reversal grouping key', ['abx«>x)x{x', [2, 2, 2, 2, 2, 1, 1, 2, 1, 1]], 'x}x(xabx«>'), ('regression: reversal grouping key', ['»«a<b(«)>', [3, 3, 4, 4, 2, 2, 2, 2, 1]], '<a<»«b(«)'), ('partial-repair probe', [']){b', [3, 3, 3, 3]], 'b}(['), ('partial-repair probe', ['{«x[<b', [1, 1, 1, 0, 0, 0]], 'x»}[<b'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['<<', [3, 3]], '>>'), ('control layout', ['a', [2]], 'a')], [('regression: reversal grouping key', ['>«>>([[»[', [1, 1, 1, 1, 2, 2, 2, 4, 2]], '([[»[<<»<'), ('regression: reversal grouping key', ['«b[a)}', [4, 4, 4, 1, 1, 4]], '}(a«b['), ('regression: reversal grouping key', [')by{}[][', [1, 1, 1, 1, 2, 2, 2, 2]], '}[][}yb('), ('partial-repair probe', ['»))<)[«', [0, 0, 1, 1, 1, 1, 1]], '»)»](>('), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['y', [0]], 'y'), ('control layout', ['x[]', [2, 2, 1]], '[x[')], [('regression: reversal grouping key', ['by)bb}»)[', [4, 4, 3, 2, 2, 2, 2, 1, 1]], ']((bybb}»'), ('regression: reversal grouping key', ['ax{]b>b)', [0, 0, 0, 0, 0, 3, 3, 1]], 'ax{]b(b<'), ('partial-repair probe', [')]y))»>', [0, 0, 0, 0, 1, 1, 1]], ')]y)<«('), ('partial-repair probe', ['<)«>>»»)»', [3, 3, 3, 3, 0, 1, 1, 1, 1]], '<»(>>«(««'), ('guillemets RTL', ['«ab»', [1, 1, 1, 1]], '«ba»'), ('bracket at level two', ['(x)', [2, 2, 2]], '(x)'), ('control layout', ['yxb][<<[<', [0, 0, 0, 0, 0, 2, 2, 0, 0]], 'yxb][<<[<'), ('control layout', ['<<', [3, 3]], '>>')]]
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
regression: reversal grouping key<[ab]{»x)x{]<[ab]{»x)x{]Passed
regression: reversal grouping key><x{xb{(>><x{xb{(>Passed
regression: reversal grouping key»b(«»>a»b(«»>aPassed
partial-repair probeababPassed
bracket in RTL run(b)a(b)aPassed
bracket at level two(x)(x)Passed
control layout<<Passed
control layoutby>»by>»Passed

SHA-256 / b5550654629edfa1577c4cc0f49ed5ea24cb5cce21a6c12994725484fbe00fde

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

Case digest / a000b481ea010f3d708d83f87779b56b84a3910b272f97c911aede9601bca828