FAILURE MAP
← Case archive

FA-75816 / Text diff and three-way merge / Open access

Conflict resolution reuse: labelled opening markers are not recognized · case 01

Conflicts produced with branch labels pass through untouched.

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

ROOT CAUSE

The opening marker must be exactly seven "<" characters with no label.

VERIFIED REPAIR

Accept the opening marker with or without a label.

Unsuccessful approach: Requiring a space after the marker rejects unlabelled conflicts.

Case contract

Scan conflict blocks ("<<<<<<<" optionally followed by a label, optional "|||||||" base section, "=======", ">>>>>>>" optionally labelled). A block matches a recorded [side1, side2, resolution] when its two sides equal the recorded sides in either order; base lines are ignored. Matched blocks are replaced by the resolution; unmatched blocks are re-emitted as bare "<<<<<<<", ours, "=======", theirs, ">>>>>>>" and counted. Return lines and the unresolved count.

Why this case matters

Reusing recorded conflict resolutions saves repeating the same manual merge during rebases.

1 / The failure

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

N = 1
observations = []
def solve(lines, recorded):
    out = []
    state = None
    o, t = [], []
    unresolved = 0
    for ln in lines:
        if state is None:
            if ln == '<<<<<<<':
                state = 'o'
                o, t = [], []
            else:
                out.append(ln)
        elif state == 'o' and ln.startswith('|||||||'):
            state = 'b'
        elif state in ('o', 'b') and ln == '=======':
            state = 't'
        elif state == 't' and ln.startswith('>>>>>>>'):
            key = sorted([o, t])
            match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
            if match is not None:
                out.extend(match)
            else:
                unresolved += 1
                out.extend(['<<<<<<<'] + o + ['======='] + t + ['>>>>>>>'])
            state = None
        elif state == 'o':
            o.append(ln)
        elif state == 't':
            t.append(ln)
    return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
    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
recorded resolution reused{'lines': ['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], 'unresolved': 0}{'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}Failed
sides swapped still match{'lines': ['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Failed
base section does not affect the fingerprint{'lines': ['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Failed
unknown conflict stays unresolved{'lines': ['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], 'unresolved': 0}{'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}Failed
unlabelled markers{'lines': ['abc'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Passed
two conflicts, one known{'lines': ['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], 'unresolved': 0}{'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}Failed
labelled base marker{'lines': ['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Failed

SHA-256 / f379624386f727fef43a637ce4cc6c2c1b79d0c76df71b9348123955091f399d

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(lines, recorded):
    out = []
    state = None
    o, t = [], []
    unresolved = 0
    for ln in lines:
        if state is None:
            if ln.startswith('<<<<<<< '):
                state = 'o'
                o, t = [], []
            else:
                out.append(ln)
        elif state == 'o' and ln.startswith('|||||||'):
            state = 'b'
        elif state in ('o', 'b') and ln == '=======':
            state = 't'
        elif state == 't' and ln.startswith('>>>>>>>'):
            key = sorted([o, t])
            match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
            if match is not None:
                out.extend(match)
            else:
                unresolved += 1
                out.extend(['<<<<<<<'] + o + ['======='] + t + ['>>>>>>>'])
            state = None
        elif state == 'o':
            o.append(ln)
        elif state == 't':
            t.append(ln)
    return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
    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
recorded resolution reused{'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}{'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}Passed
sides swapped still match{'lines': ['x = 3'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Passed
base section does not affect the fingerprint{'lines': ['abc'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Passed
unknown conflict stays unresolved{'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}{'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}Passed
unlabelled markers{'lines': ['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Failed
two conflicts, one known{'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}{'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}Passed
labelled base marker{'lines': ['x = 3'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Passed

SHA-256 / 6cfaad5e72ff49a87aafc681eb47aa67ebd454b78370385de2959c452702b96c

3 / The verified repair

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

N = 1
observations = []
def solve(lines, recorded):
    out = []
    state = None
    o, t = [], []
    unresolved = 0
    for ln in lines:
        if state is None:
            if ln.startswith('<<<<<<<'):
                state = 'o'
                o, t = [], []
            else:
                out.append(ln)
        elif state == 'o' and ln.startswith('|||||||'):
            state = 'b'
        elif state in ('o', 'b') and ln == '=======':
            state = 't'
        elif state == 't' and ln.startswith('>>>>>>>'):
            key = sorted([o, t])
            match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
            if match is not None:
                out.extend(match)
            else:
                unresolved += 1
                out.extend(['<<<<<<<'] + o + ['======='] + t + ['>>>>>>>'])
            state = None
        elif state == 'o':
            o.append(ln)
        elif state == 't':
            t.append(ln)
    return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
    1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
    5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
    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
recorded resolution reused{'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}{'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}Passed
sides swapped still match{'lines': ['x = 3'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Passed
base section does not affect the fingerprint{'lines': ['abc'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Passed
unknown conflict stays unresolved{'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}{'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}Passed
unlabelled markers{'lines': ['abc'], 'unresolved': 0}{'lines': ['abc'], 'unresolved': 0}Passed
two conflicts, one known{'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}{'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}Passed
labelled base marker{'lines': ['x = 3'], 'unresolved': 0}{'lines': ['x = 3'], 'unresolved': 0}Passed

SHA-256 / 06206ed748ff46cbd75b15c89385569ab4ecfe0d9baba751ff01bfa02a567964

Verification & scope

A deterministic, bounded teaching model of one diff, patch or merge rule with stipulated conventions; it is not a production diff or version-control implementation and makes no claim of conformance to any specific tool. 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:10.315975+00:00.

Case digest / 8037b5adb4d20e9dbe04ce501575617a64c9be84092815c20e1ff3774f155f9a