Imported from RabbitAI-Lab/RabbitWork (
AGENTS.md). Install upstream withnpx skills add RabbitAI-Lab/RabbitWork. Copyright stays with the author.
AGENTS.md — RabbitWork 工作规范(AI 与人类协作者必读)
本文件是仓库的最高工作规范。任何 AI 会话(Claude Code / ZCode 等)或人类协作者在本仓库工作前必须先读本文。 CLAUDE.md 与本文件保持同步,规范冲突时以本文件为准。 本规范自 RabbitAITest(RabbitAI-Lab 前代项目)全量移植,工程经验出处标注为「RabbitAITest 先例」。
0. 项目一句话
【待定】RabbitWork:……(产品一句话与对标基线必须在首个产品规格评审前由人工填定)。
当前阶段交付物是工程脚手架(Sprint 0,见 docs/sprint-0-scaffold/);产品域文档随首个迭代产出。
1. 硬性工作流门禁(违反即停止开发)
门禁 1:文档先行
任何功能开始编码前,必须有对应规格文档 docs/sprint-{N}-*/{MODULE}-NNN-*.md 且状态为 Approved。没有文档的代码 PR 直接拒绝。规格必须用 docs/plan/功能规格模板.md 的固定七章结构。
门禁 2:高保真原型 + 人工确认 + 实现后走查(最重要)
每个功能点必须先产出高保真原型,经人工确认通过后,才能开始功能迭代开发;实现完成后必须走查对照原型。
- 执行顺序铁律(RabbitAITest S2 教训):高保真原型的产出必须先于对应功能的编码——任何会话的任务清单(todo)/执行计划/看板中,「产出高保真原型」必须排在对应功能编码任务之前;禁止在原型未产出时开始该功能编码,也禁止把原型产出排到实现/测试之后「后补」。可依先例后置的只有人工确认与走查,不包括原型产出本身。规格文档「高保真确认」字段必须如实:原型文件创建前不得写「原型已产出」(虚标即规格缺陷)
- 高保真原型产出在
docs/design/{MODULE}-NNN-{slug}/(静态 HTML+Tailwind 或 Storybook story,可浏览器打开走查) - 规格文档元信息表必须含「高保真确认」字段:
确认人 / 确认日期 / 原型链接;未确认前该字段为待确认,编码不得开始 - 确认后如交互变更,须更新原型并重新确认,状态回到
待确认 - 纯后端/引擎类规格以「接口契约评审」替代高保真:OpenAPI/事件流 schema 人工确认后视为通过
- 实现完成 ≠ 与高保真一致:UI 功能交付前必须与原型逐项走查(布局/交互/各状态/边界/裁剪),走查批次编号登记(走查①②③…);发现差异要么回改实现、要么更新原型并登记「勘误 N」(勘误记在原型目录 README,可追溯)——前代实践中约 1/3 的 UI 缺陷(布局裁剪、漏挂组件、下拉被裁切)由走查环节暴露
- 走查结论、录屏(§rules/testing 3.3)与视觉还原度报告(多模态比对高保真↔实现截图,工具随首个 UI 迭代接入)一并归档进 PR 描述
门禁 3:一次建齐数据模型
核心域表在 packages/db/prisma/schema.prisma 随该域首份规格一次性建齐全部列(含未启用列),后续迭代只做「开关 + 种子 + 索引」。新增列必须说明为何无法初期建齐并经架构评审。
门禁 4:API 契约纪律
- 端点必须符合
docs/architecture/api-conventions.md(路径 / 响应信封 / 错误码分段 / 分页 / 软删除) - 请求响应 schema 一律用 zod 定义于
packages/shared,OpenAPI 由 schema 生成(生成管线随首个 API 落地接入,RabbitAITestscripts/gen-openapi.mjs先例,接入当天接 CI 快照校验) - 前端禁止手写接口路径,只能使用
packages/api-client的方法
门禁 5:权限与解耦
- 每个端点声明所需权限点(
packages/shared/permissions.ts),经withPermission()包装(见 rbac-permission-model.md) - 跨域读实体只准经 Provider 接口,禁止跨域直接查表(见 dependency-graph.md §4;红线登记
scripts/check-boundaries.domains.json) - 后台 worker(
apps/engine,引入时)不得 importapps/web与packages/db(引擎无数据库依赖)——pnpm lint:boundaries静态拦截
门禁 6:范围红线
- 产品范围与优先级红线(P0-P4 分级)随产品定位评审确定后登记于需求总纲;未定前只做工程基线与已评审规格内的工作,禁止 speculative 功能
- 技术栈变更 = 架构级决策,须修改
docs/architecture/tech-stack.md并评审,不允许只在代码里悄悄换
门禁 7:自动化测试门槛(功能「完成」的定义)
任何功能点开发完成 = 功能代码 + 单测 + JMeter 接口用例 + Playwright UI 用例全部交付且 CI 全绿,缺一项 PR 不予合并:
- 单元测试(Vitest):核心分支覆盖,与代码同 PR;核心域行覆盖率 ≥ 70%。
- 接口自动化(JMeter):每个功能点至少一个
tests/api/{MODULE}-NNN-*.jmx,必测四类场景(正常路径 / 401·403·404 权限 / 422 校验失败 / 分页信封);每个采样器四项断言必备(HTTP 状态码、业务码code、关键字段 JSONPath、响应时间上限)。 - UI 自动化(Playwright):按规格 §1.2 能力行覆盖——每行交互类能力至少一条
tests/e2e/{MODULE}-NNN-*.spec.ts,关键状态二态(预置/自定义、只读/可写、启用/禁用、空/有、有权/无权)显式覆盖(细则 rules/testing §1.2),且每条用例必须同时包含三类断言:- UI 断言:元素可见/文本/表格行数/表单回显/Toast 等界面结果
- Console 断言:全程无
console.error、无未捕获pageerror(白名单须显式登记) - 接口断言:关键链路网络请求的状态码、响应体关键字段、请求负载(payload)
- 主链路 E2E + 全量 tests/ 绿是 Release Gate。
详细规范(目录命名、fixtures、选择器、数据隔离、CI 执行)见 rules/testing.md。
门禁 8:测试与文档同步
- 规格 §5 用例表与 tests/ 文件编号一一对应,且必须覆盖 §1.2 全部 P1 能力行与关键状态二态(或显式登记豁免+理由);「先合功能后补测试」不允许;Bug 修复必须先写失败用例复现再修复转绿。
门禁 9:远程 CI 与 Sprint 交付纪律
- GitHub CI 必须通过:远端 CI(GitHub Actions)全绿是 PR 合并与任何交付的硬性条件——本地自测通过不等于完成,以远端 CI 结果为准。
- main 必须保持绿:main 分支 CI 变红即最高优先级(stop the line),先修复再继续任何新开发;禁止在红 main 上继续合并。
- 每个 Sprint 收尾必须 commit + push 到远程:Sprint 交付的定义包含「代码已 push 到 GitHub(合入 main 或功能分支)且远端 CI 全绿」;禁止代码只留在本地(防丢失、保证可追溯、远端 CI 真实执行)。
- Sprint 收尾同时完成:文档状态流转(sprint-overview 交付表更新)、changelog 追加(涉及用户可见变更时)。细化流程见 rules/git-workflow.md §8。
2. 技术栈约束(不得擅自变更)
| 项 | 选型 |
|---|---|
| 工程结构 | Monorepo:pnpm workspace + Turborepo,纯 TypeScript |
| 应用框架 | 全栈 Next.js(App Router + React 19):UI 与 API 同仓同应用,API 走 Route Handlers(REST,/api/v1) |
| 前端 | React + Ant Design(React 19 兼容版)+ Tailwind CSS + TanStack Query(+ Zustand,引入时登记) |
| 数据库 | embedded-postgres(@embedded-postgres/node):开发与单机部署内嵌免外部 DB;DATABASE_URL 可切外部 PostgreSQL 16 |
| ORM | Prisma(packages/db 唯一出口,schema + migration) |
| 异步任务 | BullMQ + Redis(预留,随任务体系引入;定时任务用 repeatable job) |
| 实时通道 | SSE(Route Handler 流式;Redis Stream 断线续传,预留) |
| 后台 worker | apps/engine(预留):Node.js worker(undici 采样、p-limit 并发槽),编码规范 rules/engine.md 已先行移植 |
| 中间件 | 仅 PostgreSQL + Redis 起步(+MinIO 预留) |
技术栈编码细则分层管理:本文件只定门禁与红线,细则全部在 rules/ 目录(9 份,按需扩展):
| 规则文件 | 适用场景 |
|---|---|
| rules/react-nextjs.md | React 19 / Next.js App Router 编码(组件边界、数据获取、Route Handler、状态) |
| rules/testing.md | 自动化测试:Vitest 单测、JMeter 接口(四类场景×四项断言)、Playwright UI(三类断言 + 录屏/trace + 每用例截屏) |
| rules/database.md | PostgreSQL/Prisma:命名、类型、索引、查询、迁移纪律、embedded-postgres |
| rules/engine.md | 后台 worker/执行引擎:状态机、事件流、kernel 纯函数、沙箱(引入 apps/engine 时生效) |
| rules/security.md | 安全:认证、输入校验、注入与越权、SSRF 边界、密钥、依赖供应链、Mimosa 误报处置 SOP |
| rules/typescript.md | TS 通用:strict 基线、命名、类型推导、错误处理、模块边界、注释 |
| rules/git-workflow.md | 分支/Commit/PR 模板/Review checklist/CI 流水线/版本与发布 |
| rules/observability.md | 结构化日志、reqId 链路、健康检查、指标、排障包 |
| rules/ai-collaboration.md | 人+AI 协作:会话冷启动义务、生成红线、验证义务、人保留决策 |
技术栈变更 = 架构级决策,须修改 docs/architecture/tech-stack.md 并评审,不允许只在代码里悄悄换。
3. 文档状态流转
Draft(起草)→ Approved(规格评审通过)
→ Prototyped(高保真已确认,编码可开始)
→ Implemented(代码合并)→ Verified(验收通过)
状态记录在规格文档元信息表;sprint-overview 的交付表同步更新。
4. 常用命令
pnpm install && pnpm dev # 启动 web(含 embedded-postgres 自动初始化 + migrate + seed)
pnpm test # Vitest 单测 + scripts 单测(含端口表守护)
pnpm test:api # JMeter 接口自动化(对已启动的 jm 栈执行,校验 jtl 失败数=0;需本机 jmeter)
pnpm test:e2e # Playwright UI 自动化(自动起全套服务,生产构建口径)
pnpm lint && pnpm format # oxlint / oxfmt
pnpm lint:boundaries # 模块边界静态检查(dependency-graph §4)
pnpm db:migrate && pnpm db:seed # Prisma 迁移与种子
4.1 环境复用优先(修复循环效率铁律)
逐条修复 × 每轮重建环境的循环,预计或实际超过 30 分钟时,必须停下来评估:环境能否复用就复用,禁止无脑每轮全量重建(initdb/迁移/起栈的固定开销 30-60 秒/轮,是修复循环最大的时间黑洞)。
- 已内置接口:e2e 带
E2E_DATABASE_URL(及需要时E2E_REDIS_URL)时 global-setup 检测到即跳过建库直接复用(常驻库维护工具 pg-e2e 随首个迭代按 RabbitAITest 先例移植) - 边界:持久库累积脏数据,依赖用例自身数据隔离(本就是规范);最终验收必须跑一次全新口径(不带 E2E_* 的
pnpm test:e2e)保证与 CI 一致 - 通用原则:任何「修复-验证」循环超 30 分钟,先审查固定开销(环境重建/全量跑),能增量就增量、能复用就复用;同时考虑并行修复(多问题互不依赖时并行处理)
4.2 并行 worktree 槽位隔离
多 worktree 并行联调/自测时,端口/Redis 键空间/共享 /tmp 路径按槽位隔离,单一事实源 scripts/rabbit-env.mjs(槽位推导:RABBIT_SLOT > 目录名 RabbitWork-s{N} > 主仓/CI=0)。硬性禁令:任何脚本/测试/服务禁止硬编码端口,一律从 rabbit-env 取值(e2e 用例侧走 tests/e2e/env.ts)。端口表与启动操作手册见 rules/git-workflow.md §9/§9.7。
速查:dev 栈 web 3600+s / PG 6440+s / Redis 6390·db{s};e2e 栈 web 3700+s / PG 6450+s / Redis 6391·db{s};JMeter 栈 web 3800+s / PG 6460+s。
端口基址相对 RabbitAITest(3000/3100/3200/4000/…/5440+ 系)整体偏移——同机两项目 worktree 并行互不冲突(scripts/rabbit-env.test.mjs 锁定该不变量)。
5. 协作与提交
- 分支:main 保护;feature 分支命名
{MODULE}-NNN-{slug}(与文档编号一致) - Commit:Conventional Commits(feat/fix/docs/refactor/test/chore),scope 用模块缩写(如
feat(case): ...;白名单见 commitlint.config.js) - 每个 PR 描述必须链接对应规格文档与高保真确认记录
- 文档与代码同 PR 变更:改了行为必须同步改文档(含状态流转)
- pre-push hook(husky):push 前跑
lint + typecheck
6. 阅读顺序(新会话冷启动)
- 本文件 → 2.
docs/README.md→ 3.docs/architecture/tech-stack.md→ 4.docs/architecture/monorepo-structure.md→ 5. 当前迭代sprint-overview.md→ 6. 目标功能规格 → 7. 按工作内容读对应 rules:编码前react-nextjs.md+typescript.md;写测试前testing.md;改模型/写 SQL 前database.md;worker 开发engine.md;提 PR 前git-workflow.md;安全相关security.md;日志/排障observability.md;AI 会话协作ai-collaboration.md
This is NOT the Turborepo you know
Turborepo configuration, task behavior, and CLI commands can vary between installed versions and may differ from your training data. Resolve the turbo package from this file's directory or relevant workspace; in monorepos, it may not be visible from the repository root. For example, run node -p "require.resolve('turbo/package.json')" from a workspace that depends on turbo.
Read docs/README.md inside that installed package first, then read the relevant pages from its docs/ directory before changing Turborepo configuration or commands. Heed deprecation notices. These bundled docs match the installed package version and are available without network access.
This block is written and re-added by turbo before repository-scoped commands when an AI agent is detected. In the Turborepo source repository, its template is defined in crates/turborepo-cli/src/cli/agent_guidance.rs. Removing the managed block while updates are enabled means a later qualifying invocation will add it again. Set "agentGuidance": false in the root turbo.json or turbo.jsonc to opt out; this does not remove an existing block. Keep the block committed with your work to avoid an uncommitted change on the next agent invocation.
