死磕claude code-项目地图:让 Claude Code 读懂目录、命令和边界

📅 2026/7/8 15:37:48
死磕claude code-项目地图:让 Claude Code 读懂目录、命令和边界
TL;DR项目地图不是目录树打印。它是一份结构化声明告诉 Claude Code 哪些目录存在、各管什么、服务怎么调用、命令怎么跑、哪些东西不能碰。没有地图Claude Code 靠搜索猜结构——猜错一次就是跨模块耦合的开始。问题新成员进项目会问四件事代码在哪、怎么跑、怎么测、什么不能动。Claude Code 也需要这四件事的答案。区别在于人类能从对话和经验里逐步补全而 Claude Code 每次会话从零开始。如果CLAUDE.md里没有写清楚项目结构它会在每次任务开始时执行一轮目录扫描ls根目录、cat package.json、find测试文件——这些操作消耗的 token 本来可以用在实际工作上。更严重的问题不是 token 浪费而是边界误判。Claude Code 看到两个 package 都有utils目录可能把共享逻辑放进错误的那个。它看到api/和worker/都访问数据库可能直接在api/里写 SQL 而不是走数据层。这些错误的共同根因是同一件事项目地图缺失或不够精确。项目地图是什么项目地图是CLAUDE.md中的一段结构化描述回答以下六类问题这六类信息的密度不同。命令清单和禁区声明是高频引用的必须精确无歧义。目录职责和模块依赖是低频但高影响的——用错一次就是架构污染。一个常见的误区是把项目地图写成tree命令的输出。目录树能告诉你文件在哪但不能告诉你目录之间的关系、调用方向和修改约束。项目地图的价值不在于列出每个文件而在于声明目录之间的依赖规则和操作边界。好的项目地图让 Claude Code 在动手写代码之前就知道哪些路径可以安全修改、哪些操作需要额外的确认步骤、哪些模块之间不应该产生新的依赖关系。三种项目类型的项目地图MonorepoTurborepo Next.js 共享包## Project Map ### Structure - apps/web — Next.js 前端React 18, Tailwind CSS, App Router - apps/api — Express APINode.js 20, Prisma ORM - apps/worker — BullMQ 后台任务处理器 - packages/ui — 共享组件库Storybook 维护 - packages/config — 共享 ESLint config、TS config、Tailwind preset - packages/db — Prisma schema 和生成的 client - packages/shared — 业务类型定义和工具函数 ### Commands - Install: pnpm install - Dev all: pnpm dev - Dev single: pnpm --filter web dev - Test all: pnpm test - Test single: pnpm --filter api vitest run src/modules/orders/ - Build: pnpm build - Lint: pnpm lint - Type check: pnpm typecheck - DB migrate: pnpm --filter db prisma migrate dev --name 描述 - DB seed: pnpm --filter db prisma db seed - DB studio: pnpm --filter db prisma studio ### Boundaries - apps/web 可以导入 packages/ui、packages/config、packages/shared - apps/web 不能直接导入 apps/api 的任何代码 - apps/api 可以导入 packages/db、packages/shared、packages/config - apps/api 不能导入 apps/web 或 apps/worker 的代码 - packages/db 是 Prisma schema 的唯一归属地 - 不允许在 apps/api 或 apps/web 里直接写 Prisma import统一通过 packages/db 导出 - 修改 prisma/schema.prisma 后必须运行 migrate不允许只改 schema 不迁移 ### Test Strategy - Unit: Vitestpackages/* 用 vitest.config.ts - Integration: apps/api 测试用真实 SQLitevitest beforeAll 建表 - E2E: Playwrightapps/web/e2e/ - 只测单个文件: pnpm --filter pkg vitest run path/to/file.test.ts - 只测变更相关: pnpm test -- --changed HEAD~1 ### Off-limits - packages/db/prisma/migrations/ — 只通过 prisma migrate 生成 - apps/web/.next/ — 构建产物 - packages/db/src/client/ — Prisma 生成代码 - pnpm-lock.yaml — 不手动编辑 - .env* — 任何环境变量文件这份地图的关键不是覆盖每个文件而是让 Claude Code 在动手之前就知道边界在哪里。apps/web 不能直接导入 apps/api这一行能阻止它在前后端之间创建隐式依赖。微服务多仓库微服务的项目地图和 monorepo 有本质区别Claude Code 通常一次只在一个仓库里工作但你需要让它知道上下游依赖。## Project Map ### 本仓库: payment-service - src/handlers/ — HTTP handlerFastify routes - src/services/ — 业务逻辑层 - src/repositories/ — 数据访问层Knex.js - src/clients/ — 调用其他服务的 HTTP client - src/workers/ — 消息队列消费者SQS - src/types/ — TypeScript 类型定义 - migrations/ — Knex 迁移文件 ### Commands - Install: npm install - Dev: npm run dev端口 3010 - Test: npm test - Test single: npx vitest run src/services/refund.test.ts - Test with coverage: npm run test:coverage - Lint: npm run lint - Build: npm run build - Migrate: npx knex migrate:latest - Migrate (make): npx knex migrate:make 名称 ### Service Dependencies - order-serviceHTTPbase URL 从 ORDER_SERVICE_URL 读取— 查询订单状态 - user-serviceHTTPbase URL 从 USER_SERVICE_URL 读取— 查询用户支付偏好 - notification-serviceSQSqueue 从 NOTIFICATION_QUEUE_URL 读取— 发送支付通知 - gatewayAPI Gateway本服务注册在 /payments 路径下 ### Boundaries - handlers 只做参数校验和 HTTP 转换业务逻辑在 services/ - services/ 可以调用 repositories/ 和 clients/不能直接用 Knex - clients/ 里封装所有外部调用超时设 5 秒失败走重试策略 - workers/ 调用 services/不直接操作 repositories/ - 迁移文件只加不改新增迁移文件不修改已执行的迁移 ### Off-limits - migrations/ 中已合并的文件 — 只加新文件不修改旧文件 - dist/ — 构建产物 - knexfile.js — 环境相关配置不改动 - .env* — 凭据和环境变量微服务场景的重点是Service Dependencies段。Claude Code 需要知道本服务在系统中的位置——它依赖谁、谁依赖它、通信方式是什么。没有这段信息它可能在本服务里复制其他服务的逻辑而不是发 HTTP 请求。单服务Express / Fastify单服务项目结构最简单但测试策略容易模糊。## Project Map ### Structure - src/routes/ — 路由定义Express Router - src/controllers/ — 请求处理调用 services - src/services/ — 业务逻辑不依赖 Express - src/models/ — Mongoose 模型定义 - src/middleware/ — Express 中间件auth, rate-limit, error-handler - src/utils/ — 纯工具函数无副作用 - src/config/ — 配置加载环境变量 → 配置对象 - scripts/ — 一次性运维脚本 - seeds/ — 数据库种子脚本 ### Commands - Install: npm install - Dev: npm run devnodemon, 端口 3000 - Test: npm test - Test single: npx jest src/services/user.test.ts - Test watch: npm run test:watch - Lint: npm run lint - Lint fix: npm run lint:fix - Seed: npm run seed ### Boundaries - routes/ 只做路由注册逻辑在 controllers/ - controllers/ 可以调用 services/ 和 models/不写业务逻辑 - services/ 不能 import Expressreq, res, next - models/ 只定义 schema 和静态方法不含业务逻辑 - middleware/ 可以依赖 services/但尽量只做轻量校验 - utils/ 是纯函数不能 import 项目中任何其他模块 ### Test Strategy - Unit: Jestservices/, utils/ - Integration: Jest mongodb-memory-servercontrollers/ 用 supertest - E2E: 手动本服务无 E2E 框架 - 只测单个文件: npx jest 路径 --no-coverage ### Off-limits - node_modules/ — 不可修改 - seeds/ — 只在开发环境运行不随意改生产种子数据 - .env — 凭据文件 - package-lock.json — 不手动编辑单服务地图的重点是分层边界。services/ 不能 import Express这条规则能阻止 Claude Code 把 HTTP 语义status code、response format渗透到业务逻辑层。决策矩阵信息放在哪里项目地图的信息分布在多个位置。放错位置不会导致错误但会降低 Claude Code 的使用效率。|信息类型|放在哪里|为什么|加载时机|| — | — | — | — ||目录结构和职责|CLAUDE.md 项目地图段|每次任务都需要理解全局|每次会话||服务边界规则|CLAUDE.md 项目地图段|全局约束违反代价高|每次会话||测试命令|CLAUDE.md Commands 段|高频使用精确写法避免试错|每次会话||目录特定规则|.claude/rules/下按路径|只在操作该路径时加载节省上下文|按需加载||架构图ASCII|CLAUDE.md 项目地图段|全局理解帮助 Claude Code 定位改动影响|每次会话||风险文件列表|CLAUDE.md Safety 段|安全边界违反会出事故|每次会话||代码风格偏好|.claude/rules/style.md|编辑代码时才需要|编辑文件时||PR 审查清单|.claude/rules/review.md|只在 review 时需要|review 时||依赖版本约束|CLAUDE.md 项目地图段|防止 Claude Code 建议不兼容的 API|每次会话|核心原则全局约束放 CLAUDE.md路径特定规则放.claude/rules/。CLAUDE.md 每次会话全量加载所以只放高频和高影响的内容。低频规则放.claude/rules/下的文件Claude Code 只在操作相关路径时读取。这个分工在 04CLAUDE.md[1] 和 05rules[2] 里会展开。质量诊断写完项目地图后不要直接信任它。用以下四个测试验证 Claude Code 是否真正理解了你的项目。测试一目录复述。让 Claude Code 列出所有顶层目录及其职责和你写的地图对比。不看项目地图用你自己的话描述这个项目的目录结构。 每个顶层目录负责什么目录之间是什么关系如果它漏掉了packages/db或把apps/worker的职责说错了地图的 Structure 段需要补充。如果它说不出目录之间的关系比如packages/ui 被 apps/web 使用说明 Structure 段缺少依赖描述。测试二边界识别。给它一个跨模块的场景看它是否知道边界。我需要在 apps/web 里调用支付功能。应该怎么做正确回答应该是通过 HTTP 调用 apps/api 的支付端点或者使用 packages/shared 里的支付 client。如果它建议直接在 web 里写支付逻辑或直接导入 api 的代码边界规则不够清晰。这个测试的关键是看 Claude Code 是否理解前端不直接处理后端逻辑这个架构意图。测试三命令精准度。指定一个具体文件问测试命令。我只改了 packages/ui/src/Button.tsx应该跑什么测试命令正确答案是pnpm --filter ui vitest run src/Button.test.tsx或类似的精确命令。如果它给出pnpm test这种全量命令Commands 段需要更明确的单文件测试说明。命令不精确的后果是每次改动都跑全量测试浪费时间且容易引入无关的失败噪声。测试四禁区尊重。让它做一件会触犯禁区的事。把 prisma/schema.prisma 里的 User model 加一个 phone 字段。正确行为是修改 schema 后主动提醒需要运行prisma migrate dev。如果它改完 schema 就停了Safety 段的约束没有被 Claude Code 内化。更严重的情况是它同时修改了 migrations 目录里已存在的迁移文件——这说明禁区声明完全失效。四个测试中任何一个失败都是地图写得不够好的信号。补充对应的信息段然后重新测试。每次补充后重新运行所有四个测试确保修改没有引入新的理解偏差。维护策略项目地图不是写一次就完了。它在两种情况下会过期结构变更和命令变更。结构变更触发更新• 新增或删除顶层目录• 新增服务或 package• 改变测试框架Jest → Vitest• 改变包管理器npm → pnpm• 新增或改变 CI 流程命令变更触发更新• 测试命令变化加了--coverage要求、改了测试脚本名• 构建流程变化加了 esbuild、改了 webpack config• 数据库操作变化新增 seed 命令、改变迁移工具更新原则谁改结构谁更新地图。这不是 Claude Code 的活——结构变更通常是人工决策新建服务、迁移工具链变更者在合并 PR 之前更新CLAUDE.md中的项目地图段。如果跳过这一步下一个人或下一次会话的 Claude Code 就会基于过期信息做决策。可以用 PR template 加一条 checklist 强制执行## PR Checklist - [ ] 如果改了目录结构或命令更新了 CLAUDE.md 的项目地图段周期性验证。每两周或每次 sprint 结束让 Claude Code 复述项目结构测试一看是否和实际一致。不一致的地方就是过期了的地图段。这个验证不需要人工逐条核对直接让 Claude Code 自己做对比即可。阅读当前仓库结构然后对比 CLAUDE.md 中的项目地图段。 列出所有不一致的地方新出现的目录、消失的目录、职责描述不准的目录。 不要修改文件只输出对比结果。失败案例支付服务的隐形耦合一个电商平台用 monorepo 结构初始只有orders和users两个服务。项目地图描述了它们之间的边界### Boundaries - orders 可以调用 usersHTTP - users 不依赖 orders三个月后业务增长团队拆分出payments服务。apps/payments/目录创建了代码写好了CI 也跑通了。但没有人更新CLAUDE.md的项目地图。接下来两周里Claude Code 在处理支付相关需求时做了一系列决策结果是orders和payments之间形成了紧耦合。orders里出现了大量应该属于payments的逻辑。等到团队发现时需要在两个服务之间迁移代码、重写测试、修复调用链。根因项目地图没有反映payments服务的存在和边界。修复### Boundaries - orders 可以调用 usersHTTP和 paymentsHTTP - payments 可以调用 usersHTTP和 ordersHTTP查询订单详情 - users 不依赖 orders 或 payments - 所有支付相关逻辑收费、退款、币种转换属于 payments 服务 - orders 只负责订单生命周期支付操作必须通过 payments API教训项目地图的过期不会报错。Claude Code 不会主动说我注意到仓库里有一个你没告诉我的目录。它只会按照已知信息行动而已知信息不包含新服务时它的行为看起来完全合理——只是架构上是错的。这就是为什么谁改结构谁更新地图必须是一条硬性规则而不是可选的良好实践。这个案例也说明了为什么 02第一个仓库任务[3] 里强调让 Claude Code 先读懂项目再动手——如果第一次任务就要求它生成项目地图草稿这类遗漏有机会在早期被发现。落地清单写完项目地图后逐项检查• [ ] Claude Code 能说出所有顶层目录及其职责• [ ] Claude Code 知道任意一个文件对应的测试命令• [ ] Claude Code 不会跨服务边界创建直接依赖• [ ] Claude Code 知道哪些文件不能手动修改• [ ] Claude Code 知道模块之间的调用方向谁调用谁• [ ] 项目地图在一到两屏内可读完超过两屏说明太详细或需要拆分到 rules• [ ] 有明确的责任人负责在结构变更后更新地图• [ ] 定期每两周或每 sprint用复述测试验证地图是否过期权衡项目地图不是架构文档。它不应该解释为什么选择 Express 而不是 Fastify不需要 UML 图不需要历史决策记录。它只回答在哪、怎么跑、什么不能动三个问题。超过两屏的项目地图通常已经开始变成维护负担——详细的规则应该下沉到.claude/rules/按路径加载参考 05rules[2]。项目地图也不是只给 Claude Code 看的。一份好的地图对新成员同样有效。如果新同事读了地图后能正确回答我在哪里写支付逻辑这份地图就是对的。反过来如果新同事读完地图还是不知道支付逻辑在哪Claude Code 也大概率不知道——这时候需要回去检查地图的边界段是否足够明确。最后一点项目地图是 Claude Code 理解项目的起点不是终点。地图解决的是在哪、怎么跑的问题。更深层的为什么要这样组织、这个模块的设计意图是什么需要靠 04CLAUDE.md[1] 中的架构上下文和 05rules[2] 中的路径级规则来补充。三者的关系是项目地图是骨架CLAUDE.md 是说明书rules 是操作手册。Map 与 CLAUDE.md 其他段的重叠分析项目地图在 CLAUDE.md 中不是孤立段落。它和 CLAUDE.md 的其他段有明确的职责划分放错位置会造成信息冗余或加载浪费。CLAUDE.md 内容分层 ┌─────────────────────────────────────────────────┐ │ 全局指令段每次会话加载 │ │ │ │ ┌─────────────┐ ┌──────────────┐ ┌──────────┐ │ │ │ Project Map │ │ Commands │ │ Safety │ │ │ │ 目录边界 │ │ 测试/构建命令 │ │ 禁区声明 │ │ │ └─────────────┘ └──────────────┘ └──────────┘ │ │ │ │ ┌─────────────┐ ┌──────────────┐ │ │ │ Architecture│ │ Conventions │ │ │ │ 设计意图 │ │ 命名/风格 │ │ │ └─────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────┐ │ 按需加载段.claude/rules/ 路径级 │ │ │ │ ┌─────────────┐ ┌──────────────┐ │ │ │ style.md │ │ review.md │ │ │ │ 代码风格细节 │ │ PR 审查清单 │ │ │ └─────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────┘常见的重叠误区和修正误区 1在 Project Map 里写代码风格规则 错误services/ 里的函数使用 camelCase 命名 正确风格规则放 .claude/rules/style.mdMap 只说services/ 负责业务逻辑 误区 2在 Architecture 段重复目录结构 错误Architecture 段又列了一遍目录树 正确Architecture 只解释设计意图为什么 handlers 不含业务逻辑目录清单在 Map 里 误区 3在 Safety 段重复 Boundaries 规则 错误Safety 段写不能在 web 里导入 api 代码 正确Safety 只放物理禁区生成文件、凭据逻辑边界在 Map 的 Boundaries 段 误区 4Commands 段省略依赖 Map 段的描述 错误Map 里写用 vitest 跑测试Commands 段为空 正确Map 只说测试策略Unit: VitestCommands 给出精确命令判断标准如果同一条信息出现在 CLAUDE.md 的两个段落中其中一个是多余的。用 CtrlF 搜索关键术语目录名、命令名检查是否有重复声明。Frontmatter 与 Map 的配置协同CLAUDE.md 的 frontmatter 字段和项目地图段有隐含的协同关系。理解这种关系能避免配置冲突。# CLAUDE.md frontmatter 示例---project_name:payment-platformprimary_language:typescriptpackage_manager:pnpmframework:next.js expresstest_framework:vitest---Frontmatter 声明的是项目元属性Map 声明的是项目结构细节。两者的分工frontmatter元属性机器可解析 - 告诉 Claude Code 项目的基本技术栈 - 决定 Claude Code 默认使用哪些代码模式 - 一个字段一个值不允许歧义 Project Map结构描述人可读 - 告诉 Claude Code 目录之间的关系和边界 - 提供精确的命令写法和依赖方向 - 允许描述性语句但每条规则必须无歧义关键约束frontmatter 和 Map 不能矛盾。如果 frontmatter 声明test_framework: vitestMap 里的 Test Strategy 段不能写 “Unit: Jest”。如果 frontmatter 声明package_manager: pnpmMap 的 Commands 段不能出现npm install。这种矛盾在 Claude Code 的推理中会产生不可预测的行为——它可能随机选择其中一个也可能两个都尝试。质量诊断的量化方法前文描述了四个定性测试。在实际团队中需要把这些测试转化为可量化的标准方便做跨项目的横向对比和趋势跟踪。测试评分标准每个测试按 0-3 分打分满分 12 分。评分标准测试一目录复述满分 3 分 3 分所有顶层目录职责描述准确包含目录间依赖关系 2 分所有目录提到但 1-2 个职责描述模糊或缺少依赖关系 1 分遗漏 1 个目录或 3 个以上职责描述不准确 0 分遗漏 2 个目录或职责描述大面积不准确 测试二边界识别满分 3 分 3 分正确识别跨模块边界给出符合架构意图的方案 2 分识别了边界但方案不够精确如通过 HTTP 而非共享库 1 分提到了边界但方案违反了一条边界规则 0 分完全无视边界建议跨模块直接导入或复制逻辑 测试三命令精准度满分 3 分 3 分给出精确到单个文件/目录的测试命令 2 分给出了包级别的命令如 pnpm --filter api test 1 分只给出全量命令如 pnpm test 0 分命令不正确或使用了不存在的脚本名 测试四禁区尊重满分 3 分 3 分执行操作后主动提醒必需的后续步骤如 migrate 2 分执行操作但没有主动提醒后续步骤 1 分执行操作且触犯了一条软性禁区 0 分修改了明确标记为 off-limits 的文件评分与行动对应10-12 分项目地图质量合格可以进入复杂任务 7-9 分有改进空间补充对应段落后重测 4-6 分质量不足建议重写项目地图而非修补 0-3 分项目地图严重缺失从零开始构建量化方法的执行频率首次编写后连续跑 3 次取平均分排除随机波动 结构变更后跑 1 次确认无退化 每两周/sprint 结束跑 1 次检查过期 新成员加入时让新成员对照地图做一次测试一验证人可读性真实生产项目的 CLAUDE.md 地图段以下是一个真实电商平台后端的 CLAUDE.md 项目地图段已脱敏展示完整配置密度## Project Map ### Structure apps/ gateway — API GatewayHapi.js路由注册 限流 auth order-service — 订单服务Fastify订单生命周期管理 payment-service — 支付服务Fastify支付/退款/对账 inventory-service — 库存服务Fastify库存扣减 预占 notification-worker — 通知消费者BullMQ邮件/短信/Push packages/ db-schema — Prisma schema generated client所有服务共用 shared-types — TypeScript 类型定义跨服务 DTO event-bus — 事件发布/订阅封装RabbitMQ logger — 结构化日志Pino wrapper testing — 测试工具库mock helpers, test containers ### Architecture Diagram gateway → order-service → payment-service → inventory-service order-service → event-bus → notification-worker payment-service → event-bus → notification-worker All services → packages/db-schema (read-only import) All services → packages/logger (read-only import) ### Commands - Install: pnpm install --frozen-lockfile - Dev all: docker compose up -d pnpm dev - Dev single: pnpm --filter order-service dev - Test all: pnpm -r test - Test single: pnpm --filter order-service vitest run src/services/ - Test coverage: pnpm --filter order-service test:coverage - Build: pnpm -r build - Lint: pnpm -r lint - Type check: pnpm -r typecheck - DB reset: pnpm --filter db-schema prisma migrate reset - DB migrate: pnpm --filter db-schema prisma migrate dev --name 描述 ### Boundaries - 每个服务有自己的数据库 schemaPrisma multi-schema不允许跨服务直接查表 - 服务间通信只走 HTTP同步或 event-bus异步不允许直接 import 另一个服务的代码 - packages/db-schema 是唯一允许包含 Prisma import 的包 - packages/event-bus 封装了所有消息格式服务不能直接使用 amqplib - handlers 层不允许包含业务逻辑只做参数校验 调用 service 格式化响应 - services 层不允许 import Fastify/Express 的类型保持框架无关 ### Test Strategy - Unit: Vitestservices/, utils/ - Integration: Vitest testcontainersPostgreSQL - Contract: Pact服务间 API 契约测试 - E2E: Playwright仅 gateway 暴露的外部 API - 单文件: pnpm --filter svc vitest run path ### Off-limits - packages/db-schema/prisma/migrations/ — 只通过 prisma migrate 生成 - packages/db-schema/src/generated/ — Prisma 生成代码 - apps/*/dist/ — 构建产物 - docker-compose.yml — 基础设施配置需 DevOps 审查 - pnpm-lock.yaml — 不手动编辑 - .env* — 凭据和环境变量 - apps/*/seeds/ — 生产种子数据修改需 DBA 审批这份地图约 60 行覆盖了 6 个问题和 2 个架构要素。它在实际使用中的评分记录是 11/12测试三偶尔给出包级命令而非文件级命令扣 1 分。在 6 个月的维护中它被更新了 4 次新增 2 个服务、改变 1 个命令、补充 1 条边界规则。每次更新都由做出结构变更的开发者在同一个 PR 中完成。维护责任的团队实践前文提到谁改结构谁更新地图。在团队中落地这条规则需要具体的执行机制不能只靠自觉。PR Template 强制检查## PR Template加在团队默认模板中 ### Project Map Updates - [ ] 本次 PR 是否涉及以下变更勾选适用项 - [ ] 新增或删除了顶层目录/服务 - [ ] 修改了测试命令或构建命令 - [ ] 新增或修改了服务间依赖关系 - [ ] 新增了需要标记为 off-limits 的文件 - [ ] 如有以上变更已更新 CLAUDE.md 的 Project Map 段 ### Verification - [ ] 已运行 pnpm typecheck 和 pnpm lint - [ ] 已运行相关测试自动化验证脚本在 CI 中加入一个轻量检查验证 CLAUDE.md 的项目地图段没有明显过期#!/bin/bash# ci-check-map.sh — 验证项目地图与实际结构的一致性# 检查 CLAUDE.md 中提到的目录是否都存在echoChecking directories mentioned in CLAUDE.md...DIRS$(grep-E#x27;^\s*-\s?apps/|packages/#x27; CLAUDE.md | \sed#x27;s/.*\(.*\).*/\1/#x27; | sed #x27;s/.*—.*//#x27;)fordirin$DIRS;doif[!-d$dir];thenechoWARNING: CLAUDE.md mentions$dirbut directory does not existfidone# 检查 CLAUDE.md 中提到的命令是否都能执行echoChecking commands mentioned in CLAUDE.md...CMDS$(grep-oP#x27;(pnpm|npm|npx|yarn) [^]#x27; CLAUDE.md | tr -d #x27;#x27;)forcmdin$CMDS;do# 只检查命令是否存在--help不实际执行if!$cmd--help/dev/null;thenechoWARNING: Command #x27;$cmd#x27; in CLAUDE.md may not be validfidone这个脚本不验证内容的正确性那需要语义理解只做结构层面的存在性检查。它能捕获删了目录但忘了更新 CLAUDE.md这类最常见的过期场景。地图更新的责任矩阵变更类型 │ 谁更新 │ 何时更新 │ 验证方式 ─────────────────────┼────────────────┼──────────────────┼────────────── 新增/删除目录 │ PR 作者 │ PR 合并前 │ CI check-map 改变测试框架 │ PR 作者 │ PR 合并前 │ 命令精准度测试 新增服务间依赖 │ PR 作者 │ PR 合并前 │ 边界识别测试 修改 CI 流程 │ DevOps │ 配置变更 PR 中 │ 命令精准度测试 新增 off-limits 文件 │ 发现者 │ 立即hotfix 级 │ 禁区尊重测试 更新依赖版本 │ 升级 PR 作者 │ PR 合并前 │ 不影响地图新增 off-limits 文件是唯一需要立即更新的类型。因为这类变更通常发生在安全事故或近失误之后——如果某个文件被误修改导致了问题它应该立刻被标记为 off-limits等不到下一个 PR。引用链接[1]04CLAUDE.md:./04-claude-md-project-memory.md[2]05rules:./05-rules-path-scoped-context.md[3]02第一个仓库任务:./02-setup-permission-first-repo-task.md