11"""Current canonical waits constrain historical supervision, not vice versa."""
22from copy import deepcopy
3+ import pytest
34
45from loopx .control_plane .handoff .delivery_contract import handoff_delivery_contract
56from loopx .control_plane .testing .quota_fixtures import quota_status_payload , quota_todo_item , quota_todo_summary
67from loopx .control_plane .work_items .delivery_history import project_delivery_response
8+ from loopx .control_plane .todos .summary_item import TODO_PLANNING_SOURCE_KEYS
9+ from loopx .control_plane .todos .resume_condition import evaluate_todo_resume_conditions
710from loopx .control_plane .work_items .work_lane_context import build_work_lane_context_contract
811from loopx .quota import build_quota_should_run , quota_with_handoff_outcome_floor
912from loopx .status import project_post_handoff_history
@@ -23,14 +26,41 @@ def waiting_todo():
2326 return quota_todo_item (todo_id = "todo_delivery" , title = "Wait for the dependency" , status = "deferred" ,
2427 claimed_by = "agent-a" , resume_when = "todo_done:todo_dependency" , resume_ready = False ,
2528 resume_condition = {"schema_version" : "todo_resume_condition_v0" , "resume_when" : "todo_done:todo_dependency" ,
26- "satisfied" : False , "kind" : "todo_done" , "target_status" : "open" ,
29+ "satisfied" : False , "kind" : "todo_done" , "target_todo_id" : "todo_dependency" , " target_status" : "open" ,
2730 "target_task_class" : "advancement_task" , "target_archive_state" : "active" })
2831
2932
3033def dependency_todo ():
3134 return quota_todo_item (todo_id = "todo_dependency" , title = "Complete prerequisite" , claimed_by = "agent-b" )
3235
3336
37+ @pytest .mark .parametrize ("patch" , [
38+ {"target_todo_id" : "todo_other" }, {"target_todo_id" : None },
39+ {"target_task_class" : "unknown_class" }, {"target_task_class" : "" },
40+ {"kind" : "monitor_changed" },
41+ ])
42+ def test_stale_or_malformed_target_cannot_suppress_any_consumer (patch ):
43+ todo = waiting_todo ()
44+ extra = quota_todo_item (todo_id = "todo_alternative" , title = "Continue independent work" , claimed_by = "agent-a" )
45+ summary = quota_todo_summary ([todo , dependency_todo (), extra ], claim_scope_agent_id = "agent-a" )
46+ # Mutate the evaluated snapshot, not the authoring input: summary building
47+ # legitimately recomputes supplied conditions from its canonical source.
48+ for key in TODO_PLANNING_SOURCE_KEYS :
49+ for row in summary .get (key , []):
50+ if row ["todo_id" ] == "todo_delivery" :
51+ row ["resume_condition" ].update (patch )
52+ readiness = project_post_handoff_history ([blocked_run ()] * 3 , PROFILE )
53+ asset = {"execution_profile" : PROFILE , "agent_todos" : summary }
54+ item = {"handoff_readiness" : readiness , "agent_todos" : summary , "project_asset" : asset }
55+ before = deepcopy (item )
56+ assert project_delivery_response (blocked_run (), summary )["reason" ] == "history_supervision"
57+ assert quota_with_handoff_outcome_floor ({"state" : "eligible" }, waiting_on = "codex" ,
58+ project_asset = asset , handoff_readiness = readiness )["state" ] == "focus_wait"
59+ assert handoff_delivery_contract (item ) is not None
60+ assert build_work_lane_context_contract (item , agent_todo_summary = summary )["must_attempt_work" ] is True
61+ assert item == before
62+
63+
3464def test_status_compaction_preserves_binding_and_all_consumers_defer_to_current_wait ():
3565 readiness = project_post_handoff_history ([blocked_run ()] * 3 , PROFILE )
3666 summary = quota_todo_summary ([waiting_todo (), dependency_todo ()], claim_scope_agent_id = "agent-a" )
@@ -55,6 +85,26 @@ def test_status_compaction_preserves_binding_and_all_consumers_defer_to_current_
5585 assert "outcome_followthrough" not in lane
5686
5787
88+ @pytest .mark .parametrize ("resume, patch" , [
89+ ("monitor_changed:todo_dependency" , {"baseline_generation" : 1 }),
90+ ("capacity_available:network" , {"capability" : "other" }),
91+ ("pr_merged:#1" , {"pr_number" : 2 }),
92+ ])
93+ def test_real_resume_projection_identity_survives_python_transport (resume , patch ):
94+ todo = {** waiting_todo (), "resume_when" : resume , "resume_monitor_generation" : 0 ,
95+ "task_repository" : "git:github.com/example/project" }
96+ dependency = {** dependency_todo (), "task_class" : "continuous_monitor" , "material_change_generation" : 0 }
97+ condition = evaluate_todo_resume_conditions ([todo ], source_items = [dependency ], available_capabilities = [])[todo ["todo_id" ]]
98+ summary = quota_todo_summary ([todo , dependency ], claim_scope_agent_id = "agent-a" )
99+ for key in TODO_PLANNING_SOURCE_KEYS :
100+ for row in summary .get (key , []):
101+ if row ["todo_id" ] == todo ["todo_id" ]:
102+ row ["resume_condition" ] = condition
103+ assert project_delivery_response (blocked_run (), summary )["reason" ] == "canonical_todo_wait"
104+ condition .update (patch )
105+ assert project_delivery_response (blocked_run (), summary )["reason" ] == "history_supervision"
106+
107+
58108def test_surface_supervision_remains_and_invalid_wait_does_not_clear_floor ():
59109 summary = quota_todo_summary ([waiting_todo ()], claim_scope_agent_id = "agent-a" )
60110 asset = {"execution_profile" : PROFILE , "agent_todos" : summary }
0 commit comments