实现侧: - 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。 - 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。 - 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。 - 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。 - 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。 - 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。 - 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。 - 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。 用例侧: - 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存; - 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
260 lines
12 KiB
Python
260 lines
12 KiB
Python
"""固定真实方法、反馈和B10实验;跨用途及owner提交后登记中断可恢复。"""
|
||
|
||
import json
|
||
import os
|
||
import subprocess
|
||
import sys
|
||
from dataclasses import asdict, replace
|
||
from datetime import UTC, datetime, timedelta
|
||
from uuid import uuid4
|
||
|
||
import pytest
|
||
import test_方法启用凭据 as 启用测试
|
||
import test_正文候选与作者决定 as 正文测试
|
||
|
||
from muse.作者经验.存储 import 经验存储
|
||
from muse.作者经验.接口 import 反馈版本, 反馈请求, 改进定位, 改进请求
|
||
from muse.共享.调用身份 import 用途
|
||
from muse.共享.错误 import Muse错误
|
||
from muse.正文写作.接口 import 读取候选依据
|
||
|
||
pytestmark = pytest.mark.数据库
|
||
方法环境 = 启用测试.方法环境
|
||
执行环境 = 启用测试.执行环境
|
||
|
||
|
||
def _提案(env):
|
||
app, author = env["business"], env["owner"]
|
||
service = app.要求作者经验()
|
||
body = app.要求正文()
|
||
body.保存人工(author, "before", "mw-1", 0, 正文测试.草稿())
|
||
candidate = body.创建人工候选(author, "after", "mw-1", 1, 正文测试.草稿("改过的一句。"))[
|
||
"results"
|
||
][0]
|
||
original = body.读取正文(author, "mw-1")
|
||
with env["pools"][用途.生产].连接(只读=True) as conn:
|
||
updated = 读取候选依据(conn, author.作者, candidate["candidate_id"], 1)
|
||
feedback = service.记录反馈(
|
||
author,
|
||
"improvement-feedback",
|
||
反馈请求(
|
||
"method-work",
|
||
反馈版本("document", "mw-1", 1, original["document_hash"]),
|
||
反馈版本("candidate", candidate["candidate_id"], 1, updated["document_hash"]),
|
||
"回收前文物件,不再临时添加解释。",
|
||
"revise",
|
||
),
|
||
)
|
||
request = 改进请求(
|
||
str(uuid4()),
|
||
0,
|
||
"检验物件回收方法",
|
||
"依据本次修改保留回收时机。",
|
||
str(env["version"]["version_id"]),
|
||
(str(feedback["feedback_id"]),),
|
||
)
|
||
row = service.提出改进(author, request)
|
||
return service, request, 改进定位(request.improvement_id, row["revision"], row["content_hash"])
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w26-26c001",
|
||
environment="隔离PG、实际B10/S01/B04与合成HTTP;不认证外部文学效果",
|
||
given="确切方法版本、真实反馈和同作者用途配置",
|
||
when="登记具体改进、实际验证和owner启停并恢复已提交结果;记录分版本观察",
|
||
then=["具体改进实际评测与owner回执中断恢复"],
|
||
contract="docs/系统架构/新版设计/模块设计/B07-作者经验.md",
|
||
)
|
||
@pytest.mark.parametrize("执行环境", [启用测试.参数], indirect=True)
|
||
@pytest.mark.timeout(900)
|
||
@pytest.mark.慢
|
||
def test_具体改进实际评测与owner回执中断恢复__26c001(执行环境, 方法环境, monkeypatch):
|
||
env = 启用测试._确认方法(执行环境, 方法环境)
|
||
service, request, point = _提案(env)
|
||
author = env["owner"]
|
||
evaluation = env["app"].要求评测()
|
||
certificate = 启用测试.效果测试._校准(env)
|
||
write_result = 经验存储.保存改进结果
|
||
failures = {"validate": 1, "enable": 1}
|
||
|
||
def 断一次(self, who, command, receipt):
|
||
if failures.get(command, 0):
|
||
failures[command] -= 1
|
||
raise RuntimeError("目标已经提交,登记前中断")
|
||
return write_result(self, who, command, receipt)
|
||
|
||
monkeypatch.setattr(经验存储, "保存改进结果", 断一次)
|
||
|
||
def 注册(req):
|
||
with pytest.raises(RuntimeError, match="登记前中断"):
|
||
service.申请验证(author, "validate", point, evaluation, env["actor"], req)
|
||
pending = service.读取改进(author, request.improvement_id)["actions"][0]
|
||
assert pending["receipt"] is None
|
||
actual = evaluation.查找已登记实验(
|
||
env["actor"], "B07.validation:" + str(pending["action_id"]), req
|
||
)
|
||
assert actual is not None
|
||
recovered = service.申请验证(author, "validate", point, evaluation, env["actor"], req)
|
||
assert recovered["receipt"]["experiment_id"] == actual["experiment_id"]
|
||
assert set(recovered["receipt"]) == {
|
||
"experiment_id",
|
||
"conditions_hash",
|
||
"target",
|
||
"request_hash",
|
||
"registration",
|
||
}
|
||
return actual
|
||
|
||
dest = 启用测试._实际方法留出(env, certificate, 登记=注册)
|
||
assert 启用测试.效果测试._完成(dest)["assessment"]["gate_b"]["status"] == "passed"
|
||
eid = dest["exp"]["experiment_id"]
|
||
evaluation.封存效果判据(env["actor"], eid)
|
||
proof = evaluation.导出启用凭据(
|
||
env["actor"],
|
||
eid,
|
||
env["pools"][用途.维护],
|
||
replace(env["actor"], 用途=用途.维护),
|
||
批准引用="synthetic-improvement-only",
|
||
有效期=datetime.now(UTC) + timedelta(hours=1),
|
||
)
|
||
with pytest.raises(RuntimeError, match="登记前中断"):
|
||
service.请求启停(author, "enable", point, "enable", proof["receipt_id"])
|
||
after = service.读取改进(author, request.improvement_id)
|
||
assert after["target_state"] == "enabled"
|
||
intent = next(x for x in after["actions"] if x["kind"] == "enable")
|
||
assert intent["receipt"] is None
|
||
original = service.正式.读取回执(author, "B07.owner:" + str(intent["action_id"]))
|
||
evaluation.取消实验(
|
||
env["actor"], certificate["result"]["experiment_id"], "stop-before-recovery"
|
||
)
|
||
recovered = service.请求启停(author, "enable", point, "enable", proof["receipt_id"])
|
||
assert recovered["receipt"] == original
|
||
assert (
|
||
service.请求启停(author, "enable", point, "enable", proof["receipt_id"])["receipt"]
|
||
== original
|
||
)
|
||
disabled = service.请求启停(author, "disable", point, "disable")
|
||
assert disabled["receipt"]["results"][0]["state"] == "disabled"
|
||
assert service.读取改进(author, request.improvement_id)["target_state"] == "disabled"
|
||
with pytest.raises(Muse错误):
|
||
service.请求启停(author, "reenable", point, "enable", proof["receipt_id"])
|
||
service.提出改进(
|
||
author, replace(request, expected_revision=1, rationale="改进理由已由作者修正。")
|
||
)
|
||
with pytest.raises(Muse错误, match="当前版本"):
|
||
service.请求启停(author, "old-approval", point, "enable", proof["receipt_id"])
|
||
assert (
|
||
service.请求启停(author, "enable", point, "enable", proof["receipt_id"])["receipt"]
|
||
== original
|
||
)
|
||
assert len(env["received"]) == 85
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w26-26c002",
|
||
environment="隔离PG、实际B10/S01/B04与合成HTTP;不认证外部文学效果",
|
||
given="确切方法版本、真实反馈和同作者用途配置",
|
||
when="登记具体改进、实际验证和owner启停并恢复已提交结果;记录分版本观察",
|
||
then=["无真实反馈或异目标不能登记改进实验"],
|
||
contract="docs/系统架构/新版设计/模块设计/B07-作者经验.md",
|
||
)
|
||
@pytest.mark.parametrize("执行环境", [启用测试.参数], indirect=True)
|
||
def test_无真实反馈或异目标不能登记改进实验__26c002(执行环境, 方法环境):
|
||
env = 启用测试._确认方法(执行环境, 方法环境)
|
||
service, request, point = _提案(env)
|
||
with pytest.raises(Muse错误):
|
||
service.提出改进(
|
||
env["owner"],
|
||
replace(request, improvement_id=str(uuid4()), feedback_ids=(str(uuid4()),)),
|
||
)
|
||
with pytest.raises(Muse错误, match="非空"):
|
||
replace(request, feedback_ids=())
|
||
with pytest.raises(Muse错误, match="同一具体改进"):
|
||
service.申请验证(
|
||
env["owner"], "wrong-target", point, env["app"].要求评测(), env["actor"], env["request"]
|
||
)
|
||
assert service.读取改进(env["owner"], request.improvement_id)["actions"] == []
|
||
stranger = replace(env["owner"], 作者="stranger")
|
||
with pytest.raises(Muse错误):
|
||
service.读取改进(stranger, request.improvement_id)
|
||
assert env["methods"].读取方法详情(env["owner"], env["method_id"])["state"] == "confirmed"
|
||
assert env["received"] == []
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w26-26c003",
|
||
environment="隔离PG、实际B10/S01/B04与合成HTTP;不认证外部文学效果",
|
||
given="确切方法版本、真实反馈和同作者用途配置",
|
||
when="登记具体改进、实际验证和owner启停并恢复已提交结果;记录分版本观察",
|
||
then=["具体改进CLI与作者HTTP引用同一版本"],
|
||
contract="docs/系统架构/新版设计/模块设计/B07-作者经验.md",
|
||
)
|
||
def test_具体改进CLI与作者HTTP引用同一版本__26c003(方法环境, tmp_path):
|
||
import test_偏好实际消费 as 作者测试
|
||
import test_生产评测权限隔离 as 接入测试
|
||
from fastapi.testclient import TestClient
|
||
|
||
from muse.接入.http.应用 import 创建应用
|
||
from muse.配置 import 读取配置
|
||
|
||
env = 启用测试._确认方法({"actor": 方法环境[1]}, 方法环境)
|
||
service, request, point = _提案(env)
|
||
config = 接入测试._配置文件(env["pools"][用途.生产], tmp_path)
|
||
config.write_text(config.read_text().replace("eval-author", env["owner"].作者))
|
||
changed = replace(request, improvement_id=str(uuid4()), title="CLI具体改进")
|
||
file = tmp_path / "improvement.json"
|
||
file.write_text(json.dumps({"proposal": asdict(changed)}, ensure_ascii=False))
|
||
process = subprocess.run(
|
||
[sys.executable, "-m", "muse", "经验", str(config), "提出改进", str(file)],
|
||
cwd=tmp_path,
|
||
text=True,
|
||
capture_output=True,
|
||
timeout=30,
|
||
)
|
||
assert process.returncode == 0, process.stderr
|
||
created = json.loads(process.stdout)
|
||
assert created["improvement_id"] == changed.improvement_id
|
||
process = subprocess.run(
|
||
[sys.executable, "-m", "muse", "经验", str(config), "读取改进", changed.improvement_id],
|
||
cwd=tmp_path,
|
||
text=True,
|
||
capture_output=True,
|
||
timeout=30,
|
||
)
|
||
assert process.returncode == 0, process.stderr
|
||
assert json.loads(process.stdout)["target_state"] == "confirmed"
|
||
with TestClient(创建应用(读取配置(config)), headers={"origin": "http://testserver"}) as client:
|
||
assert (
|
||
client.post(
|
||
"/api/v1/session", json={"password": "synthetic-evaluation-only"}
|
||
).status_code
|
||
== 200
|
||
)
|
||
detail = client.get("/api/v1/improvements/" + point.improvement_id)
|
||
assert detail.status_code == 200 and detail.json()["content_hash"] == point.content_hash
|
||
assert detail.json()["consumption"] == []
|
||
invalid = client.post(
|
||
"/api/v1/improvements",
|
||
json={"proposal": {**asdict(changed), "expected_revision": True}},
|
||
)
|
||
assert invalid.status_code == 422
|
||
denied = client.post(
|
||
"/api/v1/improvements/enable",
|
||
json={"command_id": "bad-proof", "selection": asdict(point), "proof_id": str(uuid4())},
|
||
)
|
||
assert denied.status_code >= 400, denied.text
|
||
assert client.get("/api/v1/improvements/" + point.improvement_id).json()["actions"] == []
|
||
if os.environ.get("MUSE_RUN_BROWSER") == "1":
|
||
output = 作者测试._浏览器偏好(
|
||
读取配置(config), request.feedback_ids[0], tmp_path, "具体改进.spec.ts"
|
||
)
|
||
files = list(output.rglob("实际改进.json"))
|
||
assert len(files) == 1
|
||
saved = json.loads(files[0].read_text())
|
||
actual = service.读取改进(env["owner"], saved["improvement_id"])
|
||
assert actual["content_hash"] == saved["content_hash"]
|
||
assert actual["target_state"] == "confirmed" and actual["actions"] == []
|
||
report = service.读取观察(env["owner"], saved["improvement_id"])
|
||
assert report["groups"][0]["metrics"]["review_seconds"]["total"] == 0
|
||
assert report["groups"][0]["metrics"]["cost_usd"]["total"] is None
|