# 新 Goal 自动派发——需求文档 **日期**: 2026-08-06 **性质**: 需求文档(BRD/PRD 层面),不含详细技术设计。**2026-08-08 拆分**:原文档 `docs/todo/scheduler-production-polling-loop-requirements.md`(FR-1/FR-2 合并)已按完成状态拆分—— FR-2(在途任务复原)已实现,移入 `docs/done/scheduler-task-reconciliation-requirements.md`/ `-design.md`;本文档只保留仍是草案的 FR-1。 **状态**: ✅ 已实施(2026-08-13)。"要不要做"这个曾经被单独搁置的自主权边界决策,已由用户明确拍板:完整开放,常驻轮询、自动派发。 ## 1. 背景 `run_scheduler_once(db_path, goals, max_workers=None)` 的入参 `goals` 是 `[(target_folder_path, goal_text), ...]`,语义是"这一轮要**新建**并跑完这些 Goal",内部通过 `task_create.create_task()` 每次都新建一个 `task` 行。这个函数存在且经过测试,但从未被任何常驻进程接入——`queued` 状态的新 Goal(还没被任何调用触发过 `run_goal_to_completion`)目前只能靠人工手动点击控制台的 Start 按钮 执行,不会被自动拿去跑。 跟"在途任务复原"(`docs/done/scheduler-task-reconciliation-requirements.md`,已实现)是两个独立 问题:那个是"已经开始执行的任务卡住了怎么自动接回去",这个是"还没开始执行的新 Goal 怎么自动开始"。 ## 2. 目标 `queued` 状态的任务(或者说,还没被任何调用触发过 `run_goal_to_completion`/ `run_or_resume_task_lifecycle` 的新 Goal)需要被自动拿去执行,不需要人工每次手动点 Start。 ## 3. 非目标 1. **不在本文档里裁定"要不要做""什么时候做"这个更大的问题**。是否现在就投入、要不要额外的 人工评审门槛,是需要单独确认的决策,本文档只负责把需求本身讲清楚,供决策时参考。 2. **不要求解决方案是常驻进程/独立进程/`backend_server.py` 内置线程三选一中的哪一个**。具体载体 形式留给设计阶段。 3. **不重新设计 `run_scheduler_once` 本身**。它的行为已经是对的,本需求要解决的是"谁、在什么 时机去调用它"这一层。 ## 4. 功能需求 | # | 需求描述 | 优先级 | |---|---|---| | FR-1 | 需要一个机制,定期(具体周期留待设计阶段)调用 `scheduler.run_scheduler_once()` 派发新 Goal。 | 必须 | ## 5. 验收标准 新建一个 `queued` 状态的 Goal,不手动点 Start,验证机制能在设定周期内自动派发执行。 ## 6. 风险 **这是改变系统自主权边界的决策**——意味着系统会在没有人显式点击"Start"的情况下自主开始消耗 真实 API 调用、真实修改代码。这条风险不因为实现简单而减轻,需要在决策阶段被认真对待。 ## 7. 开放问题——✅ 全部回答(2026-08-13 实施落地) - [x] 轮询周期:45 秒(`--new-goal-dispatch-interval-seconds`,默认值),刻意比"在途任务复原"的 300 秒短,满足"接近实时派发"的验收要求。 - [x] 载体形式:`backend_server.py::main()` 内置后台 daemon 线程(`_start_new_goal_dispatch_loop`), 跟"在途任务复原"同款,不是独立进程。 - [x] 暴露成可配置项:`--new-goal-dispatch-interval-seconds`/`--disable-new-goal-dispatch-loop` 两 个 CLI flag,命名风格照抄已实现的 `--reconciliation-interval-seconds`/`--disable-reconciliation-loop`。 - [x] 跟在途任务复原循环保持独立,不合并成一个"万能调度循环"——新写了独立模块 `src/new_goal_dispatch.py`(`find_queued_tasks()`/`dispatch_once()`),不改 `task_reconciliation.py`。 同时给 `supervisor/deploy_stage.py::_launch_candidate()` 补上了跟 `--disable-reconciliation-loop` 同款的联动 flag,防止候选进程用生产库拷贝在健康检查完成前就自主派发真实 Goal。 ## 8. 实施summary 新模块 `src/new_goal_dispatch.py`(找 `task.status = 'queued'` 的行,逐个 `task_execution. start_task_execution_in_background`,单个候选派发失败不影响其余候选)+ `src/test_new_goal_dispatch.py`; `backend_server.py`/`test_backend_server.py` 的 CLI 接线;`supervisor/deploy_stage.py`/ `supervisor/test_deploy_stage.py` 的候选进程联动。`discover -s src`(797 tests)+ `discover -s supervisor`(127 tests)全绿。