diff --git a/CLAUDE.md b/CLAUDE.md index 74ef323..d77601a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,24 +1,9 @@ # Claude Code 项目入口 -本仓库的完整开发规则以 [AGENTS.md](AGENTS.md) 为唯一事实来源。 +@AGENTS.md -Claude Code 开始任何工作前,必须按顺序阅读: +## Claude Code 专用说明 -1. 根目录的 `AGENTS.md`; -2. Gitea Wiki 的项目档案;Wiki 不可用时读取 `docs/00-project-profile.md` 镜像并明确其 revision; -3. Gitea Wiki 的架构与代码地图、业务规则,以及任务直接涉及的主题页; -4. 任务涉及目录中更具体的 `AGENTS.md`; -5. 当前 Gitea 工单及其父级 MVP、Epic 工单。 - -必须遵守以下入口规则: - -- 方案经用户确认并建立单元任务工单后,才能修改产品代码。 -- 只修改当前工单范围内的文件,保留用户已有和无关的改动。 -- 在单元任务中明确文档影响;入口、命令、配置、数据、业务规则或排错方式变化时先更新对应 Wiki。 -- 严格遵守 `AGENTS.md` 的效率与范围控制:优先真实反馈、复用未失效的检查结果、完成必要闭环后停止,但不得省略安全和最终验收。 -- 实现、测试、Git 提交、待验收、Wiki 任务归档、导出本地镜像和关闭工单的顺序不得跳过。 -- 长期文档先修改 Wiki,再导出 `docs/`;不得直接编辑镜像作为最终结果。 -- 未经用户明确验收,不得关闭工单。 -- 不得把密码、令牌、Cookie、私钥或生产数据写入代码、日志、工单和文档。 - -不要在本文件复制完整工作流。流程发生变化时只更新 `AGENTS.md`,本文件保持为 Claude Code 的稳定入口,防止两套规则不一致。 +- 上方导入的 `AGENTS.md` 是所有编码 Agent 的共同规则事实来源,Claude Code 必须完整遵守。 +- 本文件只记录 Claude Code 特有的入口或工具差异;当前没有额外的项目专用差异。 +- 共同规则变化时只修改 `AGENTS.md`,不要在本文件重复维护。 diff --git a/dev_scripts/check_harness.py b/dev_scripts/check_harness.py index 56191f9..f763f86 100644 --- a/dev_scripts/check_harness.py +++ b/dev_scripts/check_harness.py @@ -85,6 +85,7 @@ CORE_DOCUMENT_REQUIREMENTS = { } REQUIRED_FILES = ( "AGENTS.md", + "CLAUDE.md", "README.md", "docs/00-project-profile.md", "docs/01-workflow.md", @@ -191,6 +192,25 @@ def check_agent_efficiency_rules(errors: list[str], root: Path = ROOT) -> None: errors.append(f"AGENTS.md 缺少:{section}") +def check_claude_code_entry(errors: list[str], root: Path = ROOT) -> None: + """检查 Claude Code 入口直接复用共同 Agent 规则。""" + + path = root / "CLAUDE.md" + if not path.is_file(): + return + content = path.read_text(encoding="utf-8") + lines = {line.strip() for line in content.splitlines()} + if "@AGENTS.md" not in lines: + errors.append("CLAUDE.md 缺少独立的 @AGENTS.md 导入") + required = ( + "共同规则事实来源", + "只记录 Claude Code 特有", + "只修改 `AGENTS.md`", + ) + for section in missing_sections(content, required): + errors.append(f"CLAUDE.md 缺少:{section}") + + def core_mapping_errors(configured_mappings: dict[str, str]) -> list[str]: errors: list[str] = [] for page, expected_path in CORE_PAGE_PATHS.items(): @@ -258,6 +278,7 @@ def main() -> int: check_core_documents(errors) check_task_template(errors) check_agent_efficiency_rules(errors) + check_claude_code_entry(errors) check_archives(errors) for warning in warnings: diff --git a/tests/test_harness_docs.py b/tests/test_harness_docs.py index 57104cc..c0c7374 100644 --- a/tests/test_harness_docs.py +++ b/tests/test_harness_docs.py @@ -1,6 +1,7 @@ from __future__ import annotations import sys +import tempfile import unittest from pathlib import Path @@ -12,6 +13,7 @@ from check_harness import ( # noqa: E402 CORE_DOCUMENT_REQUIREMENTS, CORE_PAGE_PATHS, REQUIRED_FILES, + check_claude_code_entry, check_core_documents, check_agent_efficiency_rules, check_task_template, @@ -62,6 +64,23 @@ class AgentRuleTests(unittest.TestCase): check_agent_efficiency_rules(errors) self.assertEqual(errors, []) + def test_claude_code_entry_imports_shared_rules(self) -> None: + errors: list[str] = [] + check_claude_code_entry(errors) + self.assertEqual(errors, []) + + def test_claude_code_entry_requires_exact_import_line(self) -> None: + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + (root / "CLAUDE.md").write_text( + "共同规则事实来源\n只记录 Claude Code 特有\n" + "共同规则只修改 `AGENTS.md`\n", + encoding="utf-8", + ) + errors: list[str] = [] + check_claude_code_entry(errors, root) + self.assertIn("CLAUDE.md 缺少独立的 @AGENTS.md 导入", errors) + if __name__ == "__main__": unittest.main()