fix: QC竞态双守卫——start_qc已通过不开新轮/空产出不烧轮+对账器维度任务在办不派审核(实测qualifications被烧3轮、cost_benefit对空表打0)

This commit is contained in:
yumoqing 2026-09-02 19:12:33 +08:00
parent ab32686211
commit 6c4aaa79a2
2 changed files with 33 additions and 0 deletions

View File

@ -557,6 +557,13 @@ async def reconcile_project(sor, project_id, project_name=""):
for t, _, _, _ in needs_qc:
if await _open_qc_type_tasks(sor, project_id, t) > 0:
continue
# 竞态守卫2026-09-02该维度分析/重做任务在办 → 不派审核。
# 根治产出被清空后重做任务还在跑QC 审核就先派出去对着重写中
# 的半成品打分(实测 cost_benefit 对空表打 0、qualifications 被连烧两轮)。
dim = QC_TYPE_TO_DIM.get(t, "")
if dim and await _open_dim_tasks(sor, project_id, dim) > 0:
acts.append("waiting: 维度「%s」分析任务在办,暂不派 %s 审核" % (dim, t))
continue
tid = await create_role_task(
sor, project_id, R_QC,
"%s 解析产出契合度审核(%s" % (pname, t),

View File

@ -119,6 +119,32 @@ async def start_qc(qc_type, project_id="", who=None, agent_id=None, task_id=""):
"AND fit_score IS NULL ORDER BY created_at DESC LIMIT 1",
{"p": project_id, "t": qc_type})
await sor.sqlExe("COMMIT", {})
# 已通过守卫2026-09-02最新一轮已放行 → 不再开新轮。
# 根治:任务被引擎通用门禁弹回重跑时再次 start_qc 会白白烧掉一轮
# qualifications 实测第2轮8.80已过弹回重跑开第3轮对重写中的表打5.6)。
# 产出若被 QC 清空重做,对账器只在重做完成后才重新派审核,此处不会误挡。
last_r = await sor.sqlExe(
"SELECT round, fit_score, passed FROM bid_qc_reviews WHERE project_id=${p}$ AND qc_type=${t}$ "
"ORDER BY round DESC LIMIT 1", {"p": project_id, "t": qc_type})
await sor.sqlExe("COMMIT", {})
if last_r and not open_r and str(rec_to_dict(last_r[0]).get("passed")) == "1":
_lr = rec_to_dict(last_r[0])
return True, {"status": "already_passed", "qc_type": qc_type,
"round": _lr.get("round"), "fit_score": _lr.get("fit_score"),
"message": "该类型第 %s 轮已通过契合度审核(%.2f 分 > 通过分),无需重审。"
"直接完成任务即可。" % (_lr.get("round"), to_float(_lr.get("fit_score")))}
# 空产出守卫2026-09-02产出被 QC 清空、重做未完成 → 不开新轮。
# 根治QC 审核任务比分析重做任务先跑时对着空表开轮打 0 分,白白烧一轮
# cost_benefit 实测第2轮对着零记录表打 0.00)。
_cnt = await sor.sqlExe(
"SELECT COUNT(*) AS c FROM " + QC_OUTPUT_TABLE[qc_type] + " WHERE project_id=${p}$",
{"p": project_id})
await sor.sqlExe("COMMIT", {})
if not open_r and to_int(getattr(_cnt[0], "c", 0) if _cnt else 0) == 0:
return True, {"status": "no_output", "qc_type": qc_type,
"message": "%s 当前无产出记录(被 QC 清空待重做或重做未完成),"
"不开评审轮次。请等待分析重做任务落库后再审,"
"本轮任务直接交付说明等待原因即可。" % qc_type}
if open_r:
rid = getattr(open_r[0], "id", "")
rnd = to_int(getattr(open_r[0], "round", 1), 1)