-
route_org_loop(): fast_lane -> coding/coder, full_replan -> planning_brd_prd_sdd/planner, loop_round += 1, writes an execution_event(event_type=loop_routed) recording the decision. loop_round >= 3 forces blocked_pending_human (blocked_reason= 'loop_limit_reached') and raises LoopLimitReachedError instead of routing (03-C §3.11: "不接受常规路由请求,只接受 manual_resume"). manual_resume walks execution_event's task_status_changed history backwards to find what status preceded the most recent transition into blocked_pending_human, and restores it -- 04-P says "恢复到触发前状态" but task has no previous_status column, so this reconstructs it from the event log already being written everywhere in this codebase, rather than adding a new column for a value that's already reconstructable. Also built close_task_done() (validating->done, validator_pass): 04-P names this transition but not a controller for it, and nothing in this codebase had ever set task.status='done' before this commit -- REQ-05's happy case ends there, so it had to exist for that to be reachable. Documented as a deliberate scope extension, not silently assumed. Simplification, noted rather than silently collapsed: 04-P models fast_lane/full_replan as two hops (validating -> routed_fast_lane -> coding) but c_org_loop_route's own 03-C contract returns the final state directly and no controller owns the second hop -- implemented as one atomic transition, with the route decision preserved via the loop_routed event instead of a persisted intermediate status. Neither REQ-05 nor REQ-09 check for that literal intermediate state. 11 new stdlib unittest cases, all real (sqlite is fast/free/local, no mocking needed). 157 total across U-001-016, all passing. This closes PH2-S1 (U-015 + U-016): REQ-04, REQ-05, and REQ-09 are now all real code, not just planned. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>