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

103 lines
4.6 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.

"""只读逐项对账:原输入、不可变台账、真实S01回执和业务候选分别核查。"""
from __future__ import annotations
import hashlib
from collections import Counter
from pathlib import Path
from muse.共享.调用身份 import 调用身份
from muse.共享.错误 import Muse错误
from muse.启动 import 应用装配
from muse.基础设施.数据库.连接 import 数据库工厂
from muse.配置 import 数据库引用
from 关联已确认 import 冻结模式
from 导入新库 import 核对隔离目标
from 建立映射 import 稳定JSON, 旧快照, 映射配置, 迁移错误
from 映射台账 import 迁移台账
from 来源回放 import 只读回放来源
from 读取旧文件 import 核对文件保全
from 转换业务对象 import 核对目标产物
def 核对迁移结果(
装配: 应用装配,
身份: 调用身份,
快照: list[旧快照],
映射: 映射配置,
*,
允许实例: Path,
管理引用: 数据库引用,
目标回执: Path,
文件回执: Path | None = None,
来源回放: dict | None = None,
) -> dict:
库 = 数据库工厂(装配.配置.数据库, 装配.配置.运行用途)
核对隔离目标(库, 允许实例=允许实例, 管理引用=管理引用, 目标回执=目标回执)
正式 = 装配.要求知识方法().正式
台账 = 迁移台账(库, 身份, 正式, 装配.要求故事世界(), 装配.要求审校(), 装配)
映射哈希 = hashlib.sha256(稳定JSON(映射.值).encode()).hexdigest()
问题, 状态 = [], Counter()
已见 = {}
for 源 in 快照:
key = 源.source.记录键
if key in 已见:
if 已见[key] != 源.源哈希:
问题.append({"source_key": key, "reason_code": "source_drift"})
continue
已见[key] = 源.源哈希
try:
行 = 台账.读取(key)
if 行 is None:
问题.append({"source_key": key, "reason_code": "source_unaccounted"})
continue
状态[行["state"]] += 1
if 行["source_hash"] != 源.源哈希 or 稳定JSON(行["original"]) != 稳定JSON(源.导出()):
问题.append({"source_key": key, "reason_code": "source_drift"})
if 行["mapping_hash"] != 映射哈希:
问题.append({"source_key": key, "reason_code": "mapping_drift"})
if 行["state"] == "reserved":
问题.append({"source_key": key, "reason_code": "unfinished"})
elif 行["state"] == "quarantined":
问题.append({"source_key": key, "reason_code": 行["reason_code"] or "quarantined"})
elif 行["state"] == "mapped":
if 行["frozen_request"].get("pg_kind"):
from PG台账接线 import 核对PG台账
回执 = 行["receipt"]
目标 = 核对PG台账(台账, 行, 回执)
elif 冻结模式(行["frozen_request"]) == "link_confirmed":
回执, 目标 = 台账.核对关联(key)
elif 行["frozen_request"].get("quality_kind") == "rule_version":
回执 = 行["receipt"]
目标 = 核对目标产物(装配, 身份, 行["frozen_request"], 回执)
else:
回执 = 正式.读取回执(身份, 行["command_id"])
目标 = 核对目标产物(装配, 身份, 行["frozen_request"], 回执)
if 稳定JSON(回执) != 稳定JSON(行["receipt"]) or 稳定JSON(目标) != 稳定JSON(
行["targets"]
):
问题.append({"source_key": key, "reason_code": "target_receipt_mismatch"})
except (迁移错误, Muse错误) as 错:
代码 = 错.code if isinstance(错, 迁移错误) else 错.错误码
问题.append({"source_key": key, "reason_code": 代码})
文件检查 = 核对文件保全(文件回执, 快照)
回放 = 只读回放来源(台账, 来源回放, 映射哈希)
总问题 = (
问题
+ [{"side": "file", **e} for e in 文件检查["issues"]]
+ [{"side": "lineage", **e} for e in 回放["issues"]]
)
return {
"source_count": len(快照),
"distinct_source_count": len(已见),
"states": dict(状态),
"issues": 总问题,
"file_checks": 文件检查,
"pg_checks": {"passed": not 问题, "issues": 问题},
"lineage_replay": 回放,
"data_checks_passed": not 总问题,
"production_switch_authorized": False,
"package_acceptance_claimed": False,
}