Produce coding and human remediation handoffs for confirmed diagnoses

This commit is contained in:
Nico committed 2026-10-15 19:15:25 +02:00
1 parent c1f44e4e02
commit a318faf3e6
18 files changed
+2177 -323

No files matched your search

+10 -7
View File
@@ -27,6 +27,9 @@ class RequestAdapter:
'forbidden_changes':['Unrelated database changes.'],'do_not_fix_by':['Disabling the interaction.'],
'validation_requirements':[{'description':'The reported interaction reaches the expected state; other interactions remain intact.','evidence_refs':[eid]}],
'missing_information':[],'reason':'A narrow implementation scope is available.'}
if 'human_dev' in request['output_schema']['required']:
p.update(placeholders=[],human_dev={'status':'none','title':'Kein Human-Dev-Auftrag vorhanden',
'reason':'The coding assignment has sufficient context.','instructions':[],'expected_results':[]})
if self.change:self.change(p,c)
return ProviderResponse(p,'fixture-change-request',100,50)
@@ -97,25 +100,25 @@ def test_invalid_reply_has_no_partial_task_or_debit(diagnosed,change):
assert r.manifest['artifacts']['change_request'] is None and r.manifest['state']==State.BUILDING_DIAGNOSIS
assert BudgetManager(store).snapshot(*CASE).state==before
def test_missing_context_and_invalid_limit_go_to_review(diagnosed):
def test_missing_remediation_data_goes_to_human_handoff(diagnosed):
store,_=diagnosed
def insufficient(p,c):p.update(status='insufficient_context',affected_scope=[],validation_requirements=[],missing_information=['Obtain the actual activation definition.'])
def insufficient(p,c):p.update(status='none',affected_scope=[],validation_requirements=[],implementation_guidance=[],missing_information=['Obtain the actual activation definition.'],human_dev={'status':'assigned','title':'Collect remediation data','reason':'Placement information is absent.','instructions':['Collect approved placement information.'],'expected_results':['Provide the collected information to the implementer.']})
adapter=RequestAdapter(insufficient);builder=ChangeRequestBuilder(store,gateway(adapter))
result=build(builder);assert result.status=='INCONCLUSIVE' and result.failure_ref
result=build(builder);assert result.status=='COMPLETED' and result.failure_ref is None
assert build(builder).reused and adapter.calls==1
exported=asyncio.run(OutputValidator(store,gateway(adapter)).publish(*CASE))
assert exported.status=='REVIEW' and exported.exported.parent==store.workspace.review
assert exported.status=='OUTPUT_READY' and exported.exported.parent==store.workspace.outbox
with PackageReader(exported.package) as r:
assert r.manifest['state']==State.FAILED_TO_ANALYZE and r.manifest['artifacts']['change_request'] is None
assert r.manifest['state']==State.OUTPUT_READY and r.manifest['artifacts']['change_request']
assert json.loads(r.read_bytes(r.manifest['artifacts']['diagnosis']))['diagnosis']['status']=='confirmed'
def test_invalid_limit_fallback_and_replay(diagnosed):
store,_=diagnosed;adapter=RequestAdapter(lambda p,c:p.update(affected_scope=[]))
builder=ChangeRequestBuilder(store,gateway(adapter),ChangeRequestConfig(2))
assert build(builder).status=='REJECTED'
result=build(builder);assert result.status=='INCONCLUSIVE' and adapter.calls==2
result=build(builder);assert result.status=='COMPLETED' and adapter.calls==2
assert build(ChangeRequestBuilder(store,gateway(adapter))).reused and adapter.calls==2
assert asyncio.run(OutputValidator(store,gateway(adapter)).publish(*CASE)).status=='REVIEW'
assert asyncio.run(OutputValidator(store,gateway(adapter)).publish(*CASE)).status=='OUTPUT_READY'
def test_inconclusive_diagnosis_never_creates_coding_request(tool_case):
store=tool_case[0];asyncio.run(Investigator(store,gateway(LoopAdapter())).run(*CASE,max_steps=20))