FA-75671 / Text diff and three-way merge / Open access
Three-way key-value merge: keys added only by their branch are dropped · case 01
New settings introduced on the other branch are missing after the merge.
ROOT CAUSE
The key universe is built from base and ours only.
VERIFIED REPAIR
Iterate over the union of keys from base, ours and theirs.
Unsuccessful approach: Using base and theirs drops keys added only on our branch.
Case contract
Merge base, ours and theirs maps key by key over the union of keys; an absent key and a key holding null are different states. If ours and theirs agree, take that state; else if ours equals base take theirs; else if theirs equals base take ours; otherwise record a conflict and keep ours. Return sorted merged [key, value] pairs and sorted conflicting keys.
Why this case matters
Structured configuration and lock files are merged per key, where deletions and null values must stay distinguishable.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(base, ours, theirs):
MISSING = object()
merged, conflicts = {}, []
for k in sorted(set(base) | set(ours)):
b = base.get(k, MISSING)
o = ours.get(k, MISSING)
t = theirs.get(k, MISSING)
if o == t:
r = o
elif o == b:
r = t
elif t == b:
r = o
else:
conflicts.append(k)
r = o
if r is not MISSING:
merged[k] = r
return {'merged': sorted([k, v] for k, v in merged.items()), 'conflicts': conflicts}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '81', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z1'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e1'}], {'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm1'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
2: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '82', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '82']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z2'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z2'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e2'}], {'merged': [['extra', 'e2'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm2'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm2'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
3: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '83', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '83']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z3'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z3'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e3'}], {'merged': [['extra', 'e3'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm3'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm3'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
4: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '84', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '84']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z4'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z4'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e4'}], {'merged': [['extra', 'e4'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm4'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm4'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
5: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '85', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '85']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z5'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z5'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e5'}], {'merged': [['extra', 'e5'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm5'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm5'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
}[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 |
|---|---|---|---|
| each side changes a different key | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | Passed |
| both change a key the same way | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | Passed |
| both delete the same key | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | Passed |
| conflicting changes keep ours | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | Passed |
| delete versus modify conflicts | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | Passed |
| explicit null differs from deletion | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | Passed |
| key added only by theirs | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']]} | Failed |
| key added only by ours | {'conflicts': [], 'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']]} | Passed |
| modify versus delete conflicts | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | Passed |
| null in base and deleted by ours | {'conflicts': [], 'merged': [['j', '2']]} | {'conflicts': [], 'merged': [['j', '2']]} | Passed |
SHA-256 / 2fd292ab502f4c198c44a7fbe644075afbc3d8633a0e89e454d39b3e3a57f964
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(base, ours, theirs):
MISSING = object()
merged, conflicts = {}, []
for k in sorted(set(base) | set(theirs)):
b = base.get(k, MISSING)
o = ours.get(k, MISSING)
t = theirs.get(k, MISSING)
if o == t:
r = o
elif o == b:
r = t
elif t == b:
r = o
else:
conflicts.append(k)
r = o
if r is not MISSING:
merged[k] = r
return {'merged': sorted([k, v] for k, v in merged.items()), 'conflicts': conflicts}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '81', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z1'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e1'}], {'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm1'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
2: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '82', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '82']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z2'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z2'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e2'}], {'merged': [['extra', 'e2'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm2'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm2'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
3: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '83', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '83']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z3'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z3'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e3'}], {'merged': [['extra', 'e3'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm3'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm3'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
4: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '84', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '84']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z4'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z4'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e4'}], {'merged': [['extra', 'e4'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm4'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm4'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
5: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '85', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '85']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z5'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z5'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e5'}], {'merged': [['extra', 'e5'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm5'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm5'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
}[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 |
|---|---|---|---|
| each side changes a different key | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | Passed |
| both change a key the same way | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | Passed |
| both delete the same key | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | Passed |
| conflicting changes keep ours | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | Passed |
| delete versus modify conflicts | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | Passed |
| explicit null differs from deletion | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | Passed |
| key added only by theirs | {'conflicts': [], 'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']]} | Passed |
| key added only by ours | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']]} | Failed |
| modify versus delete conflicts | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | Passed |
| null in base and deleted by ours | {'conflicts': [], 'merged': [['j', '2']]} | {'conflicts': [], 'merged': [['j', '2']]} | Passed |
SHA-256 / bfa3d180322b6011cb383b1c4806120598124682ed30917b4035982c38f551ca
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(base, ours, theirs):
MISSING = object()
merged, conflicts = {}, []
for k in sorted(set(base) | set(ours) | set(theirs)):
b = base.get(k, MISSING)
o = ours.get(k, MISSING)
t = theirs.get(k, MISSING)
if o == t:
r = o
elif o == b:
r = t
elif t == b:
r = o
else:
conflicts.append(k)
r = o
if r is not MISSING:
merged[k] = r
return {'merged': sorted([k, v] for k, v in merged.items()), 'conflicts': conflicts}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '81', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z1'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e1'}], {'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm1'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
2: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '82', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '82']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z2'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z2'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e2'}], {'merged': [['extra', 'e2'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm2'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm2'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
3: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '83', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '83']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z3'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z3'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e3'}], {'merged': [['extra', 'e3'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm3'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm3'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
4: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '84', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '84']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z4'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z4'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e4'}], {'merged': [['extra', 'e4'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm4'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm4'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
5: [('each side changes a different key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'b', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '85', 'mode': 'x'}], {'merged': [['host', 'b'], ['mode', 'x'], ['port', '85']], 'conflicts': []}), ('both change a key the same way', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'y'}, {'host': 'a', 'port': '80', 'mode': 'y'}], {'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']], 'conflicts': []}), ('both delete the same key', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['port', '80']], 'conflicts': []}), ('conflicting changes keep ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '1', 'mode': 'x'}, {'host': 'a', 'port': '2', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']], 'conflicts': ['port']}), ('delete versus modify conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'z5'}, {'host': 'a', 'port': '80'}], {'merged': [['host', 'a'], ['mode', 'z5'], ['port', '80']], 'conflicts': ['mode']}), ('explicit null differs from deletion', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': None}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', None], ['port', '80']], 'conflicts': []}), ('key added only by theirs', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'extra': 'e5'}], {'merged': [['extra', 'e5'], ['host', 'a'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('key added only by ours', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'port': '80', 'mode': 'x', 'mine': 'm5'}, {'host': 'a', 'port': '80', 'mode': 'x'}], {'merged': [['host', 'a'], ['mine', 'm5'], ['mode', 'x'], ['port', '80']], 'conflicts': []}), ('modify versus delete conflicts', [{'host': 'a', 'port': '80', 'mode': 'x'}, {'host': 'a', 'mode': 'x'}, {'host': 'a', 'port': '443', 'mode': 'x'}], {'merged': [['host', 'a'], ['mode', 'x']], 'conflicts': ['port']}), ('null in base and deleted by ours', [{'k': None, 'j': '1'}, {'j': '1'}, {'k': None, 'j': '2'}], {'merged': [['j', '2']], 'conflicts': []})],
}[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 |
|---|---|---|---|
| each side changes a different key | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | {'conflicts': [], 'merged': [['host', 'b'], ['mode', 'x'], ['port', '81']]} | Passed |
| both change a key the same way | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', 'y'], ['port', '80']]} | Passed |
| both delete the same key | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['port', '80']]} | Passed |
| conflicting changes keep ours | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x'], ['port', '1']]} | Passed |
| delete versus modify conflicts | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | {'conflicts': ['mode'], 'merged': [['host', 'a'], ['mode', 'z1'], ['port', '80']]} | Passed |
| explicit null differs from deletion | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mode', None], ['port', '80']]} | Passed |
| key added only by theirs | {'conflicts': [], 'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['extra', 'e1'], ['host', 'a'], ['mode', 'x'], ['port', '80']]} | Passed |
| key added only by ours | {'conflicts': [], 'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']]} | {'conflicts': [], 'merged': [['host', 'a'], ['mine', 'm1'], ['mode', 'x'], ['port', '80']]} | Passed |
| modify versus delete conflicts | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | {'conflicts': ['port'], 'merged': [['host', 'a'], ['mode', 'x']]} | Passed |
| null in base and deleted by ours | {'conflicts': [], 'merged': [['j', '2']]} | {'conflicts': [], 'merged': [['j', '2']]} | Passed |
SHA-256 / 8d90e3af1313999b155a9ede11ce8e2147e1a6712b46c8e934df371b31dd4764
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.032107+00:00.
Case digest / 27c94ef03e02bb6d29f5e1b95c5544915080e5f32b6d7cce7ca3c03e0295236c