From 89ca159b6099c20b3aa45edd291cc265431c27df Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Mon, 17 Aug 2026 11:24:16 +0800 Subject: [PATCH] docs: require online Wiki initialization before coding (#20) --- AGENTS.md | 8 ++++++ README.md | 12 +++++---- dev_scripts/check_harness.py | 29 ++++++++++++++++++++++ docs/01-workflow.md | 15 +++++++++-- docs/07-new-project-documentation-setup.md | 17 ++++++++++--- docs/09-product-requirements-overview.md | 6 ++--- tests/test_harness_docs.py | 25 +++++++++++++++++++ 7 files changed, 99 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7c97b20..01053c6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,6 +42,14 @@ Gitea 不可用时,输出完整工单草稿并说明阻塞。未经用户明确授权,不得默认绕过建单。 +### 新项目 Wiki 初始化门禁 + +- 从本模板创建新项目时,先创建 Gitea 远端仓库并启用工单和 Wiki,再配置 `wiki-docs.json`;不得把模板自带的本地 `docs/` 当作新项目 Wiki 已初始化的证据。 +- 优先使用项目已配置的 Gitea MCP 查询和写入 Wiki;MCP 不可用或不支持所需写操作时,才使用 Gitea API,并在初始化工单记录回退原因。凭据只从环境或 MCP 安全配置读取。 +- 先查询线上页面列表;`Home` 不存在时必须先创建 `Home`,在线回读正文并记录 revision,然后再逐页创建或更新其他核心映射页面。 +- 每个核心页面写入后必须在线回读并取得 revision。页面缺失、回读失败或没有 revision 时停止初始化,不得开始产品代码。 +- 产品编码前必须运行 `python dev_scripts/sync_wiki_docs.py`、`python dev_scripts/check_harness.py --strict` 和 `python dev_scripts/sync_wiki_docs.py --check`;全部成功才表示线上 Wiki 和核心镜像初始化完成。 + ### 工单与设计证据双门禁 - 纯界面显示文案只有在不改变业务含义、流程、权限、状态、接口、数据、法律/安全/支付/单位等高风险含义、国际化键、程序标识符、布局和可访问性,且没有任何不确定时,才免工单和原型;修改后执行最小界面检查。 diff --git a/README.md b/README.md index cd45e2e..c04f8da 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,17 @@ DevHarness 是一个以 Gitea 工单管理任务过程、以 Gitea Wiki 管理 ## 快速开始 1. 复制或克隆本仓库,并修改仓库名称。 -2. 按 [新项目文档初始化](docs/07-new-project-documentation-setup.md) 在 Gitea Wiki 填写项目档案和核心主题页。 -3. 把项目不可违反的安全规则写入根目录或子项目的 `AGENTS.md`。 -4. 创建 Gitea 远端仓库并推送当前引导提交。 -5. 配置 `wiki-docs.json` 的页面映射;读取 Wiki 可匿名访问或使用 `GITEA_TOKEN`,写 Wiki 必须通过环境变量提供令牌。 -6. 使用 `.gitea/issue_template/` 中的模板创建第一个 Epic、MVP 和单元任务。 +2. 创建 Gitea 远端仓库并推送当前引导提交,启用工单和 Wiki。 +3. 配置 `wiki-docs.json` 和安全访问方式;优先使用已配置的 Gitea MCP,MCP 不可用时才使用 Gitea API 并记录原因。令牌只通过环境变量或 MCP 安全配置提供。 +4. 按 [新项目文档初始化](docs/07-new-project-documentation-setup.md) 查询线上 Wiki;`Home` 不存在时先创建并回读 `Home`,取得 revision 后再创建其他核心页面。 +5. 把项目不可违反的安全规则写入根目录或子项目的 `AGENTS.md`。 +6. 使用 `.gitea/issue_template/` 中的模板创建第一个 Epic、MVP 和单元任务。本地 `docs/` 的存在不能证明线上 Wiki 已初始化。 7. 开始产品代码前运行: ```powershell + python dev_scripts/sync_wiki_docs.py python dev_scripts/check_harness.py --strict + python dev_scripts/sync_wiki_docs.py --check ``` 新仓库在 Gitea 尚未建立前允许一次不关联工单的引导提交。远端和工单系统配置完成后,所有改变程序行为的工作都必须先有单元任务工单。 diff --git a/dev_scripts/check_harness.py b/dev_scripts/check_harness.py index 6eab498..8d7cc1c 100644 --- a/dev_scripts/check_harness.py +++ b/dev_scripts/check_harness.py @@ -53,6 +53,7 @@ CORE_DOCUMENT_REQUIREMENTS = { "## 环境、配置与凭据", ), "docs/01-workflow.md": ( + "## 新项目 Wiki 初始化门禁", "## 工单与设计证据双门禁", "### 先判断是否需要工单", "### 再判断设计证据", @@ -103,6 +104,7 @@ CORE_DOCUMENT_REQUIREMENTS = { "#### 判断案例", "### 3. 识别子项目与交付单元", "### 7. 确定交付对象和文档", + "#### 在线创建与回读门禁", "## 完成标准", ), "docs/08-existing-project-adoption.md": ( @@ -297,6 +299,9 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None: "高风险修改必须停止", "用户没有明确验收通过前不得关闭", "长期核心文档必须先修改 Wiki", + "### 新项目 Wiki 初始化门禁", + "`Home` 不存在时必须先创建 `Home`", + "不得把模板自带的本地 `docs/` 当作新项目 Wiki 已初始化的证据", "提交只包含当前工单相关文件", "### 工单与设计证据双门禁", "新页面、独立用户功能、重大交互或导航变化", @@ -321,6 +326,29 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None: errors.append(f"AGENTS.md 缺少:{section}") +def check_repository_readme(errors: list[str], root: Path = ROOT) -> None: + """检查快速开始包含线上 Wiki 初始化顺序和产品编码门禁。""" + + path = root / "README.md" + if not path.is_file(): + return + content = path.read_text(encoding="utf-8") + required = ( + "创建 Gitea 远端仓库并推送当前引导提交,启用工单和 Wiki", + "优先使用已配置的 Gitea MCP", + "`Home` 不存在时先创建并回读 `Home`", + "本地 `docs/` 的存在不能证明线上 Wiki 已初始化", + "python dev_scripts/sync_wiki_docs.py --check", + ) + for section in missing_sections(content, required): + errors.append(f"README.md 缺少:{section}") + + remote_index = content.find("创建 Gitea 远端仓库") + wiki_index = content.find("`Home` 不存在时先创建") + if remote_index < 0 or wiki_index < 0 or remote_index > wiki_index: + errors.append("README.md 必须先创建 Gitea 远端,再创建 Wiki Home") + + def check_claude_code_entry(errors: list[str], root: Path = ROOT) -> None: """检查 Claude Code 入口直接复用共同 Agent 规则。""" @@ -415,6 +443,7 @@ def main() -> int: check_core_documents(errors) check_task_template(errors) check_agent_efficiency_rules(errors) + check_repository_readme(errors) check_claude_code_entry(errors) check_archives(errors) diff --git a/docs/01-workflow.md b/docs/01-workflow.md index fb678e1..bcd06e7 100644 --- a/docs/01-workflow.md +++ b/docs/01-workflow.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Development-Workflow wiki_url: https://git.ilapage.cn/OPC/dev_harness/wiki/Development-Workflow.- -wiki_revision: 3fa437209777476101dc709444c4fe7a0015b76a -synchronized_at: 2026-08-17T02:17:54Z +wiki_revision: a9f7cf4014129840e0772b8f951da82b9573e4e5 +synchronized_at: 2026-08-17T03:21:38Z # 开发工作流 @@ -15,6 +15,17 @@ synchronized_at: 2026-08-17T02:17:54Z - Git 保存源码、与特定代码版本强绑定的文档,以及 Wiki 的本地镜像。 - 本地 `docs/` 仅供浏览和审查,不是长期文档编辑入口。 +## 新项目 Wiki 初始化门禁 + +从 DevHarness 创建新项目时,本地 `docs/` 即使完整存在,也只能证明模板镜像存在,不能证明新项目的线上 Wiki 已初始化。开始任何产品代码前必须完成以下闭环: + +1. 先创建 Gitea 远端仓库并启用 Wiki,再把 `wiki-docs.json` 指向该仓库。 +2. 优先使用项目已配置的 Gitea MCP 查询 Wiki 页面;MCP 不可用或不支持所需写操作时,才使用 Gitea API,并在初始化工单记录回退原因。凭据只从环境或 MCP 安全配置读取。 +3. 查询线上页面列表;没有 `Home` 时先创建 `Home`,回读正文并记录 revision,然后再创建或更新其他核心映射页面。 +4. 每个核心页面写入后都要在线回读;页面可读取且取得 revision 才算创建成功,不能用本地 `docs/` 文件替代这项证据。 +5. 运行 `python dev_scripts/sync_wiki_docs.py`、`python dev_scripts/check_harness.py --strict` 和 `python dev_scripts/sync_wiki_docs.py --check`。任一映射页面不存在、无法回读或镜像不一致时,停止产品编码并完成初始化。 + +Gitea 暂时不可用时可以准备工单和 Wiki 草稿,但不得把本地草稿宣称为线上事实,也不得绕过此门禁开始产品功能开发。 ## 工单与设计证据双门禁 开始正式实现前依次判断“是否需要工单”和“需要什么设计证据”。原型确认不能代替方案、工单、安全检查或技术验证;工单存在也不能绕过原型确认。 diff --git a/docs/07-new-project-documentation-setup.md b/docs/07-new-project-documentation-setup.md index 31a9117..c82d67f 100644 --- a/docs/07-new-project-documentation-setup.md +++ b/docs/07-new-project-documentation-setup.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: New-Project-Documentation-Setup wiki_url: https://git.ilapage.cn/OPC/dev_harness/wiki/New-Project-Documentation-Setup.- -wiki_revision: 8c70a393a0537b94091224d00363fc61edadb1b6 -synchronized_at: 2026-08-17T01:58:11Z +wiki_revision: 47b78d0fcba529ad677b8d208da4b5f1b2ccc971 +synchronized_at: 2026-08-17T03:21:52Z # 新项目文档初始化 @@ -102,7 +102,9 @@ synchronized_at: 2026-08-17T01:58:11Z ### 4. 建立 Gitea -创建远端仓库并完成允许的初始引导提交。开启工单和 Wiki。任何产品功能开发在引导提交后都必须先有单元任务工单。 +创建远端仓库并完成允许的初始引导提交,开启工单和 Wiki;必须先有远端仓库,才能填写该仓库的线上 Wiki。配置项目已有的 Gitea MCP 和安全凭据;优先使用 MCP,MCP 不可用或不支持所需写操作时才回退到 Gitea API,并在初始化工单记录原因。凭据只通过环境或 MCP 安全配置提供。 + +任何产品功能开发在引导提交后都必须先有单元任务工单,并且必须通过第 8 步的线上 Wiki 初始化门禁。 ### 5. 修改镜像配置 @@ -139,6 +141,13 @@ Agent 只读检查: ### 8. 先创建线上 Wiki +#### 在线创建与回读门禁 + +1. 使用配置好的 Gitea MCP 查询目标仓库的 Wiki 页面列表;MCP 不可用时使用 Gitea API,并记录回退原因。 +2. 如果 `Home` 不存在,先创建 `Home`。创建后立即在线回读正文并记录 revision;`Home` 可读取后才能继续。 +3. 依照 `wiki-docs.json` 逐页创建或更新其他核心页面。每页写入后在线回读正文,记录页面名和 revision。 +4. 本地 `docs/` 是模板或 Wiki 镜像;本地文件存在、标题完整或 `check_harness.py --strict` 通过,都不能单独证明线上 Wiki 已初始化。 +5. 页面缺失、回读失败或没有 revision 时停止初始化,不得开始产品代码;Gitea 恢复后从首个失败页面继续。 至少创建或填写: 1. Home; @@ -178,6 +187,8 @@ python -m unittest discover -s tests -v 只有线上 Wiki 确认后才导出核心 `docs/`。任务归档默认不导出;用户明确要求时再运行 `python dev_scripts/export_task_archives.py` 或加 `--all`。旧项目的任务归档快照不能带入新项目历史。 +`sync_wiki_docs.py --check` 会在线读取全部显式映射页面;任一页面不存在、无法读取或 revision 与镜像不一致时,初始化不通过。只有上述命令全部成功后才允许开始产品代码。 + ## 完成标准 初级程序员应能仅依靠 Home 和链接页面回答: diff --git a/docs/09-product-requirements-overview.md b/docs/09-product-requirements-overview.md index d0d43a9..5a553a7 100644 --- a/docs/09-product-requirements-overview.md +++ b/docs/09-product-requirements-overview.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Product-Requirements-Overview wiki_url: https://git.ilapage.cn/OPC/dev_harness/wiki/Product-Requirements-Overview.- -wiki_revision: 1cf7515c3dd9d98f633cdb7fad27113c11449e5b -synchronized_at: 2026-08-17T02:32:05Z +wiki_revision: 0d4b83f7e4d600614f5067fbec667d158a870d01 +synchronized_at: 2026-08-17T03:21:58Z # 产品需求总览 @@ -31,7 +31,7 @@ synchronized_at: 2026-08-17T02:32:05Z | 需求领域 | 用户与场景 | 状态 | 版本 / MVP | 详细说明 | 实施工单 | 原型 | 验收入口 | |---|---|---|---|---|---|---|---| -| 文档事实来源与需求追溯 | 负责人和 Agent 需要从需求到实现、验收可追溯 | 已交付 | 模板核心 | [开发工作流](Development-Workflow.-) | [#1](https://git.ilapage.cn/OPC/dev_harness/issues/1)、[#10](https://git.ilapage.cn/OPC/dev_harness/issues/10)、[#14](https://git.ilapage.cn/OPC/dev_harness/issues/14) | 无(流程文档) | [#1 归档](Task-1-Wiki-文档主源)、[#10 归档](Task-10-需求记录与流转规则)、[#14 归档](Task-14-任务归档按需导出) | +| 文档事实来源与需求追溯 | 负责人和 Agent 需要从需求到实现、验收可追溯 | 开发中(Wiki 初始化门禁) | 模板核心 | [开发工作流](Development-Workflow.-) | [#1](https://git.ilapage.cn/OPC/dev_harness/issues/1)、[#10](https://git.ilapage.cn/OPC/dev_harness/issues/10)、[#14](https://git.ilapage.cn/OPC/dev_harness/issues/14)、[#20](https://git.ilapage.cn/OPC/dev_harness/issues/20) | 无(流程文档) | [#1 归档](Task-1-Wiki-文档主源)、[#10 归档](Task-10-需求记录与流转规则)、[#14 归档](Task-14-任务归档按需导出) | | 初级维护者文档 | 初级程序员需要理解项目并处理简单修改 | 已交付 | 模板核心 | [项目档案](Project-Profile.-)、[代码地图](Architecture-and-Code-Map.-)、[常见修改](Common-Changes.-) | [#2](https://git.ilapage.cn/OPC/dev_harness/issues/2)、[#3](https://git.ilapage.cn/OPC/dev_harness/issues/3) | 无(流程文档) | [#2 归档](Task-2-Junior-Maintainer-Docs)、[#3 归档](Task-3-Dev-Scripts-Rename) | | Agent 范围、效率和 Claude 协作 | Agent 按确认范围实施并选择合适模型 | 已交付(原型门禁) | 模板核心 | [开发工作流](Development-Workflow.-)、仓库 `AGENTS.md` 和 `CLAUDE.md` | [#4](https://git.ilapage.cn/OPC/dev_harness/issues/4)–[#9](https://git.ilapage.cn/OPC/dev_harness/issues/9)、[#19](https://git.ilapage.cn/OPC/dev_harness/issues/19) | 无(流程文档) | 对应 `Task-4` 至 `Task-9` Wiki 归档;[#19 归档](Task-19-UI原型确认与文字修改双门禁) | | 交付文档 | 其他岗位和客户需要与版本匹配的使用、部署或支持说明 | 待验收 | 模板核心 | [交付文档指南](Delivery-Documentation-Guide.-)、[岗位文档模板](Audience-Document-Template.-) | [#11](https://git.ilapage.cn/OPC/dev_harness/issues/11) | 无(文档模板) | [#11 归档](Task-11-交付文档指南与岗位文档模板) | diff --git a/tests/test_harness_docs.py b/tests/test_harness_docs.py index 4d67a1e..b199e17 100644 --- a/tests/test_harness_docs.py +++ b/tests/test_harness_docs.py @@ -16,6 +16,7 @@ from check_harness import ( # noqa: E402 check_claude_code_entry, check_core_documents, check_agent_efficiency_rules, + check_repository_readme, check_task_template, core_mapping_errors, missing_sections, @@ -78,6 +79,14 @@ class CoreDocumentTests(unittest.TestCase): self.assertIn("### 再判断设计证据", required) self.assertIn("### 记录和重新确认", required) + def test_workflow_requires_online_wiki_initialization_gate(self) -> None: + workflow = CORE_DOCUMENT_REQUIREMENTS["docs/01-workflow.md"] + setup = CORE_DOCUMENT_REQUIREMENTS[ + "docs/07-new-project-documentation-setup.md" + ] + self.assertIn("## 新项目 Wiki 初始化门禁", workflow) + self.assertIn("#### 在线创建与回读门禁", setup) + def test_existing_project_adoption_requires_upgrade_process(self) -> None: required = CORE_DOCUMENT_REQUIREMENTS[ "docs/08-existing-project-adoption.md" @@ -223,6 +232,22 @@ class AgentRuleTests(unittest.TestCase): check_agent_efficiency_rules(errors) self.assertEqual(errors, []) + def test_repository_readme_requires_online_wiki_gate(self) -> None: + errors: list[str] = [] + check_repository_readme(errors) + self.assertEqual(errors, []) + + def test_repository_readme_rejects_missing_gate(self) -> None: + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + (root / "README.md").write_text( + "# 项目\n创建 Gitea 远端仓库\n", + encoding="utf-8", + ) + errors: list[str] = [] + check_repository_readme(errors, root) + self.assertTrue(any("README.md 缺少" in error for error in errors)) + def test_claude_code_entry_imports_shared_rules(self) -> None: errors: list[str] = [] check_claude_code_entry(errors)