日常更新

This commit is contained in:
2026-03-29 09:08:01 +08:00
parent 31709425e2
commit befdefd222
224 changed files with 7240 additions and 3297 deletions

View File

@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""校验执行域 verify/doc/files 一致性。
该脚本是“离线门禁”的一部分:发现 doc_id 三元契约不一致时应 fail-fast
并输出可定位的冲突清单doc_id + 路径集合)。
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent.parent
VERIFY_DIR = ROOT / "ansible" / "playbooks" / "verify"
DOCS_DIR = ROOT / "docs"
EXEC_ID_RE = re.compile(r"^(0[1-9]|[1-9][0-9])-(0[1-9]|[1-9][0-9])$")
def is_exec_domain(doc_id: str) -> bool:
return EXEC_ID_RE.fullmatch(doc_id) is not None
def main() -> None:
if not VERIFY_DIR.is_dir() or not DOCS_DIR.is_dir():
print("ERR: verify/docs 目录缺失", file=sys.stderr)
sys.exit(2)
# --- scan verify playbooks (.yml/.yaml) ---
verify_by_doc_id: dict[str, list[Path]] = {}
invalid_verify_names: list[str] = []
for p in sorted(VERIFY_DIR.iterdir()):
if not p.is_file():
continue
if p.name.startswith("_"):
# private helpers are allowed but not part of doc_id contract
continue
if p.suffix not in {".yml", ".yaml"}:
continue
# Only accept <doc_id>.yml|yaml
stem = p.stem
if len(stem) != len("00-00") or stem[2:3] != "-":
invalid_verify_names.append(p.name)
continue
if not is_exec_domain(stem):
invalid_verify_names.append(p.name)
continue
verify_by_doc_id.setdefault(stem, []).append(p)
# Same doc_id with multiple verify entrypoints is a hard conflict (EC1).
verify_conflicts: dict[str, list[str]] = {}
for did, paths in verify_by_doc_id.items():
if len(paths) > 1:
verify_conflicts[did] = [str(p.relative_to(ROOT)) for p in sorted(paths)]
missing_docs: list[str] = []
missing_files_dir: list[str] = []
weak_doc_exec_refs: list[str] = []
multi_docs: dict[str, list[str]] = {}
for did in sorted(verify_by_doc_id.keys()):
matches = sorted(DOCS_DIR.glob(f"{did}-*.md"))
if not matches:
missing_docs.append(did)
continue
if len(matches) > 1:
multi_docs[did] = [str(p.relative_to(ROOT)) for p in matches]
doc = matches[0]
content = doc.read_text(encoding="utf-8", errors="ignore")
if f"ansible/files/{did}/" not in content and "```yaml" in content:
weak_doc_exec_refs.append(did)
# Execution-domain doc_id must always have a files truth-source directory (ADR-002 / R4).
if not (ROOT / "ansible" / "files" / did).is_dir():
missing_files_dir.append(did)
if invalid_verify_names:
print(f"ERR: verify 仅允许执行域命名: {sorted(invalid_verify_names)}", file=sys.stderr)
sys.exit(2)
if verify_conflicts:
print("ERR: verify 入口冲突(同一 doc_id 多个入口,必须 fail-fast:", file=sys.stderr)
for did in sorted(verify_conflicts.keys()):
paths = verify_conflicts[did]
print(f" - {did}: {paths}", file=sys.stderr)
sys.exit(2)
if missing_docs:
print(f"ERR: 缺少 docs/<doc_id>-*.md: {missing_docs}", file=sys.stderr)
sys.exit(2)
if multi_docs:
print("ERR: docs 命名冲突(同一 doc_id 匹配到多篇 docs/<doc_id>-*.md:", file=sys.stderr)
for did in sorted(multi_docs.keys()):
print(f" - {did}: {multi_docs[did]}", file=sys.stderr)
sys.exit(2)
if missing_files_dir:
print(f"ERR: 缺少 ansible/files/<doc_id>/ 目录: {missing_files_dir}", file=sys.stderr)
sys.exit(2)
if weak_doc_exec_refs:
print(f"ERR: 文档 YAML 未映射 ansible/files/<doc_id>/ 真源: {weak_doc_exec_refs}", file=sys.stderr)
sys.exit(2)
print(f"[OK] 执行域 verify/doc/files 一致性通过({len(verify_by_doc_id)} 条)")
if __name__ == "__main__":
main()