90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""上线与质保观察跟踪文档(docs/上线与质保观察跟踪.md,issue #93)一致性检查。
|
||
|
||
检查项:
|
||
1. 必备章节齐全(阶段定位/上线/质保观察/闭环/交付物/风险);
|
||
2. 验收流程最后三节点关键词存在(上线 / 质保观察 / 闭环,PRD §10);
|
||
3. NFR 量化指标齐全(可用性≥99.8% / 丢失率≤0.02% / P99≤1.8s / 路由≥96.5% / PSI≤0.2);
|
||
4. 回滚机制关键词存在(helm rollback / 回滚点,PRD §5.6 / §5.7);
|
||
5. 功能安全红线关键词存在(不直接联动执行机构 / 人工确认 / 只读,PRD §9);
|
||
6. 引用配套资产路径存在(healthz 探针)。
|
||
|
||
用法:python _check_golive_warranty.py
|
||
"""
|
||
import os
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
DOC_PATH = os.path.join(HERE, "上线与质保观察跟踪.md")
|
||
|
||
REQUIRED_SECTIONS = [
|
||
"## 1. 阶段定位与目标",
|
||
"## 2. 上线(Go-Live)",
|
||
"## 3. 1 个月质保观察(Warranty Observation)",
|
||
"## 4. 闭环交付(Closure)",
|
||
"## 5. 交付物清单(上线 → 闭环阶段)",
|
||
"## 6. 风险与缓解",
|
||
]
|
||
|
||
# PRD §10 验收流程后三节点
|
||
FLOW_KEYWORDS = ["上线", "质保观察", "闭环"]
|
||
|
||
# NFR / 模型质量量化底线
|
||
NFR_KEYWORDS = ["99.8%", "0.02%", "1.8s", "96.5%", "0.2"] # 0.2 = PSI 漂移阈值
|
||
|
||
# 回滚机制
|
||
ROLLBACK_KEYWORDS = ["helm rollback", "回滚点"]
|
||
|
||
# 功能安全红线(PRD §9 安全-功能安全 / 网络)
|
||
SAFETY_KEYWORDS = ["不直接联动执行机构", "人工确认", "只读"]
|
||
|
||
# 配套资产
|
||
ASSET_PATHS = ["deploy/k8s/healthz/probe_availability.py"]
|
||
|
||
|
||
def main() -> int:
|
||
failures = []
|
||
repo_root = os.path.dirname(HERE)
|
||
|
||
if not os.path.isfile(DOC_PATH):
|
||
print("FAIL\n - 文档不存在:上线与质保观察跟踪.md")
|
||
return 1
|
||
|
||
text = open(DOC_PATH, "r", encoding="utf-8").read()
|
||
|
||
for sec in REQUIRED_SECTIONS:
|
||
if sec not in text:
|
||
failures.append(f"缺少必备章节:{sec}")
|
||
|
||
for kw in FLOW_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少流程节点关键词:{kw}")
|
||
|
||
for kw in NFR_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少 NFR/模型量化指标关键词:{kw}")
|
||
|
||
for kw in ROLLBACK_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少回滚机制关键词:{kw}")
|
||
|
||
for kw in SAFETY_KEYWORDS:
|
||
if kw not in text:
|
||
failures.append(f"缺少功能安全红线关键词:{kw}")
|
||
|
||
for rel in ASSET_PATHS:
|
||
if not os.path.isfile(os.path.join(repo_root, *rel.split("/"))):
|
||
failures.append(f"配套资产缺失:{rel}")
|
||
|
||
if failures:
|
||
print("FAIL")
|
||
for f in failures:
|
||
print(" -", f)
|
||
return 1
|
||
print("OK: 上线与质保观察跟踪 章节/流程节点/NFR指标/回滚/功能安全/资产校验通过")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|