chore(workflow): adopt lightweight governance (#221)

This commit is contained in:
QiuSW
2026-09-05 12:14:14 +08:00
parent 003ab38a36
commit e91fc0cc28
18 changed files with 620 additions and 146 deletions
+59 -20
View File
@@ -67,6 +67,7 @@ CORE_DOCUMENT_REQUIREMENTS = {
),
"docs/00-project-profile.md": (
"## 基本信息",
"## 项目治理模式",
"## 建设基线",
"## 交付单元",
"## 文档事实来源",
@@ -74,6 +75,7 @@ CORE_DOCUMENT_REQUIREMENTS = {
"## 当前阶段",
),
"docs/01-workflow.md": (
"## 语言与术语",
"## 事实来源",
"## 权威源与事实边界",
"## Gitea 交互与工单最小读取",
@@ -102,6 +104,7 @@ CORE_DOCUMENT_REQUIREMENTS = {
),
"docs/04-local-development-and-verification.md": (
"## Windows PowerShell 与 UTF-8",
"### PowerShell 语法与外部命令",
"## 通用检查",
"## 服务端验证",
"## Web 验证",
@@ -271,9 +274,14 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None:
"#### 明确停止条件",
"单元任务是唯一正式实施单位",
"高风险修改必须停止",
"### 项目治理模式与明确授权后的执行",
"默认采用轻量治理",
"不能单独构成人工授权",
"不得仅因操作不可逆而重复询问或拒绝",
"平台自身强制的审批、安全策略或权限限制继续有效",
"用户没有明确验收通过前不得关闭",
"只有长期事实变化时才更新 Wiki",
"Gitea 工单是单次任务需求、变化、实现、测试、提交和验收的唯一事实来源",
"需要工单的任务以 Gitea 工单作为单次需求、变化、实现、测试、提交和验收的事实来源",
"Wiki 同步由长期事实变化触发,不由任务完成触发",
"标准流程不创建 Wiki 任务归档",
"工单默认只在开始实施、集中回写待验收、验收关闭三个节点更新",
@@ -289,6 +297,11 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None:
"不得把模板自带的本地 `docs/` 当作新项目 Wiki 已初始化的证据",
"提交只包含当前工单相关文件",
"不得仅为设置编码重复启动一层 PowerShell",
"不得默认套用 Bash",
"复杂正则优先使用变量或 `rg -e`",
"单引号 PowerShell here-string",
"`foreach`、`if` 等语句块",
"使用真实目录配合 `-g/--glob`",
"文件解码和控制台输出分别处理",
"不得默认使用 `-ExecutionPolicy Bypass`",
"### 工单与设计证据双门禁",
@@ -316,6 +329,9 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None:
"不得臆造用户原话",
"不复制完整聊天",
"Gitea 工单全文不导出到仓库",
"用户可以使用中文、英文或合理的中英混合语言交流",
"默认使用中文分析、回复、编写工单和维护内部项目文档",
"日志和错误原文保持原样",
)
for section in missing_sections(content, required):
errors.append(f"AGENTS.md 缺少:{section}")
@@ -562,32 +578,47 @@ def run_check(args: argparse.Namespace) -> int:
def run_sync(args: argparse.Namespace) -> int:
"""--verify 依次执行导出、结构检查和一致性校验,替代原来的三条命令。"""
"""同步核心镜像;--verify 复用本轮完整读取完成初始化验证。"""
if args.verify:
steps = (
("同步", lambda: run_sync(
argparse.Namespace(check=False, verify=False, config=args.config))),
("结构检查", lambda: run_check(argparse.Namespace(strict=True))),
("一致性校验", lambda: run_sync(
argparse.Namespace(check=True, verify=False, config=args.config))),
)
for name, step in steps:
code = step()
if code != 0:
print(f"错误:{name}未通过,已停止")
return code
try:
config = load_config(Path(args.config).resolve())
messages = sync_all(
config, WikiClient(config), check=False, deep_check=True
)
except WikiDocsError as exc:
print(f"错误:{exc}")
return 1
for message in messages:
print(message)
code = run_check(argparse.Namespace(strict=True))
if code != 0:
print("错误:结构检查未通过,已停止")
return code
print("Wiki 镜像初始化验证通过")
return 0
try:
config = load_config(Path(args.config).resolve())
messages = sync_all(config, WikiClient(config), check=args.check)
deep_check = getattr(args, "deep_check", False)
messages = sync_all(
config,
WikiClient(config),
check=args.check or deep_check,
deep_check=deep_check,
)
except WikiDocsError as exc:
print(f"错误:{exc}")
return 1
for message in messages:
print(message)
print("Wiki 镜像检查通过" if args.check else "Wiki 镜像同步完成")
print(
"Wiki 镜像深度检查通过"
if deep_check
else "Wiki 镜像检查通过"
if args.check
else "Wiki 镜像同步完成"
)
return 0
@@ -652,13 +683,21 @@ def main() -> int:
p_check.set_defaults(func=run_check)
p_sync = sub.add_parser("sync", help="从 Gitea Wiki 单向同步核心 docs 镜像")
p_sync.add_argument(
"--check", action="store_true", help="只检查 Wiki 与镜像是否一致,不写文件"
sync_mode = p_sync.add_mutually_exclusive_group()
sync_mode.add_argument(
"--check",
action="store_true",
help="按 revision 快速检查 Wiki 与镜像,不写文件",
)
p_sync.add_argument(
sync_mode.add_argument(
"--deep-check",
action="store_true",
help="下载全部 Wiki 正文并逐页检查镜像,不写文件",
)
sync_mode.add_argument(
"--verify",
action="store_true",
help="依次执行导出、check --strict 和一致性校验",
help="完整读取并导出 Wiki,再执行 check --strict 初始化验证",
)
p_sync.add_argument(
"--config", default=str(DEFAULT_CONFIG), help="Wiki 页面映射 JSON 文件"