muse-agent-example/tests/单元/test_上下文任务范围形状.py
zizi d909d1bd1b 后端实现与用例身份:19 包集成落地并修复收尾缺陷
实现侧:
- 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。
- 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。
- 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。
- 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。
- 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。
- 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。
- 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。
- 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。

用例侧:
- 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存;
- 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
2026-09-18 01:15:00 +08:00

187 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""任务范围新节(目标章细纲、事实系统版本与用途绑定)的离线形状校验。
只测恢复冻结范围对冻结输入的判定:形状与身份不一致必须失败关闭,
不连数据库、不调用模型。
"""
import pytest
from muse.上下文.接口 import 上下文服务, 上下文错误
from muse.任务运行.模型 import 任务快照, 任务状态, 执行计划
from muse.共享.调用身份 import 用途
from muse.基础设施.数据库.连接 import 数据库工厂
from muse.配置 import 数据库引用
def 服务() -> 上下文服务:
工厂 = 数据库工厂(数据库引用("环境变量", "MUSE_TEST_DATABASE_URL"), 用途.生产)
return 上下文服务(工厂, None)
def 快照(范围: dict) -> 任务快照:
return 任务快照(
"task-shape",
任务状态.待运行,
"ctx-author",
"hash",
{
"作品ID": 范围["work_id"],
"执行用途": "production",
"内容用途": "generation",
"冻结上下文": {"source_scope": 范围},
},
执行计划("shape-flow", "1", ()),
(),
0,
)
def 文稿(编号: str) -> dict:
return {
"chapter_id": 编号,
"branch_id": "main",
"revision": 1,
"document_id": "doc-" + 编号,
"document_hash": "hash-" + 编号,
"position": 1,
}
def 任务范围() -> dict:
"""含历史文稿、目标章细纲与事实系统版本的完整任务范围。"""
return {
"work_id": "ctx-work",
"as_of": 2,
"source_ids": ["doc-ch-1", "plan-target", "obj-fact"],
"documents": [文稿("ch-1")],
"directory_revision": 3,
"authorized_by": "ctx-author",
"run_purpose": "production",
"content_purpose": "generation",
"target_plan": {
"chapter_id": "ch-3",
"plan_id": "plan-target",
"revision": 1,
"content_hash": "plan-hash",
},
"facts": {"system_revision": 2},
}
@pytest.mark.case_id(
"NC-ctx-scope-restore-full",
environment="离线纯函数",
given="含历史文稿、目标章细纲、事实系统版本与两种用途绑定的冻结任务范围",
when="从任务快照恢复冻结范围",
then=["范围形状、来源清单与用途绑定全部通过时原样返回"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
def test_完整任务范围原样恢复__d1a2f3() -> None:
范围 = 任务范围()
assert 服务().恢复冻结范围(快照(范围)) == 范围
@pytest.mark.case_id(
"NC-ctx-scope-restore-no-documents",
environment="离线纯函数",
given="没有历史文稿但冻结了目标章细纲与事实系统版本",
when="从任务快照恢复冻结范围",
then=["documents 为空不单独拒绝;空文稿且无细纲无事实才失败"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
def test_无历史文稿但绑定细纲与事实仍可恢复__e4b5c6() -> None:
范围 = {**任务范围(), "documents": [], "source_ids": ["plan-target", "obj-fact"]}
assert 服务().恢复冻结范围(快照(范围)) == 范围
@pytest.mark.case_id(
"NC-ctx-scope-shape-invalid",
environment="离线纯函数",
given="细纲版本为零或布尔、章节为空串、事实系统版本为负或布尔或缺键、完全空范围",
when="从任务快照恢复冻结范围",
then=["一律 CONTEXT_SCOPE_INVALID 失败关闭,不猜测补默认值"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
@pytest.mark.parametrize(
"改动",
[
{"target_plan": {"chapter_id": "ch-3", "plan_id": "plan-target", "revision": 0}},
{"target_plan": {"chapter_id": "ch-3", "plan_id": "plan-target", "revision": True}},
{"target_plan": {"chapter_id": "", "plan_id": "plan-target", "revision": 1}},
{"facts": {"system_revision": -1}},
{"facts": {"system_revision": True}},
{"facts": {}},
{"documents": [], "target_plan": None, "facts": None},
],
ids=[
"zero-plan-revision",
"boolean-plan-revision",
"empty-chapter",
"negative-system-revision",
"boolean-system-revision",
"missing-system-revision",
"empty-scope",
],
)
def test_非法细纲事实形状或空范围拒绝__f7a8b9(改动: dict) -> None:
with pytest.raises(上下文错误) as 异常:
服务().恢复冻结范围(快照({**任务范围(), **改动}))
assert 异常.value.错误码 == "CONTEXT_SCOPE_INVALID"
@pytest.mark.case_id(
"NC-ctx-scope-plan-source-missing",
environment="离线纯函数",
given="target_plan 的 plan_id 不在冻结 source_ids 中",
when="从任务快照恢复冻结范围",
then=["CONTEXT_SCOPE_INVALID;来源清单必须覆盖文稿与细纲身份"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
def test_细纲身份不在来源清单拒绝__a3c4d5() -> None:
范围 = {**任务范围(), "source_ids": ["doc-ch-1", "obj-fact"]}
with pytest.raises(上下文错误) as 异常:
服务().恢复冻结范围(快照(范围))
assert 异常.value.错误码 == "CONTEXT_SCOPE_INVALID"
@pytest.mark.case_id(
"NC-ctx-scope-purpose-binding",
environment="离线纯函数",
given="target_plan 或 facts 存在但缺运行用途、或内容用途与任务不一致",
when="从任务快照恢复冻结范围",
then=["CONTEXT_SCOPE_INVALID;新节必须绑定与任务一致的两种用途"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
@pytest.mark.parametrize(
"改动",
[
{"run_purpose": None},
{"content_purpose": "planning"},
{"run_purpose": "production", "content_purpose": "extraction"},
],
ids=["missing-run-purpose", "content-mismatch", "content-unbound"],
)
def test_新节必须绑定与任务一致的用途__b6c7d8(改动: dict) -> None:
范围 = {**任务范围(), **改动}
if 改动.get("run_purpose") is None:
del 范围["run_purpose"]
with pytest.raises(上下文错误) as 异常:
服务().恢复冻结范围(快照(范围))
assert 异常.value.错误码 == "CONTEXT_SCOPE_INVALID"
@pytest.mark.case_id(
"NC-ctx-scope-legacy-shape",
environment="离线纯函数",
given="仅含历史文稿的旧形状范围(无用途键与新节)",
when="从任务快照恢复冻结范围",
then=["原样返回;用途绑定只对细纲与事实新节强制"],
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
)
def test_仅历史文稿的范围不要求用途键__c9d0e1() -> None:
范围 = 任务范围()
for 键 in ("run_purpose", "content_purpose", "target_plan", "facts"):
del 范围[键]
范围["source_ids"] = ["doc-ch-1"]
assert 服务().恢复冻结范围(快照(范围)) == 范围