zizi 9e6f1c4481 R2 改造交付:新版模块化单体全量成果
- src/muse 新版全模块(装配/共享/上下文/任务运行/作品规划/故事世界/正文写作/审校修订/知识方法/作者经验/效果评测/交付连载/资料研究/正式变更/元数据/接入/基础设施/编排)+ 测试树(单元/契约/集成/架构/迁移/端到端/夹具)
- 129 项功能全部实现与自动验证(功能覆盖.json/矩阵),含 W31 补齐的规则与代价/节奏安排/伏笔与承诺
- 旧实现按处置清单退出(702 条中 324 删,保护合同与未迁移条目留存有据);web/app.py 旧工作台退役,新工作台为唯一写入口
- 数据库/旧库迁移:真实旧库内容批次迁移链(端点守卫/PG作品正文映射/质量资产缺省投影)
- 运行手册 docs/运行手册.md;W30 本机服务阶段一已运行(infra PG 为正式内容权威)
- R2 执行证据与私有运行材料在 .agents.local/改造/R2-20260909/(不入库)
2026-09-15 12:47:42 +08:00

360 lines
13 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.

"""B06规则启停与实际消费;审阅决定始终由S01保存。"""
from __future__ import annotations
from dataclasses import asdict, dataclass
from typing import Annotated, Literal
from uuid import UUID
from pydantic import Field
from muse.审校修订.存储 import 审校存储
from muse.审校修订.机器味规则 import 核对规则
from muse.审校修订.模型 import 审校错误
from muse.正式变更.接口 import (
作者动作,
依赖引用,
修改影响,
参与操作,
固定哈希,
审阅内容,
提交计划,
读取作者决定,
)
@dataclass(frozen=True, slots=True)
class 规则状态命令:
rule_id: str
version: Annotated[int, Field(strict=True, ge=1)]
action: Literal["enable", "disable"]
expected_activation_revision: Annotated[int, Field(strict=True, ge=0)] = 0
credential_id: str = ""
def __post_init__(self):
if (
not self.rule_id
or self.action not in {"enable", "disable"}
or type(self.version) is not int
or self.version < 1
or type(self.expected_activation_revision) is not int
or self.expected_activation_revision < 0
):
raise 审校错误("规则状态命令需要精确规则、版本和激活基线")
if self.action == "enable":
try:
UUID(self.credential_id)
except (ValueError, TypeError, AttributeError):
raise 审校错误("规则启用需要B10具体诊断用途凭据") from None
elif self.credential_id:
raise 审校错误("规则停用不得夹带另一份启用凭据")
@dataclass(frozen=True, slots=True)
class 规则状态写入:
作者: str
命令ID: str
review_id: str
命令: 规则状态命令
version_id: str
candidate_id: str
candidate_hash: str
def _版本(store: 审校存储, author: str, command: 规则状态命令):
row = store.读取规则版本(author, command.rule_id, command.version)
if row is None or 固定哈希(row["payload"]) != row["payload_hash"]:
raise 审校错误("规则版本不存在、不属于本作者或哈希不符")
rule = row["payload"]["rule"]
核对规则(rule, row["payload"]["samples"])
if (
rule["id"] != command.rule_id
or rule["version"] != command.version
or rule["layer"] == "semantic"
or rule["trigger"]["type"] == "model_judgment"
):
raise 审校错误("启用用途只接受精确的B06非语义确定性规则")
return row
def _target(row: dict, rule_id: str, version: int) -> dict:
return {
"kind": "diagnostic_rule",
"target_ref": "B06.rule:" + rule_id,
"version": str(version),
"version_id": str(row["version_id"]),
"content_hash": row["payload_hash"],
"rule_hash": 固定哈希(row["payload"]["rule"]),
"examples_hash": 固定哈希(
{key: row["payload"]["samples"][key] for key in sorted(row["payload"]["samples"])}
),
}
def 读取规则目标(conn, author: str, rule_id: str, version: int) -> dict:
if not rule_id or type(version) is not int or version < 1:
raise 审校错误("规则目标需要明确规则身份与正数版本")
store = 审校存储(conn)
row = store.读取规则版本(author, rule_id, version)
if row is None or 固定哈希(row["payload"]) != row["payload_hash"]:
raise 审校错误("规则版本不存在、不属于本作者或哈希不符")
rule = row["payload"]["rule"]
核对规则(rule, row["payload"]["samples"])
if rule["id"] != rule_id or rule["version"] != version:
raise 审校错误("规则内容与精确版本身份不一致")
latest = store.最新规则版本(author, rule_id)
return {
"target": _target(row, rule_id, version),
"candidate_status": rule["status"],
"is_latest": bool(latest and str(latest["version_id"]) == str(row["version_id"])),
"activation_recorded": row["activation_recorded"],
}
def 列出规则诊断消费(conn, author: str, rule_id: str, version: int) -> list[dict]:
projection = 读取规则目标(conn, author, rule_id, version)
target = projection["target"]
return 审校存储(conn).列规则诊断消费(author, target["version_id"], target["content_hash"])
def _s01_target(author: str, rule_id: str) -> str:
return f"rule:{author}:{rule_id}"
def _current_basis(current: dict | None):
if current is None:
return None
return {
key: current[key]
for key in (
"rule_id",
"activation_revision",
"version_id",
"state",
"credential_id",
"latest_event_id",
"action",
"candidate_id",
"candidate_hash",
"review_id",
"command_id",
)
}
def _核对命令(conn, author: str, command: 规则状态命令, *, protect=False):
store = 审校存储(conn)
row = _版本(store, author, command)
current = store.读取规则激活(author, command.rule_id)
actual_revision = int(current["activation_revision"]) if current else 0
if actual_revision != command.expected_activation_revision:
raise 审校错误("规则激活基线已改变")
latest = store.最新规则版本(author, command.rule_id)
if latest is None:
raise 审校错误("规则当前版本不存在")
credential = None
if command.action == "enable":
if latest["revision"] != command.version or str(latest["version_id"]) != str(
row["version_id"]
):
raise 审校错误("旧规则版本不得在新版本发布后启用")
if current and current["state"] == "active":
raise 审校错误("规则已激活;替换前须先明确停用")
from muse.效果评测.接口 import 核对规则诊断凭据, 评测错误
try:
credential = 核对规则诊断凭据(
conn, author, command.credential_id, _target(row, command.rule_id, command.version)
)
except 评测错误 as exc:
raise 审校错误("规则诊断凭据不可用:" + exc.说明) from None
else:
if (
current is None
or current["state"] != "active"
or current["version_id"] != str(row["version_id"])
):
raise 审校错误("只能停用当前实际激活的精确规则版本")
if protect:
store.锁定规则版本(author, command.rule_id)
store.锁定规则激活(author, command.rule_id)
return row, current, latest, credential
class 规则状态入口:
身份 = "B06.change_rule_state"
请求类型 = 规则状态命令
def 查看(self, conn, identity, change):
command = change.业务请求
row, current, latest, credential = _核对命令(conn, identity.作者, command)
target = _s01_target(identity.作者, command.rule_id)
revision = int(current["activation_revision"]) if current else 0
next_revision = revision + 1
candidate_hash = 固定哈希(
[
asdict(command),
str(row["version_id"]),
row["payload_hash"],
credential["receipt_hash"] if credential else None,
]
)
return 审阅内容(
target,
revision,
target,
next_revision,
candidate_hash,
candidate_hash,
"",
"",
固定哈希(
[
str(latest["version_id"]),
_current_basis(current),
credential["receipt_hash"] if credential else None,
]
),
("rule_activation" if command.action == "enable" else "rule_deactivation",),
(
依赖引用("B06.rule_activation", target, str(revision)),
依赖引用("B06.rule_version", target, str(latest["revision"])),
),
)
def 准备(self, conn, identity, change, current):
if change.动作 in {作者动作.拒绝, 作者动作.暂缓}:
return 提交计划(())
if change.动作 is not 作者动作.采纳 or not change.审阅ID:
raise 审校错误("规则启停需要作者针对精确版本的审阅决定")
row, _, _, credential = _核对命令(conn, identity.作者, change.业务请求, protect=True)
return 提交计划(
(
参与操作(
"B06.apply_rule_state",
规则状态写入(
identity.作者,
change.命令ID,
change.审阅ID,
change.业务请求,
str(row["version_id"]),
current.候选ID,
current.候选哈希,
),
),
),
(
修改影响(
current.目标,
"rule_activation_changed",
str(current.数据版本),
str(current.候选版本),
),
),
)
class 规则状态参与者:
身份 = "B06.apply_rule_state"
请求类型 = 规则状态写入
def 提交(self, conn, operation):
row, _, _, _ = _核对命令(conn, operation.作者, operation.命令, protect=True)
if str(row["version_id"]) != operation.version_id:
raise 审校错误("被审规则版本已改变")
return 审校存储(conn).写规则激活事件(operation.作者, operation)
def _依赖范围(object_id: str) -> tuple[str, str]:
parts = object_id.split(":", 2)
if len(parts) != 3 or parts[0] != "rule" or not parts[1] or not parts[2]:
raise 审校错误("规则依赖身份不合法")
return parts[1], parts[2]
class _规则版本依赖:
种类 = "B06.rule_version"
def 锁定当前(self, conn, object_id: str) -> str:
author, rule_id = _依赖范围(object_id)
return str(审校存储(conn).锁定规则版本(author, rule_id))
class _规则激活依赖:
种类 = "B06.rule_activation"
def 锁定当前(self, conn, object_id: str) -> str:
author, rule_id = _依赖范围(object_id)
return str(审校存储(conn).锁定规则激活(author, rule_id))
def 登记规则参与者(directory) -> None:
"""装配签名由主代理调用;作者范围由S01目标与调用身份共同固定。"""
directory.登记入口(规则状态入口())
directory.登记参与者(规则状态参与者())
directory.登记依赖(_规则版本依赖())
directory.登记依赖(_规则激活依赖())
def 核对已激活规则(conn, author: str, current: dict, *, protect=False):
store = 审校存储(conn)
if protect:
store.锁定规则激活(author, current["rule_id"], 共享=True, 锁行=True)
row = store.读取规则版本ID(author, current["rule_id"], current["version_id"])
if (
current["state"] != "active"
or current["action"] != "enable"
or row is None
or 固定哈希(row["payload"]) != row["payload_hash"]
):
raise 审校错误("已激活规则的精确版本不可回查")
if 读取作者决定(conn, current["candidate_id"], current["activation_revision"]) != "adopt":
raise 审校错误("规则激活缺少S01实际作者采纳决定")
from muse.效果评测.接口 import 核对规则诊断凭据, 评测错误
try:
credential = 核对规则诊断凭据(
conn,
author,
current["credential_id"],
_target(row, current["rule_id"], int(row["revision"])),
)
except 评测错误 as exc:
raise 审校错误("已激活规则的凭据失效:" + exc.说明) from None
return row, credential
def 读取规则状态(conn, author: str, rule_id: str) -> dict:
store = 审校存储(conn)
current = store.读取规则激活(author, rule_id)
history = store.列规则激活历史(author, rule_id)
usable, reason = False, None
if current and current["state"] == "active":
try:
核对已激活规则(conn, author, current)
usable = True
except 审校错误 as exc:
reason = exc.说明
elif current:
reason = "rule_disabled"
if current:
version = store.读取规则版本ID(author, rule_id, current["version_id"])
current = {**current, "rule_version": int(version["revision"]) if version else None}
return {
"rule_id": rule_id,
"current": current,
"history": history,
"consumable": usable,
"reason": reason,
}
__all__ = [
"规则状态命令",
"登记规则参与者",
"核对已激活规则",
"读取规则目标",
"读取规则状态",
"列出规则诊断消费",
]