100 lines
4.9 KiB
Python
100 lines
4.9 KiB
Python
import copy
|
|
import json
|
|
from jsonschema import Draft202012Validator
|
|
from test_investigation_consolidation import populated
|
|
from viano_bug_analysis.analysis.investigation_view import working_view
|
|
from viano_bug_analysis.analysis.investigation_focus import focused_view
|
|
from viano_bug_analysis.analysis.investigation_blocks import restore_blocks, block_view
|
|
from viano_bug_analysis.analysis.investigation_prompt import build_prompt, output_schema
|
|
from viano_bug_analysis.analysis.model_context import model_json
|
|
|
|
|
|
def fixture():
|
|
c = populated()
|
|
c['prompt_version'] = 'investigation_project_v8'
|
|
c['recalled_evidence'] = []
|
|
c['budget']['accounts']['H1']['actions'] = {}
|
|
return c
|
|
|
|
|
|
def test_index_omits_old_payloads_but_preserves_predicates_and_scope():
|
|
c = fixture(); before = copy.deepcopy(c)
|
|
v = focused_view(c)
|
|
assert set(v['evidence']) == {'E000001'}
|
|
assert len(v['evidence_index']['rows']) == 2
|
|
row = v['evidence_index']['rows'][1]
|
|
assert row[0:2] == ['E000002','H2']
|
|
assert row[3][0]['query']['start_line'] == 41
|
|
assert row[3][0]['result_scope'] == {'coverage':'selected_lines','truncated':False}
|
|
assert 'code line 120' not in model_json(v)
|
|
assert c == before and focused_view(c) == v
|
|
assert set(v['hypotheses']['H2']) == {'proposal','confidence','disposition'}
|
|
assert set(v['hypotheses']['H2']['proposal']) == {'title','mechanism'}
|
|
assert len(model_json(v)) < len(model_json(block_view(c)))
|
|
|
|
|
|
def test_recall_exact_contents_including_cross_hypothesis_counterevidence():
|
|
c = fixture(); c['recalled_evidence'] = ['E000002']
|
|
v = restore_blocks(focused_view(c))
|
|
assert v['evidence']['E000002']['content'] == working_view(c)['evidence']['E000002']['content']
|
|
c['recalled_evidence'] = []
|
|
assert 'E000002' not in focused_view(c)['evidence']
|
|
|
|
|
|
def test_unassessed_other_hypothesis_result_stays_visible():
|
|
c = fixture()
|
|
c['budget']['accounts']['H2'] = {'actions':{'A1':{'status':'result_stored'}}}
|
|
assert set(focused_view(c)['evidence']) == {'E000001','E000002'}
|
|
|
|
|
|
def test_recall_schema_is_bounded_and_legacy_prompt_is_unchanged():
|
|
c = fixture(); new = output_schema(c)
|
|
schema = new['properties']['next']
|
|
validator = Draft202012Validator(schema)
|
|
assert validator.is_valid({'kind':'recall','evidence_refs':['E000002']})
|
|
for refs in ([], ['E000002']*2, ['E000001','E000002','E000003','E000004','E000005']):
|
|
assert not validator.is_valid({'kind':'recall','evidence_refs':refs})
|
|
assert json.loads(build_prompt(c)['messages'][1]['content'])['input'] == focused_view(c)
|
|
c['prompt_version'] = 'investigation_project_v7'
|
|
assert not Draft202012Validator(output_schema(c)['properties']['next']).is_valid({'kind':'recall','evidence_refs':['E000001']})
|
|
|
|
|
|
def test_full_history_restores_every_payload_note_and_question_without_recall():
|
|
from viano_bug_analysis.analysis.investigation_focus import full_history_view
|
|
c=fixture();c['prompt_version']='investigation_project_v10'
|
|
for h in c['hypotheses'].values():
|
|
h['notes']=['old supporting observation','later counterevidence','current assessment']
|
|
h['questions']=[{'id':'Q0001','text':'Does it exist?','resolved':True},
|
|
{'id':'Q0002','text':'Which snapshot?','resolved':False}]
|
|
c['recalled_evidence']=[]
|
|
before=copy.deepcopy(c)
|
|
view=full_history_view(c)
|
|
restored=restore_blocks(view)
|
|
expected=working_view(c);expected.pop('recalled_evidence',None)
|
|
for hid,h in expected['hypotheses'].items():
|
|
if hid!=c['selected_hypothesis']:h['proposal']={k:h['proposal'][k] for k in ('title','mechanism')}
|
|
assert model_json(restored)==model_json(expected)
|
|
assert set(view['evidence'])==set(c['evidence'])
|
|
assert 'evidence_index' not in view and 'recalled_evidence' not in view
|
|
assert c==before
|
|
schema=output_schema(c)
|
|
assert not Draft202012Validator(schema['properties']['next']).is_valid({'kind':'recall','evidence_refs':['E000002']})
|
|
v7={**c,'prompt_version':'investigation_project_v7'}
|
|
assert schema==output_schema(v7)
|
|
request=build_prompt(c)
|
|
assert json.loads(request['messages'][1]['content'])['input']==view
|
|
assert 'There is no recall action' in request['messages'][0]['content']
|
|
|
|
|
|
def test_full_history_includes_empty_negative_and_other_hypothesis_findings():
|
|
from viano_bug_analysis.analysis.investigation_focus import full_history_view
|
|
c=fixture();c['prompt_version']='investigation_project_v10'
|
|
c['previous_result']=None
|
|
capture=c['evidence']['E000002']['content']['items'][0]
|
|
capture['result']['items']=[]
|
|
capture['result']['coverage']='complete_filtered_rows'
|
|
view=restore_blocks(full_history_view(c))
|
|
assert view['evidence']['E000002']['content']['items'][0]['result']['items']==[]
|
|
assert view['evidence']['E000002']['content']['items'][0]['result']['coverage']=='complete_filtered_rows'
|
|
assert set(view['evidence'])==set(c['evidence'])
|