Ground handoff map values through explicit canonical fact bindings
This commit is contained in:
1 parent
061f82e6f1
commit
c6f4ea9877
10 files changed
+257
-5
No files matched your search
@@ -100,6 +100,11 @@ def test_existing_v2_call_stays_frozen_after_upgrade(diagnosed):
|
||||
store, _ = diagnosed
|
||||
adapter = RequestAdapter()
|
||||
builder = ChangeRequestBuilder(store, gateway(adapter))
|
||||
original_context = builder.context
|
||||
def legacy_context(reader, policy, **kwargs):
|
||||
kwargs['parameter_grounding'] = 1
|
||||
return original_context(reader, policy, **kwargs)
|
||||
builder.context = legacy_context
|
||||
original = builder._request
|
||||
builder._request = lambda reader, context, operation, **kw: original(
|
||||
reader, context, operation, version='change_request_v2')
|
||||
@@ -108,6 +113,7 @@ def test_existing_v2_call_stays_frozen_after_upgrade(diagnosed):
|
||||
with pytest.raises(ChangeRequestError):
|
||||
build(builder)
|
||||
builder._request = original
|
||||
builder.context = original_context
|
||||
builder.publish = publish
|
||||
assert build(builder).status == 'COMPLETED'
|
||||
assert build(builder).reused and adapter.calls == 1
|
||||
@@ -0,0 +1,74 @@
|
||||
import copy
|
||||
import pytest
|
||||
from viano_bug_analysis.analysis.database_value_grounding import unsupported_assignments
|
||||
from viano_bug_analysis.profiles.database_bindings import fact_bindings
|
||||
|
||||
|
||||
def context():
|
||||
case = {'case': {'project': {'type': 'wow', 'profile': 'vcore'}},
|
||||
'runtime_facts': {'facts': [{'id': 'F0002', 'name': 'map_id', 'value': 0,
|
||||
'provenance': {'kind': 'reproduction_record', 'source_ref': 'reproduction.json'}}]}}
|
||||
return {'parameter_grounding': 2, 'case': case,
|
||||
'database_fact_bindings': fact_bindings(case),
|
||||
'evidence': {'E000001': {'content': {'items': [{'query': {'kind':'database.rows','table':'creature'},
|
||||
'result': {'items': [{'row': {'map':1,'phaseMask':1,'zoneId':14}}]}}]}}}}
|
||||
|
||||
|
||||
def rejected(c, text='Use map=0.'):
|
||||
return unsupported_assignments({'implementation_guidance':[text]}, c)
|
||||
|
||||
|
||||
def test_canonical_map_zero_authorizes_known_creature_column_without_mutation():
|
||||
c=context(); before=copy.deepcopy(c)
|
||||
assert c['database_fact_bindings']==[{'fact_id':'F0002','fact_name':'map_id','table':'creature','column':'map'}]
|
||||
assert rejected(c)==[] and c==before
|
||||
assert rejected(c,'Use map=2.')==['map']
|
||||
assert rejected(c,'Use phaseMask=14.')==['phasemask']
|
||||
|
||||
|
||||
def test_legacy_context_preserves_rejection_and_exact_named_fact_needs_v2():
|
||||
c=context(); c['parameter_grounding']=1
|
||||
assert rejected(c)==['map']
|
||||
c['parameter_grounding']=2;c['database_fact_bindings']=[]
|
||||
assert rejected(c)==['map']
|
||||
c['case']['runtime_facts']['facts'][0]['name']='map'
|
||||
assert rejected(c)==[]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('change',[
|
||||
lambda c: c['case']['case']['project'].update(profile='other'),
|
||||
lambda c: c['case']['runtime_facts']['facts'][0].update(value='0'),
|
||||
lambda c: c['case']['runtime_facts']['facts'][0].update(value=False),
|
||||
lambda c: c['case']['runtime_facts']['facts'][0].update(name='zone_id'),
|
||||
lambda c: c['case']['runtime_facts']['facts'][0]['provenance'].update(kind='tester_assumption'),
|
||||
lambda c: c['database_fact_bindings'][0].update(column='phaseMask'),
|
||||
lambda c: c['database_fact_bindings'][0].update(fact_id='UNKNOWN'),
|
||||
lambda c: c['evidence']['E000001']['content']['items'][0]['query'].update(table='unrelated'),
|
||||
lambda c: c['case']['runtime_facts']['facts'].append(copy.deepcopy(c['case']['runtime_facts']['facts'][0])),
|
||||
])
|
||||
def test_alias_does_not_grant_unbound_or_ambiguous_values(change):
|
||||
c=context();change(c)
|
||||
assert rejected(c)==['map']
|
||||
|
||||
|
||||
def test_unknown_suffix_is_not_an_alias_and_schema_only_binding_is_supported():
|
||||
c=context();f=c['case']['runtime_facts']['facts'][0];f['name']='custom_map_id'
|
||||
c['database_fact_bindings']=fact_bindings(c['case'])
|
||||
assert c['database_fact_bindings']==[] and rejected(c)==['map']
|
||||
f['name']='map_id';c['database_fact_bindings']=fact_bindings(c['case'])
|
||||
cap=c['evidence']['E000001']['content']['items'][0]
|
||||
cap['query']['kind']='database.schema'
|
||||
cap['result']['items']=[{'table':'creature','columns':[{'COLUMN_NAME':'map','COLUMN_TYPE':'smallint(5) unsigned'}]}]
|
||||
assert rejected(c)==[]
|
||||
|
||||
|
||||
def test_full_handoff_validator_accepts_bound_map_but_still_rejects_wrong_mask():
|
||||
from test_handoff_outcomes import minimal, template
|
||||
from viano_bug_analysis.analysis.change_request_contracts import validate_request, ChangeRequestError
|
||||
payload,c=minimal();new=context();c.update({k:new[k] for k in ('case','parameter_grounding','database_fact_bindings')})
|
||||
c['evidence']['E000001']['content']=new['evidence']['E000001']['content']
|
||||
for item in c['evidence']['E000001']['content']['items']:item['source_ref']='code.cpp'
|
||||
template(payload,c);payload['implementation_guidance']=['Use map=0 and {{POSITION_X}}.']
|
||||
validate_request(payload,c)
|
||||
payload['implementation_guidance']=['Use map=0, phaseMask=14 and {{POSITION_X}}.']
|
||||
with pytest.raises(ChangeRequestError,match='UNGROUNDED_DATABASE_VALUE'):validate_request(payload,c)
|
||||
@@ -45,6 +45,9 @@ def test_template_and_human_data_task_are_completed_handoffs(diagnosed, tmp_path
|
||||
result=build(ChangeRequestBuilder(store,g))
|
||||
assert result.status=='COMPLETED' and result.failure_ref is None
|
||||
with PackageReader(original) as old, PackageReader(result.package) as reader:
|
||||
context=json.loads(reader.read_bytes(reader.manifest['artifacts']['change_request_context']))
|
||||
assert context['parameter_grounding'] == 2
|
||||
assert context['database_fact_bindings'] == [] # project-independent fixture
|
||||
coding=json.loads(reader.read_bytes(reader.manifest['artifacts']['change_request']))
|
||||
assert coding['assignment']=='assigned' and coding['request']['status']=='template'
|
||||
assert coding['human_dev_assigned'] is True and 'human_dev' not in coding['request']
|
||||
|
||||
Reference in new issue
Block a user