"""提示词治理守卫:模型系统提示必须来自登记资源,代码内字面量仅白名单豁免。 保护:A1 类回归——任务提示词散落在代码字面量、绕过资源登记/哈希冻结/发布包治理。 白名单唯一成员是配置探针:探针提示与探针合同同构、64 token 固定、无迭代需求, 豁免理由在 配置探针.py 调用处注释留痕。 """ from __future__ import annotations import re from pathlib import Path import pytest 仓库根 = Path(__file__).resolve().parents[2] 源码根 = 仓库根 / "src" / "muse" 白名单 = {"任务运行/配置探针.py"} # 系统提示= 后接字符串字面量(含括号包裹的隐式拼接与 f/r/b 前缀)即硬编码; # 变量或函数返回值传递(系统提示=模板 / 系统提示=拆书分析模板()[0])不匹配。 _硬编码 = re.compile(r"""系统提示\s*=\s*\(?\s*[fF]?[rRbBuU]{0,2}["']""") def _源码文件(): for 文件 in sorted(源码根.rglob("*.py")): if "__pycache__" in 文件.parts: continue yield 文件 @pytest.mark.case_id("NC-prompt-governance-no-hardcoded-system-prompt") def test_系统提示字面量仅白名单豁免(): 违规 = [ str(文件.relative_to(源码根)) for 文件 in _源码文件() if str(文件.relative_to(源码根)) not in 白名单 and _硬编码.search(文件.read_text(encoding="utf-8")) ] assert 违规 == [], f"系统提示不得硬编码字面量,应登记为资源模板:{违规}" @pytest.mark.case_id("NC-prompt-governance-guard-self-check") def test_守卫正则检出各字面量形式且不误报变量传递(): 检出样例 = ( '系统提示="你是XX。"', "系统提示='你是XX。'", '系统提示=(\n "你是XX。"\n "做YY。"\n )', '系统提示 = (\n "你是XX。"\n)', '系统提示=f"你是{名}。"', ) for 样例 in 检出样例: assert _硬编码.search(样例), f"守卫漏检字面量形式:{样例}" 放行样例 = ( "系统提示=模板", "系统提示=模板,", "系统提示=探索提示,", "系统提示=拆书分析模板()[0]", "系统提示: str,", "系统提示: str = 模板", ) for 样例 in 放行样例: assert not _硬编码.search(样例), f"守卫误报变量传递:{样例}"