- 新增3份任务模板并登记:正文/受限探索.md、抽取/章后抽取.md、抽取/拆书分析.md; 模板不带身份句,身份唯一来源为角色层,消除装配后双自我介绍 - 消费方改走 打开资源() 并返回(文本,sha256):生成正文.受限探索模板、 章后处理.章后抽取模板、拆书分析.拆书分析模板;探索/抽取检查点留痕模板哈希 - 配置探针保留代码内提示并加豁免注释(与探针合同同构、64 token、无迭代需求) - 新增架构守卫 tests/架构/test_提示词治理.py:系统提示字面量仅白名单豁免, 正则覆盖括号多行拼接与f-string形式,含守卫自检防假绿 - 新增 tests/单元/test_提示词装配.py:三链路装配=角色+模板+合同且模板无身份句 - test_规划审校发布模板.py 参数表扩至6份模板(同哈希、缺失/篡改不回退) 证据:离线全量1153项通过;受影响数据库集成19项通过(两阶段写手/章后失败与 重建/配置探针与章后绑定/参考分析权威/同作品抽取互斥/抽取版本与补偿); ruff+pyright 零告警;资源包已重建(构建编排.py),索引检查通过(用例+3)。
105 lines
4.1 KiB
Python
105 lines
4.1 KiB
Python
"""规划、审校与编排/资料研究链路仅消费发布资源;发现技能不等于全部运行能力。"""
|
|
|
|
import hashlib
|
|
import json
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from muse import 资源加载
|
|
from muse.共享.错误 import 资源缺失错误
|
|
from muse.审校修订.完整审校 import 文学模板
|
|
from muse.编排.生成正文 import 受限探索模板
|
|
from muse.编排.生成规划 import 规划模板
|
|
from muse.编排.章后处理 import 章后抽取模板
|
|
from muse.资料研究.拆书分析 import 拆书分析模板
|
|
from muse.资源加载 import 使用资源提供器, 安装包资源提供器, 读取能力
|
|
|
|
模板集 = (
|
|
(lambda: 规划模板("fine_outline"), "规划/细化章节计划.md"),
|
|
(lambda: 规划模板("outline"), "规划/生成作品规划.md"),
|
|
(文学模板, "审校/创作质量审阅.md"),
|
|
(受限探索模板, "正文/受限探索.md"),
|
|
(章后抽取模板, "抽取/章后抽取.md"),
|
|
(拆书分析模板, "抽取/拆书分析.md"),
|
|
)
|
|
|
|
|
|
def _安装资源(tmp_path, monkeypatch, 名称, 内容, *, 缺文件=False, 错哈希=False):
|
|
(tmp_path / "清单.json").write_text(
|
|
json.dumps(
|
|
{
|
|
"发布身份": "test-release",
|
|
"资源": {
|
|
名称: {"sha256": "0" * 64 if 错哈希 else hashlib.sha256(内容).hexdigest()}
|
|
},
|
|
}
|
|
)
|
|
)
|
|
with zipfile.ZipFile(tmp_path / "运行资源.zip", "w") as 包:
|
|
if not 缺文件:
|
|
包.writestr(名称, 内容)
|
|
monkeypatch.setattr(资源加载.resources, "files", lambda _: tmp_path)
|
|
|
|
|
|
@pytest.mark.case_id("NC-prompt-package-content-and-hash")
|
|
@pytest.mark.parametrize(
|
|
"读取,名称",
|
|
模板集,
|
|
ids=("fine-plan", "work-plan", "literary", "explore", "chapter-extract", "book-analysis"),
|
|
)
|
|
def test_规划审校无源树从发布包读相同内容与哈希(tmp_path, monkeypatch, 读取, 名称):
|
|
内容 = "仅存在于当前发布包的测试提示词。".encode()
|
|
_安装资源(tmp_path, monkeypatch, 名称, 内容)
|
|
# 包根仅包含 ZIP 与清单;故意拒绝从项目散落 markdown 读取的旧路径。
|
|
原读取 = Path.read_text
|
|
|
|
def 禁止源码(self, *args, **kwargs):
|
|
if self.suffix == ".md":
|
|
raise AssertionError("提示词不得回退源码文件")
|
|
return 原读取(self, *args, **kwargs)
|
|
|
|
monkeypatch.setattr(Path, "read_text", 禁止源码)
|
|
with 使用资源提供器(安装包资源提供器()):
|
|
assert 读取() == (内容.decode(), hashlib.sha256(内容).hexdigest())
|
|
|
|
|
|
@pytest.mark.case_id("NC-prompt-package-missing-or-corrupt-rejected")
|
|
@pytest.mark.parametrize(
|
|
"读取,名称",
|
|
模板集,
|
|
ids=("fine-plan", "work-plan", "literary", "explore", "chapter-extract", "book-analysis"),
|
|
)
|
|
@pytest.mark.parametrize("故障", ("missing", "hash"))
|
|
def test_发布包模板缺失或篡改不从源码补齐(tmp_path, monkeypatch, 读取, 名称, 故障):
|
|
_安装资源(
|
|
tmp_path,
|
|
monkeypatch,
|
|
名称,
|
|
b"released content",
|
|
缺文件=故障 == "missing",
|
|
错哈希=故障 == "hash",
|
|
)
|
|
with 使用资源提供器(安装包资源提供器()), pytest.raises(资源缺失错误):
|
|
读取()
|
|
|
|
|
|
@pytest.mark.case_id("NC-writing-operations-are-runtime-capabilities")
|
|
def test_作者写作与候选核对操作登记可读且命令真实(源码资源):
|
|
from muse.接入.http.应用 import 导出合同
|
|
|
|
命令 = {
|
|
操作["operationId"]
|
|
for 路径 in 导出合同()["paths"].values()
|
|
for 操作 in 路径.values()
|
|
if isinstance(操作, dict) and "operationId" in 操作
|
|
}
|
|
with 使用资源提供器(源码资源):
|
|
写作 = 读取能力("operation", "write-next-chapter")
|
|
核对 = 读取能力("operation", "check-consistency")
|
|
assert 写作["commands"] == ["start_writing_task", "read_task", "read_task_events"]
|
|
assert 核对["commands"] == ["read_candidate_review_report", "read_task_events"]
|
|
assert set(写作["commands"] + 核对["commands"]) <= 命令
|
|
assert "创作" in 写作["正文"] and "报告" in 核对["正文"]
|