fix(intelligent-eval): reject report until all sessions closed
All checks were successful
CI / test (push) Successful in 3m59s
All checks were successful
CI / test (push) Successful in 3m59s
t480 实测:评估 completed 但 completed_sessions=0(进度 0%)。根因 (diagnosing-bugs):submit_report 无条件 CAS executing→completed,不看会话 状态——worker 建会话未 close 时,analyst 仍可提交报告把评估标完成。 - lifecycle.submit_report 加校验:存在会话时须全部 close(completed), 否则抛 IntelligentEvalTransitionError(409)——杜绝'评估完成但进度 0%' - 无会话的评估仍可直接提交(analyst 正常路径不变) 回归测试(诊断闭环 Phase 1 反馈环先红后绿): - +test_submit_report_rejects_when_sessions_not_closed(running 会话→409) - +test_submit_report_allows_when_sessions_closed(全 close→200) 900 passed
This commit is contained in:
parent
8959e7ac42
commit
56d709c44f
@ -197,9 +197,15 @@ def cancel(session: Session, eval_id: str) -> IntelligentEval:
|
|||||||
def submit_report(session: Session, eval_id: str, report: dict[str, Any]) -> IntelligentEval:
|
def submit_report(session: Session, eval_id: str, report: dict[str, Any]) -> IntelligentEval:
|
||||||
"""OpenClaw 提交结构化报告:executing → completed。
|
"""OpenClaw 提交结构化报告:executing → completed。
|
||||||
|
|
||||||
报告结构校验在路由层(pydantic),此处只负责落库与状态迁移。
|
报告结构校验在路由层(pydantic),此处只负责落库与状态迁移。提交前必须
|
||||||
|
满足:存在会话时须全部 close(completed)——否则拒绝,杜绝"评估 completed
|
||||||
|
但 completed_sessions=0(进度 0%)"的不一致(worker 建会话未 close 时,
|
||||||
|
analyst 不应提前把评估标完成)。
|
||||||
"""
|
"""
|
||||||
repo = IntelligentEvalRepository(session)
|
repo = IntelligentEvalRepository(session)
|
||||||
|
sessions = IntelligentEvalSessionRepository(session).list_by_eval(eval_id)
|
||||||
|
if sessions and any(s.status != IntelligentEvalSessionStatus.COMPLETED for s in sessions):
|
||||||
|
raise IntelligentEvalTransitionError("会话未全部关闭,不能提交报告")
|
||||||
result = repo._submit_report_if_executing(eval_id, report)
|
result = repo._submit_report_if_executing(eval_id, report)
|
||||||
return _resolve_write(
|
return _resolve_write(
|
||||||
eval_id,
|
eval_id,
|
||||||
|
|||||||
@ -537,6 +537,31 @@ class TestReport:
|
|||||||
resp = await client.get(f"/api/intelligent-evals/{eval_id}/report")
|
resp = await client.get(f"/api/intelligent-evals/{eval_id}/report")
|
||||||
assert resp.status_code == 404
|
assert resp.status_code == 404
|
||||||
|
|
||||||
|
async def test_submit_report_rejects_when_sessions_not_closed(self, client, seeded_db):
|
||||||
|
"""评估不应在会话未全部 close 时被标 completed(否则进度 0% 但状态完成)。
|
||||||
|
|
||||||
|
复现 t480 真实问题:worker 建会话但未 close,analyst 仍提交报告 →
|
||||||
|
submit_report 无条件 executing→completed,completed_sessions=0。
|
||||||
|
"""
|
||||||
|
eval_id = await _create_executing_eval(client)
|
||||||
|
await _create_session(client, eval_id) # 建 1 个 running 会话,不 close
|
||||||
|
resp = await client.put(f"/api/intelligent-evals/{eval_id}/report", json={"report": _report_payload()})
|
||||||
|
# 会话未全部 close → 应拒绝(409),而非 200 直接 completed
|
||||||
|
assert resp.status_code == 409, resp.text
|
||||||
|
|
||||||
|
async def test_submit_report_allows_when_sessions_closed(self, client, seeded_db):
|
||||||
|
"""会话全部 close 后提交报告应成功(正常 analyst 路径不被破坏)。"""
|
||||||
|
eval_id = await _create_executing_eval(client)
|
||||||
|
session = await _create_session(client, eval_id)
|
||||||
|
resp = await client.post(
|
||||||
|
f"/api/intelligent-evals/{eval_id}/sessions/{session['id']}/close",
|
||||||
|
json={"verdict": {"goal_achieved": True, "summary": "完成", "severity": "low"}},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200, resp.text
|
||||||
|
resp = await client.put(f"/api/intelligent-evals/{eval_id}/report", json={"report": _report_payload()})
|
||||||
|
assert resp.status_code == 200, resp.text
|
||||||
|
assert resp.json()["status"] == "completed"
|
||||||
|
|
||||||
async def test_markdown_before_submission_returns_404(self, client, seeded_db):
|
async def test_markdown_before_submission_returns_404(self, client, seeded_db):
|
||||||
eval_id = await _create_executing_eval(client)
|
eval_id = await _create_executing_eval(client)
|
||||||
resp = await client.get(f"/api/intelligent-evals/{eval_id}/report/markdown")
|
resp = await client.get(f"/api/intelligent-evals/{eval_id}/report/markdown")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user