FA-75836 / Text diff and three-way merge / Open access
Diffstat path truncation: the directory separator is dropped after the ellipsis · case 01
Truncated paths read "...file.py" instead of ".../file.py", hiding that a directory was cut.
ROOT CAUSE
The cut starts after the slash instead of at it.
VERIFIED REPAIR
Cut the tail at the first slash and keep the slash.
Unsuccessful approach: Cutting at the last slash discards more of the path than necessary.
Case contract
A path longer than width is shown as "..." plus its last width-3 characters, further shortened to start at the first "/" inside that tail when there is one (keeping the slash). Paths not longer than width are unchanged.
Why this case matters
Narrow terminals truncate long paths in diffstat output; the rule keeps the most informative part of the path.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(names, width):
res = []
for name in names:
if len(name) <= width:
res.append(name)
continue
keep = width - 3
tail = name[len(name) - keep:] if keep > 0 else ''
slash = tail.find('/')
if slash >= 0:
tail = tail[slash + 1:]
res.append('...' + tail)
return res
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
2: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
3: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
4: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
5: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
}[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 |
|---|---|---|---|
| short name unchanged | ['src/a.c'] | ['src/a.c'] | Passed |
| name exactly the width | ['abcdefghij'] | ['abcdefghij'] | Passed |
| long name cut at a directory boundary | ['...file_name.py'] | ['.../file_name.py'] | Failed |
| no slash in the kept tail | ['...ename.txt'] | ['...ename.txt'] | Passed |
| several names | ['...g/h.txt', 'x.c', '...yyyyyyyyy'] | ['.../g/h.txt', 'x.c', '...yyyyyyyyy'] | Failed |
| tail starts exactly at a slash | ['...cc'] | ['.../cc'] | Failed |
| width just above the name | ['p/q/r.txt'] | ['p/q/r.txt'] | Passed |
SHA-256 / c85a20cdb26a0bd4056d8e57a7fca6bd67001217550461b2aa13bdb3a1ed6d37
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(names, width):
res = []
for name in names:
if len(name) <= width:
res.append(name)
continue
keep = width - 3
tail = name[len(name) - keep:] if keep > 0 else ''
slash = tail.rfind('/')
if slash >= 0:
tail = tail[slash:]
res.append('...' + tail)
return res
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
2: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
3: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
4: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
5: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
}[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 |
|---|---|---|---|
| short name unchanged | ['src/a.c'] | ['src/a.c'] | Passed |
| name exactly the width | ['abcdefghij'] | ['abcdefghij'] | Passed |
| long name cut at a directory boundary | ['.../file_name.py'] | ['.../file_name.py'] | Passed |
| no slash in the kept tail | ['...ename.txt'] | ['...ename.txt'] | Passed |
| several names | ['.../h.txt', 'x.c', '...yyyyyyyyy'] | ['.../g/h.txt', 'x.c', '...yyyyyyyyy'] | Failed |
| tail starts exactly at a slash | ['.../cc'] | ['.../cc'] | Passed |
| width just above the name | ['p/q/r.txt'] | ['p/q/r.txt'] | Passed |
SHA-256 / 358429a27b3feaa1ce5f10fc6e3f20d953e5674ec8c5bfb6969f6969e349797c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(names, width):
res = []
for name in names:
if len(name) <= width:
res.append(name)
continue
keep = width - 3
tail = name[len(name) - keep:] if keep > 0 else ''
slash = tail.find('/')
if slash >= 0:
tail = tail[slash:]
res.append('...' + tail)
return res
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
2: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
3: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
4: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
5: [('short name unchanged', [['src/a.c'], 20], ['src/a.c']), ('name exactly the width', [['abcdefghij'], 10], ['abcdefghij']), ('long name cut at a directory boundary', [['src/module/deep/file_name.py'], 18], ['.../file_name.py']), ('no slash in the kept tail', [['averyveryverylongfilename.txt'], 12], ['...ename.txt']), ('several names', [['a/b/c/d/e/f/g/h.txt', 'x.c', 'dir/yyyyyyyyyyyyyyy'], 12], ['.../g/h.txt', 'x.c', '...yyyyyyyyy']), ('tail starts exactly at a slash', [['aaaa/bbbb/cc'], 8], ['.../cc']), ('width just above the name', [['p/q/r.txt'], 10], ['p/q/r.txt'])],
}[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 |
|---|---|---|---|
| short name unchanged | ['src/a.c'] | ['src/a.c'] | Passed |
| name exactly the width | ['abcdefghij'] | ['abcdefghij'] | Passed |
| long name cut at a directory boundary | ['.../file_name.py'] | ['.../file_name.py'] | Passed |
| no slash in the kept tail | ['...ename.txt'] | ['...ename.txt'] | Passed |
| several names | ['.../g/h.txt', 'x.c', '...yyyyyyyyy'] | ['.../g/h.txt', 'x.c', '...yyyyyyyyy'] | Passed |
| tail starts exactly at a slash | ['.../cc'] | ['.../cc'] | Passed |
| width just above the name | ['p/q/r.txt'] | ['p/q/r.txt'] | Passed |
SHA-256 / ff162986d34f41572b7f9289a68e9da9931d4ac6dd15db61df73d5a9e83f9967
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.460177+00:00.
Case digest / 89793ada86fafa99d3394bd7bf53b3ba1433ed5b9b941977251f6b73713451a9