muse-agent-example/tests/契约/test_返修比较证明合同.py
zizi 9e6f1c4481 R2 改造交付:新版模块化单体全量成果
- src/muse 新版全模块(装配/共享/上下文/任务运行/作品规划/故事世界/正文写作/审校修订/知识方法/作者经验/效果评测/交付连载/资料研究/正式变更/元数据/接入/基础设施/编排)+ 测试树(单元/契约/集成/架构/迁移/端到端/夹具)
- 129 项功能全部实现与自动验证(功能覆盖.json/矩阵),含 W31 补齐的规则与代价/节奏安排/伏笔与承诺
- 旧实现按处置清单退出(702 条中 324 删,保护合同与未迁移条目留存有据);web/app.py 旧工作台退役,新工作台为唯一写入口
- 数据库/旧库迁移:真实旧库内容批次迁移链(端点守卫/PG作品正文映射/质量资产缺省投影)
- 运行手册 docs/运行手册.md;W30 本机服务阶段一已运行(infra PG 为正式内容权威)
- R2 执行证据与私有运行材料在 .agents.local/改造/R2-20260909/(不入库)
2026-09-15 12:47:42 +08:00

189 lines
6.4 KiB
Python

"""返修比较只接受类型化来源与双评委证据;自报字段不能构成证明。"""
from copy import deepcopy
from uuid import uuid4
import pytest
from pydantic import ValidationError
from muse.审校修订.接口 import 解析返修比较来源, 返修比较来源, 返修比较证明
from muse.正式变更.接口 import 固定哈希
哈希 = "0" * 64
def _来源():
value = {
"version": "revision-comparison-source-v1",
"author_id": "author",
"session_id": str(uuid4()),
"round": 1,
"target": {
"work_id": "work",
"chapter_id": "chapter",
"branch_id": "main",
"original_revision": 1,
"original_document_hash": 哈希,
},
"diagnosis": {
"diagnosis_id": str(uuid4()),
"diagnosis_hash": 哈希,
"authorization_hash": 哈希,
"basis_hash": 哈希,
},
"original": {"revision": 1, "document_hash": 哈希, "text_hash": 哈希},
"candidate": {
"candidate_id": str(uuid4()),
"revision": 1,
"candidate_hash": 哈希,
"document_hash": 哈希,
"text_hash": 哈希,
},
"delivery": {
"task_id": str(uuid4()),
"attempt_id": str(uuid4()),
"call_id": "revision-call",
"output_hash": 哈希,
"model": "writer-model",
"provider": "provider",
"thinking": "high",
"config_id": "writer-config",
"config_version": "1",
"config_hash": 哈希,
"role_policy": "role-policy-v1",
"resource_release": "release-v1",
"host": "direct",
"host_version": "1",
"pricing_version": "price-v1",
"budget_account": "budget",
"dispatch_hash": 哈希,
"validation_mode": "runtime",
"validation_receipt_id": str(uuid4()),
},
"invariance": {
"mechanical_pass": True,
"checks_hash": 哈希,
"report_id": str(uuid4()),
"report_hash": 哈希,
"verdict": "passed",
},
}
value["source_hash"] = 固定哈希(value)
return value
def _证明():
decisions = [
{
"unit_id": str(uuid4()),
"task_id": str(uuid4()),
"call_id": f"judge-call-{index}",
"model": f"judge-model-{index}",
"config_hash": 哈希,
"role_policy": "role-policy-v1",
"resource_release": "release-v1",
"choice": "candidate",
"output_hash": 哈希,
"judgment_hash": 哈希,
}
for index in (1, 2)
]
return {
"version": "revision-comparison-proof-v1",
"consumer": "B06.fixed_revision_pair_v1",
"author_id": "author",
"experiment_id": str(uuid4()),
"source": _来源(),
"conditions_hash": 哈希,
"dataset_hash": 哈希,
"plan_hash": 哈希,
"report_hash": 哈希,
"outcome": "candidate",
"comparison_complete": True,
"selection": "candidate",
"reasons": ("uncalibrated_pairwise_preference",),
"decisions": decisions,
"validation_modes": ("runtime",),
"calibration_status": "uncalibrated",
"activation_status": "not_evaluated",
"automatic_adoption": False,
}
def _选段来源():
value = _来源()
value.pop("source_hash")
value.pop("diagnosis")
value.update(
version="revision-comparison-source-v2",
selection_authorization={
"authorization_hash": 哈希,
"basis_hash": 哈希,
"mode": "rewrite",
"purpose_hash": 哈希,
"selection_ids": ["1" * 64],
"selections_hash": 哈希,
"protected_range_ids": ["2" * 64],
"protected_ranges_hash": 哈希,
},
)
value["source_hash"] = 固定哈希(value)
return value
def test_来源任一关联改变而未重算哈希即拒绝__239003():
value = _来源()
source = 返修比较来源.model_validate(value)
assert source.source_hash == value["source_hash"]
assert source.model_dump(mode="json") == value
for path in ("candidate", "diagnosis", "delivery", "target"):
changed = deepcopy(value)
key = next(iter(changed[path]))
changed[path][key] = "changed"
with pytest.raises(ValidationError):
返修比较来源.model_validate(changed)
def test_选段来源显式携带授权与保护区且不接受伪诊断__239008():
value = _选段来源()
source = 解析返修比较来源(value)
assert source.model_dump(mode="json") == value
assert source.selection_authorization.selection_ids == ("1" * 64,)
changed = deepcopy(value)
changed["diagnosis"] = _来源()["diagnosis"]
changed["source_hash"] = 固定哈希({k: v for k, v in changed.items() if k != "source_hash"})
with pytest.raises(ValidationError):
解析返修比较来源(changed)
proof = _证明()
proof.update(version="revision-comparison-proof-v2", source=value)
assert 返修比较证明.model_validate(proof).source.version.endswith("v2")
proof["version"] = "revision-comparison-proof-v1"
with pytest.raises(ValidationError, match="版本与来源类型"):
返修比较证明.model_validate(proof)
@pytest.mark.parametrize("claim", ["selection_model", "pairwise_choice"])
def test_自报模型或选择字段不能混入公共证明__239004(claim):
value = _证明()
proof = 返修比较证明.model_validate(value)
assert proof.outcome == "candidate"
assert 固定哈希(proof.model_dump(mode="json")) == 固定哈希(value)
value[claim] = "claimed-success"
with pytest.raises(ValidationError):
返修比较证明.model_validate(value)
@pytest.mark.parametrize("changed", ["one_judge", "same_model", "inconsistent_choice"])
def test_缺评委重复模型或结论不一致不能声称完整__239005(changed):
value = _证明()
assert 返修比较证明.model_validate(value).comparison_complete is True
if changed == "one_judge":
value["decisions"] = value["decisions"][:1]
elif changed == "same_model":
value["decisions"][1]["model"] = value["decisions"][0]["model"]
else:
value["outcome"] = "original"
with pytest.raises(ValidationError):
返修比较证明.model_validate(value)