实现侧: - 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。 - 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。 - 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。 - 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。 - 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。 - 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。 - 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。 - 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。 用例侧: - 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存; - 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
246 lines
10 KiB
Python
246 lines
10 KiB
Python
"""探索清单与确定性回放的合同行为:未知工具、越界参数、缺来源拒绝;顺序、范围、理由与消费哈希可核对。
|
||
|
||
离线纯函数与合成读取器;不连库、不代表真实来源授权。旧 TC 分配不承身份,按功能价值新写。
|
||
"""
|
||
|
||
import pytest
|
||
from jsonschema import Draft202012Validator
|
||
|
||
from muse.上下文.接口 import (
|
||
上下文错误,
|
||
探索条目,
|
||
来源绑定,
|
||
校验清单,
|
||
记录探索,
|
||
逐项比对,
|
||
)
|
||
from muse.任务运行.接口 import (
|
||
内容哈希,
|
||
只读工具集,
|
||
工具定义,
|
||
工具来源,
|
||
工具结果,
|
||
工具范围,
|
||
工具请求,
|
||
模型协议错误,
|
||
)
|
||
|
||
范围 = {
|
||
"work_id": "work-a",
|
||
"as_of": 2,
|
||
"source_ids": ["doc-1", "plan-1", "fact-lin"],
|
||
"documents": [
|
||
{
|
||
"chapter_id": "ch-1",
|
||
"branch_id": "main",
|
||
"revision": 1,
|
||
"document_id": "doc-1",
|
||
"document_hash": "hash-doc-1",
|
||
"position": 1,
|
||
}
|
||
],
|
||
"directory_revision": 3,
|
||
"authorized_by": "author-a",
|
||
"run_purpose": "production",
|
||
"content_purpose": "generation",
|
||
"target_plan": {
|
||
"chapter_id": "ch-3",
|
||
"plan_id": "plan-1",
|
||
"revision": 1,
|
||
"content_hash": "hash-plan-1",
|
||
},
|
||
"facts": {"system_revision": 5},
|
||
}
|
||
|
||
投影 = "visible-text-codepoints/v1:production:generation"
|
||
文档来源 = 工具来源("doc-1", "1", "hash-doc-1", 投影)
|
||
文档绑定 = (来源绑定("doc-1", "1", "hash-doc-1", 投影),)
|
||
文档结果 = 工具结果({"chapter_id": "ch-1", "text": "林深停在码头,雨还没停。"}, (文档来源,))
|
||
|
||
|
||
def 带参条目(工具名: str, 参数: dict, 顺序: int = 1, 调用ID: str = "call-x") -> 探索条目:
|
||
"""以固定来源绑定与消费哈希构造任意参数条目;参数合法性正是被测对象。"""
|
||
return 探索条目(
|
||
调用ID=调用ID,
|
||
工具名=工具名,
|
||
顺序=顺序,
|
||
参数=参数,
|
||
来源引用=文档绑定,
|
||
消费哈希=内容哈希(文档结果.内容),
|
||
)
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-ctx-replay-unknown-tool",
|
||
environment="离线契约",
|
||
given="未知工具名或范围未授权的工具",
|
||
when="校验并回放",
|
||
then="未知工具 CONTEXT_INPUT_INVALID;未授权 SCOPE_DENIED",
|
||
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
|
||
)
|
||
def test_未知工具与未授权工具分别明确拒绝__b7e0a1() -> None:
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((带参条目("read_anything", {"chapter_id": "ch-1"}),), 范围)
|
||
assert 异常.value.错误码 == "CONTEXT_INPUT_INVALID"
|
||
assert "未知工具" in 异常.value.说明 and "read_anything" in 异常.value.说明
|
||
# 工具真实存在但任务范围未冻结对应来源:拒绝的是授权,不是字符串存在性
|
||
无细纲 = {**范围, "target_plan": None}
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((带参条目("query_work_plan", {}),), 无细纲)
|
||
assert 异常.value.错误码 == "SCOPE_DENIED"
|
||
assert "query_work_plan" in 异常.value.说明 and "冻结范围" in 异常.value.说明
|
||
无事实 = {**范围, "facts": None}
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((带参条目("query_facts_as_of", {}),), 无事实)
|
||
assert 异常.value.错误码 == "SCOPE_DENIED"
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-ctx-replay-scope-args",
|
||
environment="离线契约",
|
||
given="指定未冻结文稿版本或携带扩权字段的参数",
|
||
when="校验并回放",
|
||
then="SCOPE_DENIED/CONTEXT_INPUT_INVALID 拒绝,不静默收窄",
|
||
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
|
||
)
|
||
def test_参数越出冻结范围与扩权字段拒绝__b7e0a2() -> None:
|
||
未冻结版本 = 带参条目("read_history_document", {"chapter_id": "ch-1", "revision": 2})
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((未冻结版本,), 范围)
|
||
assert 异常.value.错误码 == "SCOPE_DENIED"
|
||
assert "不在冻结范围内" in 异常.value.说明 and "版本 2" in 异常.value.说明
|
||
未冻结文稿 = 带参条目(
|
||
"read_history_document", {"chapter_id": "ch-2", "revision": 1, "branch_id": "draft"}
|
||
)
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((未冻结文稿,), 范围)
|
||
assert 异常.value.错误码 == "SCOPE_DENIED"
|
||
扩权 = 带参条目("read_history_document", {"chapter_id": "ch-1", "revision": 1, "as_of": 9})
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((扩权,), 范围)
|
||
assert 异常.value.错误码 == "SCOPE_DENIED"
|
||
assert "扩权" in 异常.value.说明 or "不得" in 异常.value.说明
|
||
# 角色视角必须携带知情主体,其他视角不得携带:与工具读取同一规则
|
||
无知情主体 = 带参条目("query_facts_as_of", {"view": "character"})
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((无知情主体,), 范围)
|
||
assert 异常.value.错误码 == "CONTEXT_INPUT_INVALID"
|
||
assert "知情主体" in 异常.value.说明
|
||
非法视角 = 带参条目("query_facts_as_of", {"view": "narrator"})
|
||
with pytest.raises(上下文错误) as 异常:
|
||
校验清单((非法视角,), 范围)
|
||
assert 异常.value.错误码 == "CONTEXT_INPUT_INVALID"
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-ctx-replay-drift-compare",
|
||
environment="离线契约",
|
||
given="版本、哈希、投影版本或内容消费哈希任一漂移的条目",
|
||
when="按清单回放",
|
||
then="SOURCE_STALE 且指明调用与来源",
|
||
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
|
||
)
|
||
def test_回放比对指明版本哈希投影与内容漂移__b7e0a3() -> None:
|
||
基准 = 带参条目(
|
||
"read_history_document", {"chapter_id": "ch-1", "revision": 1}, 调用ID="call-hist"
|
||
)
|
||
assert 逐项比对(基准, 文档结果) == ()
|
||
版本漂移 = 逐项比对(
|
||
基准, 工具结果(文档结果.内容, (工具来源("doc-1", "2", "hash-doc-1", 投影),))
|
||
)
|
||
assert len(版本漂移) == 1 and "数据版本" in 版本漂移[0] and "call-hist" in 版本漂移[0]
|
||
哈希漂移 = 逐项比对(基准, 工具结果(文档结果.内容, (工具来源("doc-1", "1", "hash-改", 投影),)))
|
||
assert len(哈希漂移) == 1 and "结构哈希" in 哈希漂移[0]
|
||
投影漂移 = 逐项比对(
|
||
基准, 工具结果(文档结果.内容, (工具来源("doc-1", "1", "hash-doc-1", "proj/v2"),))
|
||
)
|
||
assert len(投影漂移) == 1 and "投影版本" in 投影漂移[0]
|
||
内容漂移 = 逐项比对(基准, 工具结果({"chapter_id": "ch-1", "text": "改过的正文"}, (文档来源,)))
|
||
assert any("消费哈希" in 项 for 项 in 内容漂移)
|
||
来源消失 = 逐项比对(基准, 工具结果(文档结果.内容, ()))
|
||
assert any("已不在" in 项 for 项 in 来源消失)
|
||
清单外来源 = 逐项比对(
|
||
基准, 工具结果(文档结果.内容, (文档来源, 工具来源("doc-9", "1", "hash-doc-1", 投影)))
|
||
)
|
||
assert any("清单外来源 doc-9" in 项 for 项 in 清单外来源)
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-ctx-replay-consumption-hash",
|
||
environment="离线契约",
|
||
given="真实工具读取结果",
|
||
when="记录探索条目",
|
||
then="消费哈希与来源绑定与 S02 事件 source_refs 同键可核对",
|
||
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
|
||
)
|
||
def test_记录探索消费哈希与来源绑定同键__b7e0a4() -> None:
|
||
记录 = []
|
||
|
||
def 读取(_, 参数):
|
||
assert 参数 == {"chapter_id": "ch-1", "revision": 1}
|
||
return 文档结果
|
||
|
||
定义 = 工具定义(
|
||
"read_history_document",
|
||
"读取历史正文",
|
||
{
|
||
"type": "object",
|
||
"additionalProperties": False,
|
||
"required": ["chapter_id", "revision"],
|
||
"properties": {
|
||
"chapter_id": {"type": "string", "minLength": 1},
|
||
"revision": {"type": "integer", "minimum": 1},
|
||
},
|
||
},
|
||
读取,
|
||
)
|
||
Draft202012Validator.check_schema(定义.参数合同)
|
||
集合 = 只读工具集(
|
||
(定义,),
|
||
("read_history_document",),
|
||
工具范围("task-r", "work-a", ("doc-1",), 2, "production", "generation"),
|
||
记录.append,
|
||
)
|
||
参数 = {"chapter_id": "ch-1", "revision": 1}
|
||
结果 = 集合.调用(工具请求("call-hist", "read_history_document", 参数))
|
||
条目 = 记录探索((), "call-hist", "read_history_document", 参数, 结果)[0]
|
||
# 清单条目与 S02 工具读取事件留痕同键:来源四元组逐字段一致
|
||
留痕 = 记录[0]["source_refs"][0]
|
||
绑定 = 条目.来源引用[0]
|
||
assert (绑定.来源ID, 绑定.数据版本, 绑定.结构哈希, 绑定.投影版本) == (
|
||
留痕["source_id"],
|
||
留痕["revision"],
|
||
留痕["schema_hash"],
|
||
留痕["projection_version"],
|
||
)
|
||
assert 条目.消费哈希 == 内容哈希(结果.内容)
|
||
assert 条目.顺序 == 1
|
||
校验清单((条目,), 范围)
|
||
# 工具读取被 S02 拒绝时不产生清单可承接的结果
|
||
with pytest.raises(模型协议错误):
|
||
集合.调用(
|
||
工具请求("call-bad", "read_history_document", {"chapter_id": "ch-1", "work_id": "x"})
|
||
)
|
||
assert len(记录) == 1
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-ctx-replay-ordered-tools",
|
||
environment="离线契约",
|
||
given="覆盖三类具名工具的合法清单",
|
||
when="校验并回放",
|
||
then="按序通过,顺序可核对",
|
||
contract="docs/系统架构/新版设计/模块设计/B09-上下文.md",
|
||
)
|
||
def test_三类工具清单按序通过且顺序可核对__b7e0a5() -> None:
|
||
清单: tuple[探索条目, ...] = ()
|
||
for 调用ID, 工具名, 参数 in [
|
||
("call-plan", "query_work_plan", {}),
|
||
("call-facts", "query_facts_as_of", {}),
|
||
("call-hist", "read_history_document", {"chapter_id": "ch-1", "revision": 1, "end": 6}),
|
||
]:
|
||
清单 = 记录探索(清单, 调用ID, 工具名, 参数, 文档结果)
|
||
校验清单(清单, 范围) # 不抛异常即通过
|
||
assert [项.调用ID for 项 in 清单] == ["call-plan", "call-facts", "call-hist"]
|
||
assert [项.顺序 for 项 in 清单] == [1, 2, 3]
|