FA-38296 / Table interactions / Open access
Table column schema migration: alias target validation · case 01
The table alias target validation result violates the stipulated table column schema migration contract.
ROOT CAUSE
The alias target validation decision uses 'None' instead of 'aliases.get(k) if aliases.get(k) in ids else None'.
VERIFIED REPAIR
Apply the complete alias target validation rule: aliases.get(k) if aliases.get(k) in ids else None.
Unsuccessful approach: The attempted repair 'k if k in ids else None' still loses a required part of the table contract.
Case contract
Schema migration gives surviving IDs precedence over aliases, validates alias targets, deduplicates migrated order/selection and appends new columns. Direct widths override alias widths, required columns stay visible, drafts migrate only across equal types, and deleted anchors clear.
Why this case matters
An offline table UI model isolates table column schema migration, including adversarial row/column relationships.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, aliases, view, drafts, selected, anchor):
ids=[c['id'] for c in new]
def remap(k):
if k in ids: return k
return None
order=[]
for k in view['order']:
mapped=remap(k)
if mapped is not None and mapped not in order: order.append(mapped)
order += [k for k in ids if k not in order]
widths={}
for k,v in view['widths'].items():
mapped=remap(k)
if mapped is not None and (mapped not in widths or k==mapped): widths[mapped]=v
hidden=[k for k in order if any(remap(x)==k for x in view['hidden']) and not next(c for c in new if c['id']==k).get('required')]
newdraft=[]
oldtypes={c['id']:c['type'] for c in old}; newtypes={c['id']:c['type'] for c in new}
for r,c,value in drafts:
mapped=remap(c)
if mapped is not None and oldtypes.get(c)==newtypes[mapped]: newdraft.append((r,mapped,value))
newsel=[]
for r,c in selected:
mapped=remap(c)
if mapped is not None and (r,mapped) not in newsel: newsel.append((r,mapped))
return {'order':order,'widths':widths,'hidden':hidden,'drafts':newdraft,'selected':newsel,'anchor':(anchor[0],remap(anchor[1])) if anchor is not None and remap(anchor[1]) is not None else None}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':1+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 8}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 2:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':2+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 9}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 3:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':3+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 10}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 4:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':4+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 11}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 5:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':5+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 12}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
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 |
|---|---|---|---|
| renamed numeric column | {'anchor': None, 'drafts': [['r', 'b', 'x']], 'hidden': [], 'order': ['b', 'new', 'fresh'], 'selected': [['r', 'b']], 'widths': {}} | {'anchor': ['r', 'new'], 'drafts': [['r', 'new', 3], ['r', 'b', 'x']], 'hidden': ['new'], 'order': ['new', 'b', 'fresh'], 'selected': [['r', 'new'], ['r', 'b']], 'widths': {'new': 8}} | Failed |
| direct id wins alias | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | Passed |
| merged aliases direct widths last | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [], 'widths': {'a': 8}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {'a': 8}} | Failed |
| type-changed draft | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | Passed |
| removed schema key | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | Passed |
| reverse saved order | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | Passed |
| required renamed column | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | Passed |
SHA-256 / 90ba48243bb3a073e720b03c315786e83dc18597ba7296a3f839a9f2202e09a2
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, aliases, view, drafts, selected, anchor):
ids=[c['id'] for c in new]
def remap(k):
if k in ids: return k
return k if k in ids else None
order=[]
for k in view['order']:
mapped=remap(k)
if mapped is not None and mapped not in order: order.append(mapped)
order += [k for k in ids if k not in order]
widths={}
for k,v in view['widths'].items():
mapped=remap(k)
if mapped is not None and (mapped not in widths or k==mapped): widths[mapped]=v
hidden=[k for k in order if any(remap(x)==k for x in view['hidden']) and not next(c for c in new if c['id']==k).get('required')]
newdraft=[]
oldtypes={c['id']:c['type'] for c in old}; newtypes={c['id']:c['type'] for c in new}
for r,c,value in drafts:
mapped=remap(c)
if mapped is not None and oldtypes.get(c)==newtypes[mapped]: newdraft.append((r,mapped,value))
newsel=[]
for r,c in selected:
mapped=remap(c)
if mapped is not None and (r,mapped) not in newsel: newsel.append((r,mapped))
return {'order':order,'widths':widths,'hidden':hidden,'drafts':newdraft,'selected':newsel,'anchor':(anchor[0],remap(anchor[1])) if anchor is not None and remap(anchor[1]) is not None else None}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':1+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 8}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 2:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':2+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 9}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 3:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':3+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 10}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 4:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':4+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 11}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 5:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':5+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 12}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
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 |
|---|---|---|---|
| renamed numeric column | {'anchor': None, 'drafts': [['r', 'b', 'x']], 'hidden': [], 'order': ['b', 'new', 'fresh'], 'selected': [['r', 'b']], 'widths': {}} | {'anchor': ['r', 'new'], 'drafts': [['r', 'new', 3], ['r', 'b', 'x']], 'hidden': ['new'], 'order': ['new', 'b', 'fresh'], 'selected': [['r', 'new'], ['r', 'b']], 'widths': {'new': 8}} | Failed |
| direct id wins alias | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | Passed |
| merged aliases direct widths last | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [], 'widths': {'a': 8}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {'a': 8}} | Failed |
| type-changed draft | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | Passed |
| removed schema key | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | Passed |
| reverse saved order | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | Passed |
| required renamed column | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | Passed |
SHA-256 / 2cc1a896c8486a68a07c94e20b8b40411343df49cae95d90c15fd1a6a9ce68f0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(old, new, aliases, view, drafts, selected, anchor):
ids=[c['id'] for c in new]
def remap(k):
if k in ids: return k
return aliases.get(k) if aliases.get(k) in ids else None
order=[]
for k in view['order']:
mapped=remap(k)
if mapped is not None and mapped not in order: order.append(mapped)
order += [k for k in ids if k not in order]
widths={}
for k,v in view['widths'].items():
mapped=remap(k)
if mapped is not None and (mapped not in widths or k==mapped): widths[mapped]=v
hidden=[k for k in order if any(remap(x)==k for x in view['hidden']) and not next(c for c in new if c['id']==k).get('required')]
newdraft=[]
oldtypes={c['id']:c['type'] for c in old}; newtypes={c['id']:c['type'] for c in new}
for r,c,value in drafts:
mapped=remap(c)
if mapped is not None and oldtypes.get(c)==newtypes[mapped]: newdraft.append((r,mapped,value))
newsel=[]
for r,c in selected:
mapped=remap(c)
if mapped is not None and (r,mapped) not in newsel: newsel.append((r,mapped))
return {'order':order,'widths':widths,'hidden':hidden,'drafts':newdraft,'selected':newsel,'anchor':(anchor[0],remap(anchor[1])) if anchor is not None and remap(anchor[1]) is not None else None}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':1+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 8}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 2:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':2+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 9}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 3:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':3+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 10}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 4:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':4+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 11}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
if N == 5:
check('renamed numeric column', solve([{'id':'old','type':'number'},{'id':'b','type':'text'}], [{'id':'new','type':'number'},{'id':'b','type':'text'},{'id':'fresh','type':'text'}], {'old':'new'}, {'order':['old','b'],'widths':{'old':5+7},'hidden':['old']}, [('r','old',3),('r','b','x')], [('r','old'),('r','b')], ('r','old')), {'order': ['new', 'b', 'fresh'], 'widths': {'new': 12}, 'hidden': ['new'], 'drafts': [('r', 'new', 3), ('r', 'b', 'x')], 'selected': [('r', 'new'), ('r', 'b')], 'anchor': ('r', 'new')})
check('direct id wins alias', solve([{'id':'a','type':'text'},{'id':'b','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'}], {'a':'b'}, {'order':['a','b'],'widths':{'a':4,'b':5},'hidden':[]}, [], [], ('r','a')), {'order': ['a', 'b'], 'widths': {'a': 4, 'b': 5}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': ('r', 'a')})
check('merged aliases direct widths last', solve([{'id':'x','type':'text'},{'id':'y','type':'text'},{'id':'a','type':'text'}], [{'id':'a','type':'text'}], {'x':'a','y':'a'}, {'order':['x','y','a'],'widths':{'x':4,'a':8,'y':6},'hidden':[]}, [], [('r','x'),('r','y')], None), {'order': ['a'], 'widths': {'a': 8}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': None})
check('type-changed draft', solve([{'id':'a','type':'text'}], [{'id':'a','type':'number'}], {}, {'order':['a'],'widths':{},'hidden':[]}, [('r','a','1')], [('r','a')], ('r','a')), {'order': ['a'], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [('r', 'a')], 'anchor': ('r', 'a')})
check('removed schema key', solve([{'id':'gone','type':'text'}], [], {'gone':'also-gone'}, {'order':['gone'],'widths':{'gone':9},'hidden':['gone']}, [('r','gone','v')], [('r','gone')], ('r','gone')), {'order': [], 'widths': {}, 'hidden': [], 'drafts': [], 'selected': [], 'anchor': None})
check('reverse saved order', solve([{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], [{'id':'a','type':'text'},{'id':'b','type':'text'},{'id':'c','type':'text'}], {}, {'order':['c','b','a'],'widths':{},'hidden':['b']}, [], [], None), {'order': ['c', 'b', 'a'], 'widths': {}, 'hidden': ['b'], 'drafts': [], 'selected': [], 'anchor': None})
check('required renamed column', solve([{'id':'old','type':'text'}], [{'id':'a','type':'text'},{'id':'new','type':'text','required':True}], {'old':'new'}, {'order':['a','old'],'widths':{},'hidden':['old','a']}, [], [], None), {'order': ['a', 'new'], 'widths': {}, 'hidden': ['a'], 'drafts': [], 'selected': [], 'anchor': None})
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 |
|---|---|---|---|
| renamed numeric column | {'anchor': ['r', 'new'], 'drafts': [['r', 'new', 3], ['r', 'b', 'x']], 'hidden': ['new'], 'order': ['new', 'b', 'fresh'], 'selected': [['r', 'new'], ['r', 'b']], 'widths': {'new': 8}} | {'anchor': ['r', 'new'], 'drafts': [['r', 'new', 3], ['r', 'b', 'x']], 'hidden': ['new'], 'order': ['new', 'b', 'fresh'], 'selected': [['r', 'new'], ['r', 'b']], 'widths': {'new': 8}} | Passed |
| direct id wins alias | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a', 'b'], 'selected': [], 'widths': {'a': 4, 'b': 5}} | Passed |
| merged aliases direct widths last | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {'a': 8}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {'a': 8}} | Passed |
| type-changed draft | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | {'anchor': ['r', 'a'], 'drafts': [], 'hidden': [], 'order': ['a'], 'selected': [['r', 'a']], 'widths': {}} | Passed |
| removed schema key | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': [], 'order': [], 'selected': [], 'widths': {}} | Passed |
| reverse saved order | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['b'], 'order': ['c', 'b', 'a'], 'selected': [], 'widths': {}} | Passed |
| required renamed column | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | {'anchor': None, 'drafts': [], 'hidden': ['a'], 'order': ['a', 'new'], 'selected': [], 'widths': {}} | Passed |
SHA-256 / 5ce8751763296f2cd68024dfc112be5dca466c1e0cc5f6eba7eb0400ba8ba7e5
Verification & scope
Old/new schema IDs are unique and aliases are single-hop; draft compatibility requires exact stipulated type-name equality. Deterministic offline table UI model; no browser, DOM, framework, or standards conformance is claimed. 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:43:09.705265+00:00.
Case digest / ff976669e84574c8a1cabdfc7049528ab1d091191c82f28e4dde55ce43866ee5