diff --git a/.gitea/issue_template/task.md b/.gitea/issue_template/task.md index 998627f..63589ce 100644 --- a/.gitea/issue_template/task.md +++ b/.gitea/issue_template/task.md @@ -22,6 +22,17 @@ - +## 文档影响 + + + +- [ ] 不影响长期文档,原因: +- [ ] 更新项目档案或本地开发与验证 +- [ ] 更新架构与代码地图 +- [ ] 更新业务规则与术语 +- [ ] 更新常见修改或故障排查 +- [ ] 更新其他 Wiki 页面: + ## 验收标准 - [ ] diff --git a/AGENTS.md b/AGENTS.md index 9974779..2b1c3a6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,7 @@ ## 3. 需求到实施 1. 先复述目标,阅读相关代码、日志和文档,区分事实与假设。 -2. 给出目标、非目标、方案、影响范围、风险、回退方式和验证方法。 +2. 给出目标、非目标、方案、影响范围、风险、回退方式、验证方法和文档影响。 3. 方案没有得到用户明确确认前,只做只读诊断和方案整理,不实施正式代码。 4. 方案确认后,先建立单元任务工单,再修改代码。 5. 开始实施前检查分支和工作区,明确哪些现有改动不属于本任务。 @@ -95,6 +95,24 @@ MVP 内所有单元任务通过后才能做 MVP 集成验收;MVP 通过后才 - Wiki 文档先写结论和用途,再写步骤;示例命令应可直接复制,本地 `docs/` 由同步工具生成。 - 面向初级维护者说明从哪里开始读、怎样运行和怎样验证。 +### 初级维护者的修改边界 + +| 风险 | 示例 | 处理方式 | +|---|---|---| +| 低 | 文案、简单校验、查询条件、独立 UI、小范围回归 Bug | 初级程序员可在 Agent 协助下理解、修改和验证 | +| 中 | API、配置、依赖、跨模块逻辑、数据结构 | 由 Agent 实现,程序员检查差异并执行验证 | +| 高 | 权限、安全、并发、迁移、支付、删除数据、不可逆操作 | 停止修改,由 Agent 分析并等待人工确认 | + +风险按影响范围判断,不按代码行数判断。 + +### 核心文档与更新条件 + +- 新项目至少维护:新人入口、项目档案、架构与代码地图、业务规则与术语、本地开发与验证、常见修改、故障排查、开发工作流和任务归档模板。 +- 每个单元任务必须在工单中选择“无长期文档影响并说明原因”或列出需要更新的 Wiki 页面。 +- 启动、测试、部署、排错命令,模块入口、目录职责、主要调用路径,配置、API、数据结构、状态、业务规则、安全边界、日志位置发生变化时,必须更新对应 Wiki。 +- 普通内部重构只有在入口、行为、配置和验证方式均未改变时,才可以记录为不影响长期文档。 +- 稳定主题页描述项目现在怎样工作;工单和任务归档只解释某次为什么修改以及如何验证。新人不应依赖按时间阅读任务归档来理解当前系统。 + ## 9. 引导提交例外 从本模板创建全新仓库时,Gitea 远端和工单尚不存在,允许一次不带工单号的初始引导提交。该提交只能包含仓库骨架、Harness 规则和远端配置准备,不能包含产品功能。 diff --git a/CLAUDE.md b/CLAUDE.md index 0c3cb05..7e8e06d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,13 +6,15 @@ Claude Code 开始任何工作前,必须按顺序阅读: 1. 根目录的 `AGENTS.md`; 2. Gitea Wiki 的项目档案;Wiki 不可用时读取 `docs/00-project-profile.md` 镜像并明确其 revision; -3. 任务涉及目录中更具体的 `AGENTS.md`; -4. 当前 Gitea 工单及其父级 MVP、Epic 工单。 +3. Gitea Wiki 的架构与代码地图、业务规则,以及任务直接涉及的主题页; +4. 任务涉及目录中更具体的 `AGENTS.md`; +5. 当前 Gitea 工单及其父级 MVP、Epic 工单。 必须遵守以下入口规则: - 方案经用户确认并建立单元任务工单后,才能修改产品代码。 - 只修改当前工单范围内的文件,保留用户已有和无关的改动。 +- 在单元任务中明确文档影响;入口、命令、配置、数据、业务规则或排错方式变化时先更新对应 Wiki。 - 实现、测试、Git 提交、待验收、Wiki 任务归档、导出本地镜像和关闭工单的顺序不得跳过。 - 长期文档先修改 Wiki,再导出 `docs/`;不得直接编辑镜像作为最终结果。 - 未经用户明确验收,不得关闭工单。 diff --git a/README.md b/README.md index b97b0aa..b0d2a06 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ DevHarness 是一个以 Gitea 工单管理任务过程、以 Gitea Wiki 管理 ## 快速开始 1. 复制或克隆本仓库,并修改仓库名称。 -2. 在 Gitea Wiki 填写项目档案,再运行 `python scripts/sync_wiki_docs.py` 导出 [本地镜像](docs/00-project-profile.md)。 +2. 按 [新项目文档初始化](docs/07-new-project-documentation-setup.md) 在 Gitea Wiki 填写项目档案和核心主题页。 3. 把项目不可违反的安全规则写入根目录或子项目的 `AGENTS.md`。 4. 创建 Gitea 远端仓库并推送当前引导提交。 5. 配置 `wiki-docs.json` 的页面映射;读取 Wiki 可匿名访问或使用 `GITEA_TOKEN`,写 Wiki 必须通过环境变量提供令牌。 @@ -42,6 +42,7 @@ CLAUDE.md Claude Code 的规则入口 .gitea/issue_template/ Epic、MVP、单元任务工单模板 docs/00-project-profile.md Wiki 项目档案的只读镜像 docs/01-workflow.md Wiki 开发工作流的只读镜像 +docs/02-07*.md 代码地图、业务、验证、修改、排错和初始化镜像 docs/templates/task-archive.md Wiki 任务归档模板的只读镜像 docs/task/ Wiki 任务归档页的只读镜像 wiki-docs.json Wiki 页面到本地镜像的显式映射 diff --git a/docs/00-project-profile.md b/docs/00-project-profile.md index f0bd89e..24811af 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: 845266496196a4fc33462dfda779d0f899fa4c18 -synchronized_at: 2026-08-07T15:53:58Z +wiki_revision: df33a1ce9d25d28866e20d942799a5d01fcec935 +synchronized_at: 2026-08-08T00:58:02Z # 项目档案 @@ -16,17 +16,31 @@ synchronized_at: 2026-08-07T15:53:58Z |---|---| | 项目名称 | DevHarness | | 一句话目标 | 提供以 Gitea 工单、Wiki 和 Git 为事实来源的 AI 辅助开发工作流模板 | +| 主要使用者 | 项目负责人、Claude/Codex Agent、接手简单维护的初级程序员 | | Gitea 地址 | http://ilaer.eicp.net:8418 | | 仓库 | `opc/dev_harness` | | 默认分支 | `main` | | 主要维护者 | `ila` | +| 文档适用范围 | 默认分支当前版本;具体镜像 revision 见每个本地文件头 | -## 技术栈 +## 技术栈与运行环境 | 部分 | 技术 | 规则文件 | |---|---|---| -| Harness 规则和模板 | Markdown、Gitea | `AGENTS.md` | +| Harness 规则和模板 | Markdown、Gitea 1.25 | `AGENTS.md` | | Wiki 镜像与结构检查 | Python 3 标准库 | `AGENTS.md` | +| 主要开发环境 | Windows、PowerShell、Git | `AGENTS.md` | + +本项目不需要安装第三方 Python 包。复制到业务项目后,必须把真实语言、框架、版本和支持平台写入本节。 + +## 阅读入口 + +- 新人入口:Home。 +- 代码入口:[架构与代码地图](Architecture-and-Code-Map.-)。 +- 业务边界:[业务规则与术语](Business-Rules-and-Glossary.-)。 +- 运行验证:[本地开发与验证](Local-Development-and-Verification.-)。 +- 简单维护:[常见修改指南](Common-Changes.-)。 +- 错误定位:[故障排查](Troubleshooting)。 ## 常用命令 @@ -34,6 +48,7 @@ synchronized_at: 2026-08-07T15:53:58Z | 用途 | 命令 | 预期结果 | |---|---|---| +| 查看工作区 | `git status --short --branch` | 显示分支且没有无关修改 | | 检查模板结构 | `python scripts/check_harness.py --strict` | 输出“DevHarness 检查通过” | | 运行单元测试 | `python -m unittest discover -s tests -v` | 所有测试通过 | | 导出 Wiki 镜像 | `python scripts/sync_wiki_docs.py` | 映射页面写入 `docs/` | @@ -50,19 +65,24 @@ synchronized_at: 2026-08-07T15:53:58Z | `scripts/` | Harness 检查、Wiki 同步和归档工具 | 产品功能代码 | | `tests/` | Harness 工具自动化测试 | 生产数据 | -## 环境与凭据 +## 环境、配置与凭据 - Wiki 同步配置:仓库根目录 `wiki-docs.json`。 - Gitea 地址可由配置提供,也可通过 `GITEA_URL` 覆盖。 -- Gitea Personal Access Token 仅通过 `GITEA_TOKEN` 环境变量提供,不写入仓库。 -- Token 至少需要读取仓库权限;创建 Wiki 任务归档时还需要写仓库权限。 -- 日志和构建产物:本项目不持久化运行日志;Python 缓存不提交。 +- Gitea PAT 仅通过 `GITEA_TOKEN` 或 MCP 安全配置提供,不写入仓库。 +- Token 至少需要读取仓库权限;创建或更新 Wiki 时还需要写仓库权限。 +- 配置示例:`wiki-docs.json` 只保存非敏感仓库信息。 +- 日志:本项目不持久化运行日志,命令行错误是主要诊断信息。 +- 测试数据:只使用测试构造的字符串、路径和模拟响应,不使用生产数据。 +- 构建产物:Python 缓存和临时文件不提交。 ## 项目专用验收要求 - 长期文档必须先更新 Wiki,再导出本地镜像。 - 镜像必须包含来源页面、revision 和同步时间。 - 页面删除、重命名和映射变更必须人工确认。 +- 新增核心文档时必须更新 Home、显式映射和 Harness 检查。 +- 代码入口、命令、配置、业务规则或排错方式变化时必须评估文档影响。 - `python scripts/check_harness.py --strict` 必须通过。 - `python -m unittest discover -s tests -v` 必须通过。 - 未执行或无法覆盖的验证必须记录到工单。 diff --git a/docs/01-workflow.md b/docs/01-workflow.md index 64d79c0..f21d45c 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: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Development-Workflow.- -wiki_revision: ae9f9aac5df77f1e3e1c2a34bd00c849c1f63cbf -synchronized_at: 2026-08-07T15:54:03Z +wiki_revision: af4c1cbdd73cf9f6df971415487e2664e227ebc9 +synchronized_at: 2026-08-08T00:58:03Z # 开发工作流 @@ -83,6 +83,44 @@ python scripts/new_task_archive.py 123 "修复登录超时" - Wiki 更新成功而导出失败时,在工单记录部分完成状态,不得把任务标为完成。 - 与具体代码版本强绑定的接口或迁移资料可直接随代码维护,但必须在 Wiki 提供入口或适用版本说明。 +## 面向初级维护者的修改边界 + +| 风险 | 示例 | 处理方式 | +|---|---|---| +| 低 | 文案、简单校验、查询条件、独立 UI、小范围回归 Bug | 初级程序员可在 Agent 协助下理解、修改和验证 | +| 中 | API、配置、依赖、跨模块逻辑、数据结构 | 由 Agent 实现,程序员检查差异并执行验证 | +| 高 | 权限、安全、并发、迁移、支付、删除数据、不可逆操作 | 停止修改,由 Agent 分析并等待人工确认 | + +风险由影响范围决定,不按代码行数判断。 + +## 每个任务的文档影响 + +单元任务必须明确选择: + +- 不影响长期文档,并说明原因; +- 更新项目档案或运行验证; +- 更新架构与代码地图; +- 更新业务规则与术语; +- 更新常见修改或故障排查; +- 新增或调整其他 Wiki 页面。 + +以下变化必须更新相关 Wiki: + +- 启动、测试、部署或排错命令变化; +- 模块入口、目录职责或主要调用路径变化; +- 配置项、API、数据结构或状态变化; +- 业务规则、安全边界或权限变化; +- 日志位置、错误定位或常见处理方式变化。 + +普通内部重构如果入口、行为、配置和验证方式均未改变,可以记录“不影响长期文档”及原因。 + +## 稳定文档与任务归档 + +- Home、项目档案、代码地图、业务规则、开发验证、常见修改和故障排查描述项目现在怎样工作。 +- 工单和任务归档解释某次为什么修改、实际改了什么以及如何验证。 +- 新人先读稳定主题页,只有追查历史原因时才读任务归档。 +- 任务产生的长期结论必须合并到主题页,不能只留在归档。 + ## 什么时候重新确认方案 以下变化必须先更新工单,再由用户确认: diff --git a/docs/02-architecture-and-code-map.md b/docs/02-architecture-and-code-map.md new file mode 100644 index 0000000..2066dfa --- /dev/null +++ b/docs/02-architecture-and-code-map.md @@ -0,0 +1,88 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Architecture-and-Code-Map +wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Architecture-and-Code-Map.- +wiki_revision: 3f86864cecb0600e3b20631b6677446dbc259927 +synchronized_at: 2026-08-08T00:58:04Z + + +# 架构与代码地图 + +## 本页用途 + +帮助第一次接触项目的人回答三个问题: + +1. 项目由哪些部分组成; +2. 一个功能应该从哪里开始读; +3. 修改后应该运行哪些验证。 + +阅读代码前先看本页;目录、入口或主要数据流变化时必须更新本页。 + +## 项目定位 + +DevHarness 不是业务应用,而是一套开发工作流模板。它约束 Agent 和维护者如何讨论需求、建立工单、修改代码、更新 Wiki、测试、提交、验收和归档。 + +```text +用户确认方案 +→ Gitea 单元任务工单 +→ Agent 修改代码与测试 +→ 长期结论更新 Wiki +→ Wiki 单向导出 docs 镜像 +→ Git 提交并回写工单 +→ 用户验收 +``` + +## 代码地图 + +| 能力 | 路径 | 阅读入口 | 主要对象或函数 | 验证位置 | 风险 | +|---|---|---|---|---|---| +| Agent 工作规则 | `AGENTS.md` | “需求到实施” | 工作流条款 | 人工审查、Harness 检查 | 高 | +| 工单结构 | `.gitea/issue_template/` | `task.md` | Epic、MVP、Task 模板 | 创建测试工单或检查模板 | 中 | +| Wiki 页面映射 | `wiki-docs.json` | `mappings` | 页面名、本地路径 | `sync_wiki_docs.py --check` | 中 | +| Wiki API 和镜像生成 | `scripts/wiki_docs.py` | `WikiClient`、`sync_all` | 配置、页面、镜像元数据 | `tests/test_wiki_docs.py` | 中 | +| 手动同步入口 | `scripts/sync_wiki_docs.py` | `main()` | `--check` | 线上 Wiki 对照检查 | 低 | +| 任务归档 | `scripts/new_task_archive.py` | `main()` | 创建页面、登记映射 | 单元测试和正式归档 | 中 | +| Harness 结构检查 | `scripts/check_harness.py` | `main()` | 必需文件、镜像、归档检查 | `--strict` | 中 | +| 本地文档镜像 | `docs/` | `docs/README.md` | 生成元数据和 Wiki 正文 | 同步检查 | 低 | +| 自动化测试 | `tests/` | `test_wiki_docs.py` | 映射、同步和安全边界 | `unittest discover` | 低 | + +## 两条主要执行路径 + +### Wiki 镜像 + +```text +wiki-docs.json +→ WikiClient 列出并解析页面 +→ 读取 Markdown 与 last_commit.sha +→ 检查本地镜像是否有未提交修改 +→ 写入来源、URL、revision、同步时间 +→ --check 对照正文和 revision +``` + +### 任务归档 + +```text +读取 Wiki 归档模板 +→ 创建 Task-<编号>-<标题> 页面 +→ 追加显式页面映射 +→ 导出 docs/task 镜像 +→ 提交镜像并回写工单 +``` + +## 修改影响判断 + +| 修改内容 | 通常还要检查 | +|---|---| +| 修改 Agent 工作流 | `README.md`、`CLAUDE.md`、Development-Workflow、工单模板 | +| 修改 Wiki 页面名称 | `wiki-docs.json`、Home 链接、同步测试;必须人工确认 | +| 修改镜像格式 | 解析器、检查器、已有镜像、单元测试 | +| 增加核心文档 | Wiki、显式映射、Home、Harness 必需页面检查 | +| 修改归档字段 | Wiki 归档模板、归档脚本、归档检查和测试 | + +## 不可破坏的边界 + +- 工单管理过程,Wiki 管理长期文档,Git 管理代码和镜像。 +- `docs/` 不是长期文档编辑入口。 +- 同步只允许写入 `docs/` 下的 Markdown。 +- 页面删除、重命名和本地脏镜像不能被静默处理。 +- 凭据不得进入代码、Wiki、工单、日志或镜像。 diff --git a/docs/03-business-rules-and-glossary.md b/docs/03-business-rules-and-glossary.md new file mode 100644 index 0000000..45c3966 --- /dev/null +++ b/docs/03-business-rules-and-glossary.md @@ -0,0 +1,61 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Business-Rules-and-Glossary +wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Business-Rules-and-Glossary.- +wiki_revision: 7534fd60157096dab2c6f06214acfff84d1a5370 +synchronized_at: 2026-08-08T00:58:06Z + + +# 业务规则与术语 + +## 本页用途 + +解释 DevHarness 中容易混淆的术语、状态和不可破坏的流程规则。新项目复制模板后,应把项目自身的业务术语、状态和关键约束补充到本页。 + +## 核心术语 + +| 术语 | 含义 | 不要误解为 | +|---|---|---| +| Epic | 完整产品目标和长期路线 | 可以直接实施的单个任务 | +| MVP | 第一个可交付范围及集成边界 | 任意里程碑名称 | +| 单元任务 | 唯一正式实施单位,可独立测试和回退 | 临时聊天待办 | +| 事实来源 | 某类信息被正式维护的位置 | 多处内容可以随意覆盖 | +| Wiki 主源 | 长期开发文档首先修改的位置 | 本地 docs 的备份副本 | +| docs 镜像 | 从 Wiki 单向生成的浏览副本 | 可以直接编辑并反向同步的文档 | +| 待验收 | 实现和测试已完成,等待用户确认 | 已完成并可关闭 | +| 未验证部分 | 本次无法真实覆盖的行为 | 可以省略的测试备注 | + +## 工单状态 + +| 状态 | 含义 | 可以进入下一状态的条件 | +|---|---|---| +| 待确认 | 目标或方案仍需用户选择 | 用户明确确认方案 | +| 待实施 | 方案已确认,尚未修改 | 工作区和范围检查完成 | +| 进行中 | 正在实现、测试或同步文档 | 验收标准逐项检查完成 | +| 阻塞 | 满足规则定义的持续阻塞条件 | 阻塞解除并更新工单 | +| 待验收 | 代码、测试、归档和证据已完成 | 用户明确验收 | +| 已完成 | 用户已验收并完成父任务同步 | 无 | + +## 稳定业务规则 + +- 没有确认方案和单元任务工单,不修改产品行为。 +- 一个单元任务只解决一个可独立验证和回退的问题。 +- 需求、接口、数据、安全边界或验收标准变化时先更新工单。 +- 长期文档必须先修改 Wiki,再导出本地镜像。 +- 测试结果必须真实;未执行的验证必须明确记录。 +- 用户未明确验收前,工单保持开启。 +- 初级程序员可以理解和验证低风险修改,但高风险决策仍由 Agent 分析并等待人工确认。 + +## 新项目需要补充什么 + +复制模板后,至少补充: + +- 项目的用户和核心目标; +- 业务名词及容易混淆的概念; +- 主要对象和状态; +- 关键状态流转; +- 必须始终满足的业务规则; +- 数据保留、权限和安全边界; +- 典型输入、输出和失败示例。 + +业务规则必须由项目负责人确认,Agent 可以整理和举例,但不能根据代码自行臆造。 diff --git a/docs/04-local-development-and-verification.md b/docs/04-local-development-and-verification.md new file mode 100644 index 0000000..aba4db8 --- /dev/null +++ b/docs/04-local-development-and-verification.md @@ -0,0 +1,85 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Local-Development-and-Verification +wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Local-Development-and-Verification.- +wiki_revision: 537da98a775da39323cb101a717d003705a97761 +synchronized_at: 2026-08-08T00:58:08Z + + +# 本地开发与验证 + +## 本页用途 + +让维护者能够安装、运行、检查和验证项目。所有命令默认在仓库根目录执行,示例以 Windows PowerShell 为主。 + +## 环境要求 + +| 工具 | 用途 | 检查命令 | +|---|---|---| +| Git | 版本管理和脏文件保护 | `git --version` | +| Python 3 | Harness 脚本和测试 | `python --version` | +| Gitea 连接 | 工单和 Wiki | 浏览仓库或调用 MCP | +| Gitea PAT | 写 Wiki 时使用 | 仅通过 MCP 安全配置或 `GITEA_TOKEN` 提供 | + +不要打印或提交 PAT。 + +## 第一次运行 + +### 1. 检查工作区 + +- 目的:确认没有混入其他任务的修改。 +- 命令:`git status --short --branch` +- 预期:显示当前分支;开始新任务时没有无关文件。 +- 失败检查:确认变更归属,不要擅自重置或覆盖。 + +### 2. 检查 Harness + +- 目的:验证必需文件、项目档案、Wiki 映射和归档结构。 +- 命令:`python scripts/check_harness.py --strict` +- 预期:输出“DevHarness 检查通过”。 +- 失败检查:按错误提示检查缺失页面、未填占位符或损坏的镜像头。 + +### 3. 运行测试 + +- 目的:验证同步、路径和安全保护。 +- 命令:`python -m unittest discover -s tests -v` +- 预期:所有测试显示 `ok`。 +- 失败检查:先单独运行失败测试,再查看最近修改的对应脚本。 + +### 4. 对照线上 Wiki + +- 目的:确认本地 docs 是最新镜像。 +- 命令:`python scripts/sync_wiki_docs.py --check` +- 预期:所有映射显示“一致”。 +- 失败检查:先读取线上页面;确认页面名、revision、网络和 `GITEA_URL`。 + +## 常用调试方式 + +- 只检查 Python 语法:`python -m py_compile scripts/*.py`。 +- 查看一个脚本帮助:`python scripts/sync_wiki_docs.py --help`。 +- 查看未提交差异:`git diff --check` 和 `git diff`。 +- 查看最近提交:`git log -5 --oneline`。 +- 调试失败测试时优先运行单个测试文件,不要先修改多个模块。 + +## 测试数据与日志 + +DevHarness 不使用生产数据,也不需要固定业务测试数据。命令输出是主要诊断信息,不应包含令牌。如果复制到业务项目,应在本节写明: + +- 合成或脱敏测试数据的创建方式; +- 日志路径和日志级别; +- 请求或任务标识如何追踪; +- 禁止使用的数据来源。 + +## 完成修改前 + +依次执行: + +```powershell +python -m unittest discover -s tests -v +python scripts/check_harness.py --strict +python scripts/sync_wiki_docs.py --check +git diff --check +git status --short +``` + +无法执行的命令必须写入工单“未验证部分”。 diff --git a/docs/05-common-changes.md b/docs/05-common-changes.md new file mode 100644 index 0000000..ac4cb41 --- /dev/null +++ b/docs/05-common-changes.md @@ -0,0 +1,78 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Common-Changes +wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Common-Changes.- +wiki_revision: 2c41287656577564fc7b78b6cf8554ce81e16003 +synchronized_at: 2026-08-08T00:58:10Z + + +# 常见修改指南 + +## 本页用途 + +帮助初级程序员在 Claude/Codex Agent 协助下处理简单 Bug 和小需求。这里说明常见入口、验证方法和停止条件,不代替工单和方案确认。 + +## 风险分级 + +| 等级 | 常见修改 | 处理方式 | +|---|---|---| +| 低风险 | 文案、简单校验、查询条件、独立 UI、小范围回归 Bug | 初级程序员可在 Agent 协助下修改和验证 | +| 中风险 | API、配置、依赖、跨模块逻辑、数据结构 | 由 Agent 实现,程序员理解差异并执行验证 | +| 高风险 | 权限、安全、并发、迁移、支付、删除数据、不可逆操作 | 停止修改,由 Agent 分析并等待人工确认 | + +“代码行数少”不等于低风险。 + +## 修改 Wiki 文案 + +1. 在相关工单确认目标。 +2. 读取线上 Wiki 页面和当前 revision。 +3. 修改线上 Wiki,不直接编辑 `docs/`。 +4. 运行 `python scripts/sync_wiki_docs.py`。 +5. 运行 `python scripts/sync_wiki_docs.py --check`。 +6. 审查本地镜像差异并提交。 + +停止条件:页面需要删除、重命名或改变事实源边界。 + +## 增加工单字段 + +1. 阅读 `.gitea/issue_template/task.md` 和 Development-Workflow。 +2. 判断字段是否影响所有任务,避免只为一个任务增加永久字段。 +3. 修改模板和对应流程说明。 +4. 为 Harness 检查增加或调整测试。 +5. 创建一份示例工单草稿检查可读性。 + +停止条件:字段改变权限、审批或关闭条件。 + +## 调整 Harness 检查 + +1. 从 `scripts/check_harness.py` 的 `main()` 开始读。 +2. 新检查应输出具体文件和缺失内容。 +3. 检查结构事实,不声称自动判断文档语义质量。 +4. 在 `tests/` 添加成功和失败用例。 +5. 运行严格检查及全部测试。 + +停止条件:检查会删除、重写文件或依赖生产环境。 + +## 修复 Wiki 同步 Bug + +1. 从 `scripts/wiki_docs.py` 的 `WikiClient`、`parse_mirror` 和 `sync_all` 开始读。 +2. 先编写能复现问题的测试。 +3. 保持 Wiki → docs 单向关系。 +4. 验证中文、路径编码、revision 和脏文件保护。 +5. 使用测试页面验证时,不删除正式页面。 + +停止条件:需要自动删除/重命名页面、覆盖本地未提交修改或输出令牌。 + +## 看懂 Agent 的修改 + +审查时至少回答: + +- 这次解决了哪个工单目标; +- 修改入口和调用路径在哪里; +- 有哪些行为变化; +- 增加或修改了哪些测试; +- 哪些内容没有验证; +- 是否更新了受影响的 Wiki 页面; +- 怎样回退。 + +回答不了时,让 Agent补充说明,不要仅凭“测试通过”验收。 diff --git a/docs/06-troubleshooting.md b/docs/06-troubleshooting.md new file mode 100644 index 0000000..5c0d7ab --- /dev/null +++ b/docs/06-troubleshooting.md @@ -0,0 +1,40 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Troubleshooting +wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Troubleshooting +wiki_revision: e1a806bb8c6b6c32a4e271c94a9bcaaed36003db +synchronized_at: 2026-08-08T00:58:12Z + + +# 故障排查 + +## 本页用途 + +按“现象 → 原因 → 检查 → 处理”定位 DevHarness 常见问题。处理后如果形成稳定结论,应更新本页;临时过程记录在工单。 + +| 现象 | 常见原因 | 检查方法 | 处理 | +|---|---|---|---| +| `--strict` 提示项目档案未填写 | 新项目仍有占位内容 | 搜索 `<填写` | 先在 Wiki 填写真实内容,再导出镜像 | +| 同步提示镜像有未提交改动 | 有人直接修改 docs,或上次镜像尚未提交 | `git status --short -- docs` | 确认来源;保留人工内容并先更新 Wiki,不要强制覆盖 | +| Wiki 页面不存在 | 页面未创建、标题或映射错误 | 查看 Wiki 页面列表和 `wiki-docs.json` | 修正明确的页面或映射;不要自动删除本地文件 | +| API 路径出现重复 `/api/v1` | `GITEA_URL` 已包含 API 后缀 | 查看非敏感 URL 配置 | 同步器会规范化;新工具也应接受两种写法 | +| 公共仓库读取返回 401/403/404 | 环境令牌失效或属于其他实例 | 不打印令牌;尝试浏览公开页面 | 只读请求可安全降级匿名;写请求必须使用正确 PAT | +| 中文 Wiki 页面读取 404 | `sub_url` 被重复百分号编码 | 查看页面列表返回的 `sub_url` | 保留已有 `%`,不要再次编码 | +| Wiki 页面标题多出 `.-` | Gitea 1.25 的页面规范路径或更新时未显式传标题 | 对照页面 title 和 `sub_url` | 更新中文页面时显式保留原 title;不要猜测路径 | +| `--check` 正文不一致 | Wiki 已更新但镜像未导出,或本地被修改 | 对照 revision 和 Git 差异 | 确认 Wiki 后运行正式同步 | +| 单元测试能过但真实同步失败 | 测试使用模拟数据,网络或 Gitea 行为不同 | 查看工单“未验证部分” | 增加最小真实验证并记录服务端版本 | +| Git 工作区包含无关修改 | 同时存在其他任务或人工工作 | `git status --short` | 保留并隔离无关修改,不重置用户工作 | + +## 排查顺序 + +1. 读取完整错误信息,不只看最后一行。 +2. 检查当前工单、分支和工作区。 +3. 检查项目档案中的真实命令和环境。 +4. 用最小命令复现。 +5. 对照最近提交和 Wiki revision。 +6. 修复后增加回归测试或稳定排错条目。 +7. 无法验证的部分写回工单。 + +## 必须停止的情况 + +出现凭据泄露、数据损坏风险、权限边界变化、不可逆操作或不明来源的工作区改动时,立即停止并说明影响,不继续尝试破坏性修复。 diff --git a/docs/07-new-project-documentation-setup.md b/docs/07-new-project-documentation-setup.md new file mode 100644 index 0000000..5b8d742 --- /dev/null +++ b/docs/07-new-project-documentation-setup.md @@ -0,0 +1,99 @@ + +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: 1745db81541e94200309dc2136ff15ce4349fa3f +synchronized_at: 2026-08-08T00:58:14Z + + +# 新项目文档初始化 + +## 本页用途 + +从 DevHarness 创建新项目时,指导 Claude/Codex Agent快速建立可供初级程序员阅读的项目文档。初始化只生成可靠的第一版,不允许 Agent 臆造业务规则、凭据、部署环境或生产数据。 + +## 初始化顺序 + +### 1. 建立项目边界 + +由项目负责人确认: + +- 项目名称和一句话目标; +- 用户和主要使用场景; +- 技术栈和支持环境; +- Gitea 仓库、默认分支和维护者; +- 安全、权限、数据和发布红线。 + +把项目专用红线写入根目录或子目录 `AGENTS.md`。 + +### 2. 建立 Gitea + +创建远端仓库并完成允许的初始引导提交。开启工单和 Wiki。任何产品功能开发在引导提交后都必须先有单元任务工单。 + +### 3. 修改镜像配置 + +把 `wiki-docs.json` 中的地址、owner 和 repository 改成新项目。移除属于 DevHarness 自身的任务归档映射;核心主题映射保留。 + +不要把 PAT 写入配置。 + +### 4. Agent 检查项目事实 + +Agent 只读检查: + +- README、配置和依赖文件; +- 启动入口; +- 主要模块和目录规则; +- 测试、格式和静态检查命令; +- 日志、示例配置和测试数据; +- 已存在的接口、数据模型和状态。 + +区分“代码中确认的事实”“负责人确认的业务规则”和“仍待确认的假设”。 + +### 5. 先创建线上 Wiki + +至少创建或填写: + +1. Home; +2. Project-Profile; +3. Architecture-and-Code-Map; +4. Business-Rules-and-Glossary; +5. Local-Development-and-Verification; +6. Common-Changes; +7. Troubleshooting; +8. Development-Workflow; +9. Task-Archive-Template。 + +Home 给出建议阅读顺序;每个命令必须有预期结果;代码地图必须指出入口和测试位置。 + +### 6. 人工确认 + +项目负责人至少确认: + +- 一句话目标和业务术语; +- 关键业务规则和状态; +- 权限、安全和数据边界; +- 真实运行、测试和部署命令; +- 哪些修改属于高风险。 + +### 7. 导出镜像并检查 + +```powershell +python scripts/sync_wiki_docs.py +python scripts/check_harness.py --strict +python scripts/sync_wiki_docs.py --check +python -m unittest discover -s tests -v +``` + +只有线上 Wiki 确认后才导出 `docs/`。旧项目的任务归档不能带入新项目历史。 + +## 完成标准 + +初级程序员应能仅依靠 Home 和链接页面回答: + +- 项目解决什么问题; +- 怎样启动和运行测试; +- 常用功能从哪个目录和入口开始读; +- 一个简单修改通常要改哪里、验证什么; +- 哪些情况必须停止并交给 Agent 或负责人。 + +回答不了的问题应继续补充主题文档,而不是堆入任务归档。 diff --git a/docs/README.md b/docs/README.md index a68b7e4..b60081b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,44 +2,86 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Home wiki_url: http://ilaer.eicp.net:8418/opc/dev_harness/wiki/Home -wiki_revision: 448de2a90fc237f6d5df6a5e8da1f94df2665a30 -synchronized_at: 2026-08-07T15:57:30Z +wiki_revision: 6cd3fccc78501c8be5bea6cd05d53799be4c6bd7 +synchronized_at: 2026-08-08T00:58:01Z # DevHarness 文档中心 -DevHarness 是一个以 Gitea 工单管理开发任务、以 Wiki 管理长期开发文档、以 Git 记录代码变更的 AI 辅助开发模板。 +DevHarness 是一个以 Gitea 工单管理开发任务、以 Wiki 管理长期开发文档、以 Git 记录代码变更的 AI 辅助开发模板。目标是让初级程序员能够理解项目、运行验证,并在 Claude/Codex Agent 协助下处理简单 Bug 和需求。 + +## 第一次阅读 + +建议按以下顺序,用 10~20 分钟建立整体认识: + +1. [项目档案](Project-Profile.-):项目目标、环境、命令和目录边界。 +2. [架构与代码地图](Architecture-and-Code-Map.-):功能从哪里开始读、测试在哪里。 +3. [业务规则与术语](Business-Rules-and-Glossary.-):重要名词、状态和不能破坏的规则。 +4. [本地开发与验证](Local-Development-and-Verification.-):怎样运行、测试和排错。 +5. [常见修改指南](Common-Changes.-):简单修改的步骤和停止条件。 +6. [故障排查](Troubleshooting):遇到错误时按什么顺序检查。 +7. [开发工作流](Development-Workflow.-):完整建单、实施、验收和归档流程。 + +从模板创建新项目时先阅读[新项目文档初始化](New-Project-Documentation-Setup.-)。 + +## 五分钟开始 + +在仓库根目录执行: + +```powershell +git status --short --branch +python scripts/check_harness.py --strict +python -m unittest discover -s tests -v +python scripts/sync_wiki_docs.py --check +``` + +预期结果: + +- 工作区没有不属于当前任务的修改; +- Harness 输出“DevHarness 检查通过”; +- 所有单元测试通过; +- 所有 Wiki 映射显示“一致”。 + +如果失败,先看[故障排查](Troubleshooting),不要直接重置工作区或覆盖本地文档。 + +## 简单修改从哪里开始 + +| 想做什么 | 先读哪里 | 主要验证 | +|---|---|---| +| 修改文档 | 对应 Wiki 页面、Common-Changes | Wiki 同步检查 | +| 调整工单字段 | `.gitea/issue_template/`、Development-Workflow | Harness 严格检查 | +| 修改同步行为 | `scripts/wiki_docs.py`、Architecture-and-Code-Map | 单元测试和真实 Wiki 检查 | +| 增加结构检查 | `scripts/check_harness.py` | 成功与失败测试 | +| 排查运行错误 | Troubleshooting、项目档案 | 最小复现命令 | + +权限、安全、并发、迁移、支付、删除数据或不可逆操作不属于简单修改,必须停止并交给 Agent 分析、等待人工确认。 ## 事实来源 | 信息 | 事实来源 | |---|---| | 任务状态、讨论、阻塞、验收过程 | Gitea 工单 | -| 架构说明、开发规范、操作手册、任务归档 | Gitea Wiki | +| 架构、业务规则、开发规范、操作手册、任务归档 | Gitea Wiki | | 源码和与特定代码版本强绑定的文档 | Git 仓库 | | 离线浏览副本 | Git 仓库中的 `docs/` Wiki 镜像 | 本地 `docs/` 不是编辑入口。长期文档必须先修改 Wiki,读取确认后再导出镜像。 -## 文档入口 +## 项目入口 -- [项目档案](Project-Profile.-) -- [开发工作流](Development-Workflow.-) -- [任务归档模板](Task-Archive-Template.-) - [Gitea 工单](http://ilaer.eicp.net:8418/opc/dev_harness/issues) - [代码仓库](http://ilaer.eicp.net:8418/opc/dev_harness) +- [任务归档模板](Task-Archive-Template.-) ## 同步原则 -固定顺序: - ```text 修改 Wiki → 读取确认 → 导出 docs → 校验差异 → 提交镜像 ``` - 页面和本地路径通过仓库中的 `wiki-docs.json` 显式映射。 - 镜像头记录来源页面、Wiki revision 和同步时间。 -- 同步工具发现已跟踪镜像存在未提交修改时必须停止。 -- 页面删除、重命名和映射变更必须人工确认,不自动传播。 +- 已映射镜像存在未提交修改时同步必须停止。 +- 页面删除、重命名和映射变更必须人工确认。 - Wiki 或导出失败时,相关任务不能标记为完成。 - 凭据、个人数据和生产数据不得进入 Wiki 或镜像。 diff --git a/scripts/check_harness.py b/scripts/check_harness.py index 9fea9f1..8f82dcd 100644 --- a/scripts/check_harness.py +++ b/scripts/check_harness.py @@ -1,4 +1,4 @@ -"""检查 DevHarness 必需文件和任务归档的基本结构。""" +"""检查 DevHarness 必需文件、核心文档和任务归档的基本结构。""" from __future__ import annotations @@ -10,12 +10,81 @@ from wiki_docs import WikiDocsError, load_config, parse_mirror ROOT = Path(__file__).resolve().parents[1] +CORE_PAGE_PATHS = { + "Home": "docs/README.md", + "Project-Profile": "docs/00-project-profile.md", + "Development-Workflow": "docs/01-workflow.md", + "Architecture-and-Code-Map": "docs/02-architecture-and-code-map.md", + "Business-Rules-and-Glossary": "docs/03-business-rules-and-glossary.md", + "Local-Development-and-Verification": ( + "docs/04-local-development-and-verification.md" + ), + "Common-Changes": "docs/05-common-changes.md", + "Troubleshooting": "docs/06-troubleshooting.md", + "New-Project-Documentation-Setup": ( + "docs/07-new-project-documentation-setup.md" + ), + "Task-Archive-Template": "docs/templates/task-archive.md", +} +CORE_DOCUMENT_REQUIREMENTS = { + "docs/README.md": ( + "## 第一次阅读", + "## 五分钟开始", + "## 简单修改从哪里开始", + "## 事实来源", + ), + "docs/00-project-profile.md": ( + "## 基本信息", + "## 技术栈与运行环境", + "## 阅读入口", + "## 常用命令", + "## 环境、配置与凭据", + ), + "docs/01-workflow.md": ( + "## 面向初级维护者的修改边界", + "## 每个任务的文档影响", + "## 稳定文档与任务归档", + ), + "docs/02-architecture-and-code-map.md": ( + "## 项目定位", + "## 代码地图", + "## 两条主要执行路径", + "## 不可破坏的边界", + ), + "docs/03-business-rules-and-glossary.md": ( + "## 核心术语", + "## 工单状态", + "## 稳定业务规则", + "## 新项目需要补充什么", + ), + "docs/04-local-development-and-verification.md": ( + "## 环境要求", + "## 第一次运行", + "## 常用调试方式", + "## 完成修改前", + ), + "docs/05-common-changes.md": ( + "## 风险分级", + "## 修改 Wiki 文案", + "## 调整 Harness 检查", + "## 看懂 Agent 的修改", + ), + "docs/06-troubleshooting.md": ( + "## 排查顺序", + "## 必须停止的情况", + ), + "docs/07-new-project-documentation-setup.md": ( + "## 初始化顺序", + "## 完成标准", + ), +} REQUIRED_FILES = ( "AGENTS.md", "README.md", "docs/00-project-profile.md", "docs/01-workflow.md", "docs/templates/task-archive.md", + *CORE_DOCUMENT_REQUIREMENTS, "wiki-docs.json", "scripts/wiki_docs.py", "scripts/sync_wiki_docs.py", @@ -61,6 +130,41 @@ def check_archives(errors: list[str]) -> None: errors.append(f"{path.name} 没有记录未验证部分") +def missing_sections(content: str, required: tuple[str, ...]) -> list[str]: + return [section for section in required if section not in content] + + +def check_core_documents(errors: list[str], root: Path = ROOT) -> None: + """检查初级维护者所需主题页的固定结构。""" + + for relative_path, required in CORE_DOCUMENT_REQUIREMENTS.items(): + path = root / relative_path + if not path.is_file(): + continue + try: + _, body = parse_mirror(path.read_text(encoding="utf-8")) + except (OSError, UnicodeDecodeError, WikiDocsError): + continue + for section in missing_sections(body, required): + errors.append(f"{relative_path} 缺少核心章节:{section}") + + +def check_task_template(errors: list[str], root: Path = ROOT) -> None: + path = root / ".gitea" / "issue_template" / "task.md" + if not path.is_file(): + return + content = path.read_text(encoding="utf-8") + required = ( + "## 文档影响", + "- [ ] 不影响长期文档,原因:", + "- [ ] 更新架构与代码地图", + "- [ ] 更新业务规则与术语", + "- [ ] 更新常见修改或故障排查", + ) + for section in missing_sections(content, required): + errors.append(f"单元任务模板缺少:{section}") + + def check_wiki_mirrors(errors: list[str]) -> None: """检查每份本地文档都有显式映射和可追踪的镜像头。""" @@ -70,6 +174,13 @@ def check_wiki_mirrors(errors: list[str]) -> None: errors.append(str(exc)) return + configured_mappings = {mapping.page: mapping.path for mapping in config.mappings} + for page, expected_path in CORE_PAGE_PATHS.items(): + if configured_mappings.get(page) != expected_path: + errors.append( + f"核心 Wiki 页面映射缺失或路径错误:{page} -> {expected_path}" + ) + mapped_paths = {mapping.path for mapping in config.mappings} actual_paths = { path.relative_to(ROOT).as_posix() for path in (ROOT / "docs").rglob("*.md") @@ -112,6 +223,8 @@ def main() -> int: check_required_files(errors) check_project_profile(errors, warnings, args.strict) check_wiki_mirrors(errors) + check_core_documents(errors) + check_task_template(errors) check_archives(errors) for warning in warnings: diff --git a/tests/test_harness_docs.py b/tests/test_harness_docs.py new file mode 100644 index 0000000..79f4f32 --- /dev/null +++ b/tests/test_harness_docs.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "scripts")) + +from check_harness import ( # noqa: E402 + CORE_DOCUMENT_REQUIREMENTS, + CORE_PAGE_PATHS, + REQUIRED_FILES, + check_core_documents, + check_task_template, + missing_sections, +) +from wiki_docs import load_config # noqa: E402 + + +class CoreDocumentTests(unittest.TestCase): + def test_current_core_documents_have_required_sections(self) -> None: + errors: list[str] = [] + check_core_documents(errors) + self.assertEqual(errors, []) + + def test_missing_sections_reports_each_heading(self) -> None: + missing = missing_sections("# 页面\n## 已有\n", ("## 已有", "## 缺少")) + self.assertEqual(missing, ["## 缺少"]) + + def test_every_core_document_is_required(self) -> None: + for path in CORE_DOCUMENT_REQUIREMENTS: + self.assertIn(path, REQUIRED_FILES) + + def test_every_core_page_has_exact_mapping(self) -> None: + config = load_config() + mappings = {mapping.page: mapping.path for mapping in config.mappings} + for page, path in CORE_PAGE_PATHS.items(): + self.assertEqual(mappings.get(page), path) + + +class TaskTemplateTests(unittest.TestCase): + def test_task_template_requires_document_impact(self) -> None: + errors: list[str] = [] + check_task_template(errors) + self.assertEqual(errors, []) + + +if __name__ == "__main__": + unittest.main() diff --git a/wiki-docs.json b/wiki-docs.json index 4b5d218..cf0cd5e 100644 --- a/wiki-docs.json +++ b/wiki-docs.json @@ -16,6 +16,30 @@ "page": "Development-Workflow", "path": "docs/01-workflow.md" }, + { + "page": "Architecture-and-Code-Map", + "path": "docs/02-architecture-and-code-map.md" + }, + { + "page": "Business-Rules-and-Glossary", + "path": "docs/03-business-rules-and-glossary.md" + }, + { + "page": "Local-Development-and-Verification", + "path": "docs/04-local-development-and-verification.md" + }, + { + "page": "Common-Changes", + "path": "docs/05-common-changes.md" + }, + { + "page": "Troubleshooting", + "path": "docs/06-troubleshooting.md" + }, + { + "page": "New-Project-Documentation-Setup", + "path": "docs/07-new-project-documentation-setup.md" + }, { "page": "Task-Archive-Template", "path": "docs/templates/task-archive.md"