fix: paused 生命周期三处修复——切迭代自动 resume + 三 poller 统一排除 paused

1. start_next_iteration 启动新迭代后自动 resume_project:旧迭代遗留的 paused
   (任务达上限触发 failed_poller 自动 pause)随任务作废消除,新迭代恢复 active,
   否则 PM poller 跳过 review 任务导致新迭代卡在 PM 审核(2026-08 实测卡 27 分钟)
2. agent poller / qc poller 也排除 paused 项目,与 PM poller 语义统一:
   paused = 完全暂停推进(不派发/不审查/不审核),消除「任务照常派发却卡审核」半吊子状态
This commit is contained in:
ymq 2026-08-22 17:39:13 +08:00
parent ea6df9c7c6
commit 191d28547b
2 changed files with 18 additions and 6 deletions

View File

@ -640,10 +640,14 @@ def load_pipeline_service():
return []
# 候选任务(含 depends_onLIMIT 放大以容纳「依赖未满足排在前面」的僵尸任务)
# 排除 paused 项目paused = 完全暂停推进(不派发/不审查/不审核),三个 poller 语义统一,
# 否则会出现「任务照常派发执行、却卡在 PM 审核」的半吊子状态2026-08 实测)。
recs = await sor.sqlExe(
"SELECT id, tenant_id, role, depends_on FROM pipeline_tasks "
"WHERE state='submitted' AND pipeline_id='role_task' "
"AND claimed_by IS NULL ORDER BY created_at ASC LIMIT 200",
"SELECT t.id, t.tenant_id, t.role, t.depends_on FROM pipeline_tasks t "
"WHERE t.state='submitted' AND t.pipeline_id='role_task' "
"AND t.claimed_by IS NULL "
"AND NOT EXISTS (SELECT 1 FROM sd_projects p WHERE p.id=t.tenant_id AND p.status='paused') "
"ORDER BY t.created_at ASC LIMIT 200",
{})
# 依赖门控提前到候选筛选:批量查 depends_on 里所有依赖任务的状态,
@ -814,9 +818,10 @@ def load_pipeline_service():
"WHERE state='qc_review' AND claimed_by IS NOT NULL "
"AND updated_at < (NOW() - INTERVAL 20 MINUTE)", {})
recs = await sor.sqlExe(
"SELECT id, tenant_id, role FROM pipeline_tasks "
"WHERE state='qc_review' AND claimed_by IS NULL "
"ORDER BY created_at ASC LIMIT 5",
"SELECT t.id, t.tenant_id, t.role FROM pipeline_tasks t "
"WHERE t.state='qc_review' AND t.claimed_by IS NULL "
"AND NOT EXISTS (SELECT 1 FROM sd_projects p WHERE p.id=t.tenant_id AND p.status='paused') "
"ORDER BY t.created_at ASC LIMIT 5",
{})
for rec in (recs or []):
tid = getattr(rec, 'id', '')

View File

@ -264,6 +264,13 @@ async def start_next_iteration(project_id, who=None, agent_id=None, confirm=Fals
from_state=S_PLANNING, to_state=S_IN_PROGRESS,
who=_normalize_role(who), agent_id=agent_id, sor=sor)
logger.info("start_next_iteration: 启动 %s (seq_no=%s)", nxt_name, nxt_seq)
# 切迭代后自动恢复项目推进:旧迭代的 paused任务达上限触发 failed_poller 自动 pause诱因
# 已随活跃任务作废而消除,新迭代是新开始,项目应恢复 active——否则 PM poller 会因 paused
# 跳过新迭代的 review 任务,导致新迭代卡在 PM 审核无人认领2026-08 实测:切迭代后 design
# 任务卡 review 27 分钟,根因就是旧迭代遗留的 paused 未清除)。
from .project_capability import resume_project
_rok, _rmsg = await resume_project(project_id, who=_normalize_role(who), agent_id=agent_id)
logger.info("start_next_iteration: resume_project ok=%s (%s)", _rok, _rmsg)
return True, f"已启动迭代「{nxt_name}」(seq_no={nxt_seq})"