broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return draft
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in dirty}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

prompt:
Deletion overlay.

A saved draft holds explicit dirty fields and tombstones. Restore untouched server fields, retain local null values, flag dirty fields changed against newer server data, and export only surviving dirty fields. Operation deletion-overlay has the six explicit input/output oracles below.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return dirty
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if draft.get(k) and draft.get(k)!=server.get(k)]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

prompt:
Conflict fields.

A saved draft holds explicit dirty fields and tombstones. Restore untouched server fields, retain local null values, flag dirty fields changed against newer server data, and export only surviving dirty fields. Operation conflict-fields has the six explicit input/output oracles below.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision!=saved_revision
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>=saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

prompt:
Server advance warning.

A saved draft holds explicit dirty fields and tombstones. Restore untouched server fields, retain local null values, flag dirty fields changed against newer server data, and export only surviving dirty fields. Operation server-advance-warning has the six explicit input/output oracles below.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in draft.items() if k not in server}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

prompt:
Clean draft expiry.

A saved draft holds explicit dirty fields and tombstones. Restore untouched server fields, retain local null values, flag dirty fields changed against newer server data, and export only surviving dirty fields. Operation clean-draft-expiry has the six explicit input/output oracles below.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(operation, s):
    draft, server, dirty, saved_revision, server_revision, deleted = s
    if operation == 'restore-dirty-fields':
        return {**server,**{k:v for k,v in draft.items() if k in dirty}}
    if operation == 'deletion-overlay':
        return {k:v for k,v in draft.items() if k not in deleted}
    if operation == 'conflict-fields':
        return [k for k in dirty if k in server and draft.get(k)!=server[k]]
    if operation == 'server-advance-warning':
        return server_revision>saved_revision and bool(dirty)
    if operation == 'clean-draft-expiry':
        return not dirty and not deleted
    if operation == 'restore-added-fields':
        return {k:v for k,v in server.items() if k not in draft}
    if operation == 'discard-restores-server':
        return dict(server)
    if operation == 'edited-field-export':
        return {k:draft[k] for k in dirty if k in draft and k not in deleted}
    if operation == 'restoration-review':
        return 'review' if dirty and server_revision>saved_revision else 'restore'
    if operation == 'known-deletion-list':
        return [k for k in deleted if k in server]
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('restore-dirty-fields scenario 1', solve('restore-dirty-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':3})
check('restore-dirty-fields scenario 2', solve('restore-dirty-fields', ({}, {'a':N},[],2,2,[])), {'a':N})
check('restore-dirty-fields scenario 3', solve('restore-dirty-fields', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('restore-dirty-fields scenario 4', solve('restore-dirty-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0,'b':N})
check('restore-dirty-fields scenario 5', solve('restore-dirty-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-dirty-fields scenario 6', solve('restore-dirty-fields', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('deletion-overlay scenario 1', solve('deletion-overlay', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N,'b':2})
check('deletion-overlay scenario 2', solve('deletion-overlay', ({}, {'a':N},[],2,2,[])), {})
check('deletion-overlay scenario 3', solve('deletion-overlay', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('deletion-overlay scenario 4', solve('deletion-overlay', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('deletion-overlay scenario 5', solve('deletion-overlay', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('deletion-overlay scenario 6', solve('deletion-overlay', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('conflict-fields scenario 1', solve('conflict-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), ['a'])
check('conflict-fields scenario 2', solve('conflict-fields', ({}, {'a':N},[],2,2,[])), [])
check('conflict-fields scenario 3', solve('conflict-fields', ({'a':None},{'a':0},['a'],2,1,[])), ['a'])
check('conflict-fields scenario 4', solve('conflict-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), (['a'] if N==2 else ['a','b']))
check('conflict-fields scenario 5', solve('conflict-fields', ({'a':N},{},['a'],0,0,[])), [])
check('conflict-fields scenario 6', solve('conflict-fields', ({'a':N},{'a':N},[],1,1,['x'])), [])
check('server-advance-warning scenario 1', solve('server-advance-warning', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), True)
check('server-advance-warning scenario 2', solve('server-advance-warning', ({}, {'a':N},[],2,2,[])), False)
check('server-advance-warning scenario 3', solve('server-advance-warning', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('server-advance-warning scenario 4', solve('server-advance-warning', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), True)
check('server-advance-warning scenario 5', solve('server-advance-warning', ({'a':N},{},['a'],0,0,[])), False)
check('server-advance-warning scenario 6', solve('server-advance-warning', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('clean-draft-expiry scenario 1', solve('clean-draft-expiry', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), False)
check('clean-draft-expiry scenario 2', solve('clean-draft-expiry', ({}, {'a':N},[],2,2,[])), True)
check('clean-draft-expiry scenario 3', solve('clean-draft-expiry', ({'a':None},{'a':0},['a'],2,1,[])), False)
check('clean-draft-expiry scenario 4', solve('clean-draft-expiry', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), False)
check('clean-draft-expiry scenario 5', solve('clean-draft-expiry', ({'a':N},{},['a'],0,0,[])), False)
check('clean-draft-expiry scenario 6', solve('clean-draft-expiry', ({'a':N},{'a':N},[],1,1,['x'])), False)
check('restore-added-fields scenario 1', solve('restore-added-fields', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {})
check('restore-added-fields scenario 2', solve('restore-added-fields', ({}, {'a':N},[],2,2,[])), {})
check('restore-added-fields scenario 3', solve('restore-added-fields', ({'a':None},{'a':0},['a'],2,1,[])), {})
check('restore-added-fields scenario 4', solve('restore-added-fields', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {})
check('restore-added-fields scenario 5', solve('restore-added-fields', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('restore-added-fields scenario 6', solve('restore-added-fields', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('discard-restores-server scenario 1', solve('discard-restores-server', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':0,'b':3})
check('discard-restores-server scenario 2', solve('discard-restores-server', ({}, {'a':N},[],2,2,[])), {'a':N})
check('discard-restores-server scenario 3', solve('discard-restores-server', ({'a':None},{'a':0},['a'],2,1,[])), {'a':0})
check('discard-restores-server scenario 4', solve('discard-restores-server', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':1,'b':2})
check('discard-restores-server scenario 5', solve('discard-restores-server', ({'a':N},{},['a'],0,0,[])), {})
check('discard-restores-server scenario 6', solve('discard-restores-server', ({'a':N},{'a':N},[],1,1,['x'])), {'a':N})
check('edited-field-export scenario 1', solve('edited-field-export', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), {'a':N})
check('edited-field-export scenario 2', solve('edited-field-export', ({}, {'a':N},[],2,2,[])), {})
check('edited-field-export scenario 3', solve('edited-field-export', ({'a':None},{'a':0},['a'],2,1,[])), {'a':None})
check('edited-field-export scenario 4', solve('edited-field-export', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), {'a':0})
check('edited-field-export scenario 5', solve('edited-field-export', ({'a':N},{},['a'],0,0,[])), {'a':N})
check('edited-field-export scenario 6', solve('edited-field-export', ({'a':N},{'a':N},[],1,1,['x'])), {})
check('restoration-review scenario 1', solve('restoration-review', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), 'review')
check('restoration-review scenario 2', solve('restoration-review', ({}, {'a':N},[],2,2,[])), 'restore')
check('restoration-review scenario 3', solve('restoration-review', ({'a':None},{'a':0},['a'],2,1,[])), 'restore')
check('restoration-review scenario 4', solve('restoration-review', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), 'review')
check('restoration-review scenario 5', solve('restoration-review', ({'a':N},{},['a'],0,0,[])), 'restore')
check('restoration-review scenario 6', solve('restoration-review', ({'a':N},{'a':N},[],1,1,['x'])), 'restore')
check('known-deletion-list scenario 1', solve('known-deletion-list', ({'a':N,'b':2},{'a':0,'b':3},['a'],1,2,[])), [])
check('known-deletion-list scenario 2', solve('known-deletion-list', ({}, {'a':N},[],2,2,[])), [])
check('known-deletion-list scenario 3', solve('known-deletion-list', ({'a':None},{'a':0},['a'],2,1,[])), [])
check('known-deletion-list scenario 4', solve('known-deletion-list', ({'a':0,'b':N},{'a':1,'b':2},['a','b'],1,3,['b'])), ['b'])
check('known-deletion-list scenario 5', solve('known-deletion-list', ({'a':N},{},['a'],0,0,[])), [])
check('known-deletion-list scenario 6', solve('known-deletion-list', ({'a':N},{'a':N},[],1,1,['x'])), [])
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)

prompt:
Restore added fields.

A saved draft holds explicit dirty fields and tombstones. Restore untouched server fields, retain local null values, flag dirty fields changed against newer server data, and export only surviving dirty fields. Operation restore-added-fields has the six explicit input/output oracles below.

split: open-access