FA-75691 / Text diff and three-way merge / Open access
Hunk overlap check: adjacent hunks are treated as independent · case 01
Changes to neighbouring lines are auto-merged although the policy treats them as conflicting.
ROOT CAUSE
The overlap test omits the one-line adjacency allowance.
VERIFIED REPAIR
Two spans conflict when each starts no later than one line after the other ends.
Unsuccessful approach: Allowing adjacency on one side only makes the result depend on which patch is first.
Case contract
Two patches against the same base list hunks as [old_start, old_len]. A hunk with length > 0 covers lines start..start+len-1; a zero-length hunk is an insertion after line start and sits at start+0.5. Hunks conflict when their spans overlap or are adjacent (within one line). Return sorted [i, j] index pairs of conflicting hunks from the first and second patch.
Why this case matters
Cherry-picks and concurrent patch application refuse to auto-merge changes that touch or abut the same lines.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(p1, p2):
def span(h):
s, ln = h
if ln == 0:
return (s + 0.5, s + 0.5)
return (s, s + ln - 1)
out = []
for i, h1 in enumerate(p1):
a_lo, a_hi = span(h1)
for j, h2 in enumerate(p2):
b_lo, b_hi = span(h2)
if a_lo <= b_hi and b_lo <= a_hi:
out.append([i, j])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [8, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 1]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
2: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [9, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 2]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
3: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [10, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 3]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
4: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [11, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 4]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
5: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [12, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 5]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
}[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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| overlapping ranges | [[0, 0]] | [[0, 0]] | Passed |
| adjacent ranges conflict | [] | [[0, 0]] | Failed |
| one line apart is clean | [] | [] | Passed |
| insertions at the same point | [[0, 0]] | [[0, 0]] | Passed |
| insertion next to a range | [] | [[0, 0]] | Failed |
| insertion inside a range | [[0, 0]] | [[0, 0]] | Passed |
| insertion two lines above a range | [] | [] | Passed |
| single-line ranges touching | [] | [[0, 0]] | Failed |
| far apart | [] | [] | Passed |
| insertion one line below a range end | [] | [] | Passed |
SHA-256 / 0b9508f6ad72318768cb1706ee188545e93659344af6c27e7910a05976d0995f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(p1, p2):
def span(h):
s, ln = h
if ln == 0:
return (s + 0.5, s + 0.5)
return (s, s + ln - 1)
out = []
for i, h1 in enumerate(p1):
a_lo, a_hi = span(h1)
for j, h2 in enumerate(p2):
b_lo, b_hi = span(h2)
if a_lo <= b_hi + 1 and b_lo <= a_hi:
out.append([i, j])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [8, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 1]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
2: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [9, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 2]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
3: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [10, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 3]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
4: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [11, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 4]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
5: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [12, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 5]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
}[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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| overlapping ranges | [[0, 0]] | [[0, 0]] | Passed |
| adjacent ranges conflict | [] | [[0, 0]] | Failed |
| one line apart is clean | [] | [] | Passed |
| insertions at the same point | [[0, 0]] | [[0, 0]] | Passed |
| insertion next to a range | [] | [[0, 0]] | Failed |
| insertion inside a range | [[0, 0]] | [[0, 0]] | Passed |
| insertion two lines above a range | [] | [] | Passed |
| single-line ranges touching | [] | [[0, 0]] | Failed |
| far apart | [] | [] | Passed |
| insertion one line below a range end | [] | [] | Passed |
SHA-256 / 6497ba65c477b0de5b388a465387d858b8fbe8ca9dda04b872ffcb8856abe69d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(p1, p2):
def span(h):
s, ln = h
if ln == 0:
return (s + 0.5, s + 0.5)
return (s, s + ln - 1)
out = []
for i, h1 in enumerate(p1):
a_lo, a_hi = span(h1)
for j, h2 in enumerate(p2):
b_lo, b_hi = span(h2)
if a_lo <= b_hi + 1 and b_lo <= a_hi + 1:
out.append([i, j])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [8, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 1]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
2: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [9, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 2]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
3: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [10, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 3]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
4: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [11, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 4]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
5: [('overlapping ranges', [[[3, 4]], [[5, 2]]], [[0, 0]]), ('adjacent ranges conflict', [[[1, 3]], [[4, 2]]], [[0, 0]]), ('one line apart is clean', [[[1, 3]], [[5, 2]]], []), ('insertions at the same point', [[[5, 0]], [[5, 0]]], [[0, 0]]), ('insertion next to a range', [[[5, 0]], [[6, 3], [12, 1]]], [[0, 0]]), ('insertion inside a range', [[[2, 5]], [[4, 0]]], [[0, 0]]), ('insertion two lines above a range', [[[4, 0]], [[6, 2]]], []), ('single-line ranges touching', [[[10, 1], [20, 1]], [[11, 1], [30, 5]]], [[0, 0]]), ('far apart', [[[1, 1]], [[50, 0]]], []), ('insertion one line below a range end', [[[5, 0]], [[2, 3]]], [])],
}[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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| overlapping ranges | [[0, 0]] | [[0, 0]] | Passed |
| adjacent ranges conflict | [[0, 0]] | [[0, 0]] | Passed |
| one line apart is clean | [] | [] | Passed |
| insertions at the same point | [[0, 0]] | [[0, 0]] | Passed |
| insertion next to a range | [[0, 0]] | [[0, 0]] | Passed |
| insertion inside a range | [[0, 0]] | [[0, 0]] | Passed |
| insertion two lines above a range | [] | [] | Passed |
| single-line ranges touching | [[0, 0]] | [[0, 0]] | Passed |
| far apart | [] | [] | Passed |
| insertion one line below a range end | [] | [] | Passed |
SHA-256 / 6bdf6061eb7d8c82fd5a83e1a1586f9de324081848b4417a3faa395d45b5aa23
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:09.137842+00:00.
Case digest / fcb0608a7f73b69a1db104301646f187f54584e037c45093ea73b8a60ac7e13f