diff --git a/.gitea/issue_template/task.md b/.gitea/issue_template/task.md index 275226f..423b407 100644 --- a/.gitea/issue_template/task.md +++ b/.gitea/issue_template/task.md @@ -11,6 +11,15 @@ - 是否允许与前置工单并行:是 / 否 - 原因: +## 子项目影响 + + + +- 仅影响的子项目 / 交付单元: +- 是否跨子项目:是 / 否 +- 是否修改共享接口或契约:是 / 否;唯一事实来源: +- 各子项目需要执行的验证: + ## 原始需求 - 来源:用户对话 / Gitea / 其他 diff --git a/dev_scripts/check_harness.py b/dev_scripts/check_harness.py index 2628489..159b811 100644 --- a/dev_scripts/check_harness.py +++ b/dev_scripts/check_harness.py @@ -42,6 +42,7 @@ CORE_DOCUMENT_REQUIREMENTS = { ), "docs/00-project-profile.md": ( "## 基本信息", + "## 子项目与交付单元", "## 技术栈与运行环境", "## 阅读入口", "## 常用命令", @@ -89,13 +90,18 @@ CORE_DOCUMENT_REQUIREMENTS = { ), "docs/07-new-project-documentation-setup.md": ( "## 初始化顺序", - "### 5. 确定交付对象和文档", + "### 2. 识别子项目与交付单元", + "### 6. 确定交付对象和文档", "## 完成标准", ), "docs/08-existing-project-adoption.md": ( "## 与新项目初始化的区别", "## 接入前只读盘点", "## 已有内容保护原则", + "## 多应用单仓库判断", + "### 适合继续单仓库", + "### 可以考虑拆仓", + "### 保持单仓库时的最小规则", "## 增量接入顺序", "## 冲突处理和停止条件", "## 可复制 Agent 指令", @@ -206,6 +212,11 @@ def check_task_template(errors: list[str], root: Path = ROOT) -> None: "- 前置工单:无 / #编号", "- 是否允许与前置工单并行:是 / 否", "- 原因:", + "## 子项目影响", + "- 仅影响的子项目 / 交付单元:", + "- 是否跨子项目:是 / 否", + "- 是否修改共享接口或契约:是 / 否;唯一事实来源:", + "- 各子项目需要执行的验证:", "## 原始需求", "- 来源:用户对话 / Gitea / 其他", "- 提出时间:", diff --git a/docs/00-project-profile.md b/docs/00-project-profile.md index 89cd963..b5b5495 100644 --- a/docs/00-project-profile.md +++ b/docs/00-project-profile.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Project-Profile wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Project-Profile.- -wiki_revision: 2a81c9e4508cf6594f90d0b54368ec1f8a3be220 -synchronized_at: 2026-08-08T01:16:47Z +wiki_revision: c35c1737161ea428c487c066cb39eba4923535d2 +synchronized_at: 2026-08-10T11:02:51Z # 项目档案 @@ -23,6 +23,18 @@ synchronized_at: 2026-08-08T01:16:47Z | 主要维护者 | `ila` | | 文档适用范围 | 默认分支当前版本;具体镜像 revision 见每个本地文件头 | +## 子项目与交付单元 + +“子项目”是仓库中具有明确职责和规则边界的应用或模块;“交付单元”是能够独立构建、测试、版本化或发布的程序、服务、库或文档包。一个子项目可以对应一个交付单元,也可以包含多个交付单元。 + +| 子项目 / 交付单元 | 职责 | 技术栈 | 构建与测试 | 版本与发布方式 | 规则入口 | 共享边界 | +|---|---|---|---|---|---|---| +| DevHarness 模板 | 提供 Agent 开发流程、Wiki 镜像和结构检查 | Markdown、Python 3 标准库、Gitea 1.25 | `python dev_scripts/check_harness.py --strict`;`python -m unittest discover -s tests -v` | 跟随仓库 `main` 分支,不单独发布产品程序 | 根目录 `AGENTS.md` | Gitea 工单、Wiki、Git 和 `docs/` 的事实来源边界 | + +单应用项目只填写一行。多应用单仓库必须逐个填写,并为技术栈、构建测试或安全规则不同的目录增加子目录 `AGENTS.md`。技术栈不同不等于必须拆分 Git 仓库;是否拆仓应根据团队、权限、发布周期、仓库效率、复用关系和共享接口稳定性判断。 + +跨子项目接口或契约必须指定唯一事实来源,并说明各交付单元的兼容范围和验证命令。不得在多个页面维护互不确认的“权威版本”。 + ## 技术栈与运行环境 | 部分 | 技术 | 规则文件 | diff --git a/docs/07-new-project-documentation-setup.md b/docs/07-new-project-documentation-setup.md index 7c487da..969cba9 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: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/New-Project-Documentation-Setup.- -wiki_revision: 710503a62b7a4ebd3c9d7a1a08dbd398161595d0 -synchronized_at: 2026-08-10T06:23:35Z +wiki_revision: a443c206780ecd40ae45732ca10686427f393349 +synchronized_at: 2026-08-10T11:03:03Z # 新项目文档初始化 @@ -26,11 +26,25 @@ synchronized_at: 2026-08-10T06:23:35Z 把项目专用红线写入根目录或子目录 `AGENTS.md`。 -### 2. 建立 Gitea +### 2. 识别子项目与交付单元 + +先判断仓库中有几个应用、服务、客户端、库或其他可独立交付的部分。对每个部分确认: + +- 职责和目录边界; +- 技术栈、依赖和支持环境; +- 构建、测试和运行命令; +- 是否拥有独立版本号和发布方式; +- 适用的根目录或子目录 `AGENTS.md`; +- 与其他子项目共享的接口、数据或业务流程; +- 共享契约的唯一事实来源和兼容要求。 + +把结果写入 Project-Profile 的“子项目与交付单元”。单应用项目只填写一个交付单元;多应用单仓库为规则不同的目录增加子目录 `AGENTS.md`,但不因为技术栈不同自动拆仓,也不强制统一版本和发布周期。 + +### 3. 建立 Gitea 创建远端仓库并完成允许的初始引导提交。开启工单和 Wiki。任何产品功能开发在引导提交后都必须先有单元任务工单。 -### 3. 修改镜像配置 +### 4. 修改镜像配置 把 `wiki-docs.json` 中的地址、owner 和 repository 改成新项目;核心主题映射保留。 @@ -38,7 +52,7 @@ synchronized_at: 2026-08-10T06:23:35Z 不要把 PAT 写入配置。 -### 4. Agent 检查项目事实 +### 5. Agent 检查项目事实 Agent 只读检查: @@ -51,7 +65,7 @@ Agent 只读检查: 区分“代码中确认的事实”“负责人确认的业务规则”和“仍待确认的假设”。 -### 5. 确定交付对象和文档 +### 6. 确定交付对象和文档 由项目负责人确认哪些岗位或客户会实际使用、部署、管理、支持、集成或验收产品,并为每类对象确定: @@ -63,7 +77,7 @@ Agent 只读检查: 按照[交付文档指南](Delivery-Documentation-Guide.-)选择文档,使用[岗位文档模板](Audience-Document-Template.-)按需创建。没有明确读者的文档不创建,不预建空白的用户手册、管理员手册或运维手册。 -### 6. 先创建线上 Wiki +### 7. 先创建线上 Wiki 至少创建或填写: @@ -81,7 +95,7 @@ Agent 只读检查: Home 给出建议阅读顺序;每个命令必须有预期结果;代码地图必须指出入口和测试位置。具体岗位文档仅按第 5 步确认的受众创建。 -### 7. 人工确认 +### 8. 人工确认 项目负责人至少确认: @@ -92,7 +106,7 @@ Home 给出建议阅读顺序;每个命令必须有预期结果;代码地图 - 哪些修改属于高风险; - 交付对象、文档可见范围和外部信息边界。 -### 8. 导出镜像并检查 +### 9. 导出镜像并检查 ```powershell python dev_scripts/sync_wiki_docs.py @@ -112,6 +126,8 @@ python -m unittest discover -s tests -v - 常用功能从哪个目录和入口开始读; - 一个简单修改通常要改哪里、验证什么; - 哪些情况必须停止并交给 Agent 或负责人; +- 项目包含哪些子项目和独立交付单元,各自怎样构建、测试和发布; +- 跨子项目共享什么接口或契约,其唯一事实来源在哪里; - 项目需要向哪些岗位交付什么文档,以及哪些内容不能对外提供。 回答不了的问题应继续补充主题文档,而不是堆入任务归档。 diff --git a/docs/08-existing-project-adoption.md b/docs/08-existing-project-adoption.md index 02631d0..e362311 100644 --- a/docs/08-existing-project-adoption.md +++ b/docs/08-existing-project-adoption.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Existing-Project-Adoption-Guide wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Existing-Project-Adoption-Guide.- -wiki_revision: cad12048c8aa6f54ec6d2595a79c814233e18285 -synchronized_at: 2026-08-10T06:59:09Z +wiki_revision: 5c187a1d1cc215c632fcc26b2a4c6df735af5d92 +synchronized_at: 2026-08-10T11:03:05Z # 已有项目接入 DevHarness 指南 @@ -62,6 +62,39 @@ Agent 在提出方案前只读检查: - 不把密码、令牌、Cookie、私钥、个人数据或生产数据带入工单、Wiki和镜像。 - 页面删除、重命名、历史清理和事实来源切换必须单独确认。 +## 多应用单仓库判断 + +一个 Git 仓库可以包含多个技术栈不同、能够独立构建和发布的应用或终端。技术栈不同本身不是拆仓理由;先把每个子项目和交付单元记录到 Project-Profile,再根据实际协作边界判断。 + +### 适合继续单仓库 + +- 多个应用共同完成一条产品或业务链路; +- 由同一团队维护,仓库权限基本一致; +- 接口变更需要在一个工单中同步修改或验证多端; +- 共享契约、业务规则和任务归档放在一起更容易保持一致; +- 仓库体积、测试时间和工具性能尚未明显影响开发; +- 初级维护者和 Agent 能通过目录、子目录 `AGENTS.md` 和文档入口清楚定位。 + +### 可以考虑拆仓 + +- 长期由不同团队独立负责并需要不同访问权限; +- 发布周期、版本策略和验收负责人已经完全独立; +- 某个应用被多个产品复用或需要单独对外提供; +- 仓库体积、检出、索引或测试耗时已经持续影响效率; +- 共享接口已经版本化、兼容周期明确,并有跨仓契约测试; +- 跨应用任务很少,拆仓后的协调成本低于继续共仓。 + +不满足这些条件时,优先保持单仓库并完善边界,不为了目录整洁或技术栈不同而拆仓。 + +### 保持单仓库时的最小规则 + +- 根目录 `AGENTS.md` 只放共同流程、安全和跨项目规则,技术栈专用规则写入子目录 `AGENTS.md`。 +- 每个交付单元拥有自己的构建、测试、版本和发布方式,不强制统一版本。 +- 单元任务必须声明只影响哪个子项目、是否跨子项目、是否修改共享接口,以及各端需要执行的验证。 +- 共享接口或契约只能指定一个事实来源;其他文档引用它,不复制一个“差不多”的版本。 +- 跨子项目契约变更在同一工单中更新事实来源,并验证所有受影响端。 +- 拆仓属于事实来源、任务和发布边界变化,必须另建工单、确认迁移和回退方案后实施。 + ## 增量接入顺序 ### 1. 确认差异方案 @@ -151,6 +184,8 @@ Agent 在提出方案前只读检查: ## 最小验收清单 - [ ] 已盘点规则、文档、任务、Git 历史和未提交改动。 +- [ ] 已识别所有子项目和独立交付单元。 +- [ ] 跨子项目共享契约已经指定唯一事实来源。 - [ ] 已明确复用、改写、冲突和暂不处理内容。 - [ ] 已保留项目专用规则、历史和无关改动。 - [ ] 未复制 DevHarness 历史归档或模板项目事实。 diff --git a/tests/test_harness_docs.py b/tests/test_harness_docs.py index 61a9b1f..649a02e 100644 --- a/tests/test_harness_docs.py +++ b/tests/test_harness_docs.py @@ -97,6 +97,24 @@ class TaskTemplateTests(unittest.TestCase): errors, ) + def test_task_template_requires_subproject_impact(self) -> None: + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + template = root / ".gitea" / "issue_template" / "task.md" + template.parent.mkdir(parents=True) + template.write_text("## 基本信息\n", encoding="utf-8") + errors: list[str] = [] + check_task_template(errors, root) + self.assertIn("单元任务模板缺少:## 子项目影响", errors) + self.assertIn( + "单元任务模板缺少:- 是否跨子项目:是 / 否", + errors, + ) + self.assertIn( + "单元任务模板缺少:- 是否修改共享接口或契约:是 / 否;唯一事实来源:", + errors, + ) + def test_task_template_requires_dependency_fields(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory)