修复: 闭合正文候选丢弃与交接合同
This commit is contained in:
parent
efb2b3e781
commit
de0f870b96
@ -299,11 +299,27 @@ def check_writer_acceptance(
|
||||
if confirmed is not True:
|
||||
raise AcceptanceError("CONFIRMATION_REQUIRED", f"{decision} 必须由用户明确确认")
|
||||
if decision == "discard":
|
||||
try:
|
||||
normalized_context = validate_writer_context(context)
|
||||
except ContractError as exc:
|
||||
raise AcceptanceError("CONTEXT_CONTRACT_INVALID", str(exc)) from exc
|
||||
try:
|
||||
normalized_candidate = validate_writer_output(candidate)
|
||||
except ContractError as exc:
|
||||
raise AcceptanceError("CANDIDATE_CONTRACT_INVALID", str(exc)) from exc
|
||||
_validate_context_binding(normalized_context, normalized_candidate)
|
||||
return {
|
||||
"schemaVersion": "writer-acceptance-result-v1",
|
||||
"status": "DISCARD_INTENT_READY",
|
||||
"decision": decision,
|
||||
"commandIntent": None,
|
||||
"runId": normalized_candidate["runId"],
|
||||
"candidateVersion": normalized_candidate["candidateVersion"],
|
||||
"candidateSha256": normalized_candidate["candidateSha256"],
|
||||
"commandIntent": {
|
||||
"command": "close_shadow_candidate",
|
||||
"expectedCandidateVersion": normalized_candidate["candidateVersion"],
|
||||
"expectedCandidateSha256": normalized_candidate["candidateSha256"],
|
||||
},
|
||||
"canonicalMutationPerformed": False,
|
||||
}
|
||||
shadow = check_shadow_ready(
|
||||
|
||||
@ -269,7 +269,7 @@ def _terminal_result(
|
||||
) -> dict[str, Any]:
|
||||
"""生成可原子落盘的稳定终态结果。"""
|
||||
|
||||
return {
|
||||
result = {
|
||||
"schemaVersion": "writer-pipeline-result-v1",
|
||||
"runId": run_id,
|
||||
"status": status,
|
||||
@ -281,6 +281,10 @@ def _terminal_result(
|
||||
"rewriteCount": rewrite_count,
|
||||
"trace": [dict(item) for item in trace],
|
||||
}
|
||||
# 只有通过全部合同和审查门的终态才暴露可进入 Shadow 的最终候选。
|
||||
if status == "PASSED" and candidate is not None:
|
||||
result["candidateArtifact"] = dict(candidate)
|
||||
return result
|
||||
|
||||
|
||||
def _publish_if_requested(
|
||||
@ -625,6 +629,9 @@ def run_writer_pipeline(
|
||||
"mechanicalPassed": mechanical_report.get("passed", False),
|
||||
"semanticStatus": semantic_report.get("status") if semantic_report else "not_run",
|
||||
"failureCodes": [item.get("code") for item in candidate_failures],
|
||||
# 保留接受层审计所需的原始报告;摘要字段仍供稳定绑定检查使用。
|
||||
"mechanicalReport": dict(mechanical_report),
|
||||
"semanticReport": dict(semantic_report) if semantic_report else None,
|
||||
}
|
||||
)
|
||||
if not candidate_failures:
|
||||
|
||||
@ -95,6 +95,7 @@ class RunWriterPipelineTest(unittest.TestCase):
|
||||
self.assertEqual(store.latest(context["runId"]).state, "REJECTED")
|
||||
self.assertEqual(raised.exception.result["status"], "REJECTED")
|
||||
self.assertEqual(raised.exception.result["failureCode"], expected_code)
|
||||
self.assertNotIn("candidateArtifact", raised.exception.result)
|
||||
self.assertEqual(
|
||||
json.loads(result_path.read_text(encoding="utf-8")),
|
||||
raised.exception.result,
|
||||
@ -442,6 +443,11 @@ class RunWriterPipelineTest(unittest.TestCase):
|
||||
)
|
||||
|
||||
self.assertEqual(result["status"], "PASSED")
|
||||
self.assertEqual(result["candidateArtifact"]["candidateVersion"], 2)
|
||||
self.assertEqual(
|
||||
result["candidateArtifact"]["candidateSha256"],
|
||||
result["candidateSha256"],
|
||||
)
|
||||
self.assertEqual(result["evidenceRequestCount"], 1)
|
||||
self.assertEqual(result["rewriteCount"], 1)
|
||||
self.assertEqual(calls, [(1, 1), (2, 2)])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user