- 迁移:调用结算与配置验证(V0056)、来源当前授权(V0057)、成品补充验证回执(V0058)、检索索引代次(V0059)、 评测单元复用来源(V0060);新表按既有约定加只追加守卫与角色授权。 - 流程模板与载入口径同步(内联保护字段改为登记类型约束);旧库迁移工具链按新表结构对齐。 - 配置:提供方模板与运行配置同步角色策略版本;角色策略白名单新增 qwen3.8-flash(见收尾报告待裁决项: 该模型精确身份与独立性尚未核验,且策略版本号未随白名单升版)。
104 lines
4.6 KiB
Python
104 lines
4.6 KiB
Python
"""只读逐项对账:原输入、不可变台账、真实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,
|
||
}
|