-
Users had no way to actually start a queued goal from the console -- task.status just sits at 'queued' forever. Traced the root cause through 03-C: c_task_create's own contract ("若 max_concurrent_goals 已达上限, 任务落 queued 但不触发调度") implies task creation auto-triggers scheduling otherwise, and 03-C/04-P repeatedly assume an always-on Org Graph scheduler that watches the queue -- src/scheduler.py builds the mechanism but nothing ever spins it up as a running process, so no "start" button was ever designed because none was supposed to be needed. Design (confirmed with user, both recommended options chosen): - Pause/Stop are a soft stop, not a real subprocess kill -- the current in-flight `claude` call finishes naturally, only the next phase is withheld. Hard-killing would need Popen + PID tracking, out of scope. - No new task.status enum value -- reuses blocked_pending_human with blocked_reason='user_paused'/'user_stopped', riding the existing manual_resume mechanism instead of a schema change. New src/task_execution.py: run_or_resume_task_lifecycle() resumes from whichever phase actually hasn't run yet (queued/planning_brd_prd_sdd/ coding), start_task_execution_in_background() runs it to completion on its own daemon thread + sqlite connection, request_pause() blocks an in-flight task. Extended /route's manual_resume handling so resuming from a user-initiated pause/stop actually re-continues execution in the background, not just flips the status field back. Real gap found while building this: backend_server.create_server() never stored db_path on the server object -- needed for the new background thread to open its own connection to the same db. 22 new tests (14 src/test_task_execution.py + 8 TaskExecutionRouteTest in test_backend_server.py, HTTP wiring mocked around the already-unit-tested background thread mechanics). Verified against a real running server via curl: /execute 409s a non-queued task, /pause 409s a queued task and a double-pause, succeeds on a coding task. src/ suite: 496 tests, all green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>