| feature_ids |
|
|
|---|---|---|
| topics |
|
|
| doc_kind | note | |
| created | 2026-02-26 | |
| updated | 2026-05-23 |
三猫开发全流程的导航图。每步的详细操作在对应 skill 内。 Stage id / suggested skill / hard rules / pitfalls 的机器真相源是
sop-definitions/development.yaml;本文件保留人类可读叙事。 冲突时先修 SopDefinition 单一源,再同步本文件和相关 skill。
Cat Café 的开发是愿景驱动的。和operator确认了 feature 的愿景后:
- 没达成愿景 = 没完成,必须继续做,不能半路停下来问"要不要继续"(§17)
- 唯一停下来的理由:发现了原本没发现的、确实解决不了的阻塞(技术限制/外部依赖不可用),此时升级operator
- SOP 每步自动推进,全链路闭环到愿景守护通过为止
大 scope feature 不能等最后才对齐愿景。每个 Phase merge 后,主动和operator碰头:
Phase N merge → 碰头(不是"要不要继续",是"方向对不对")→ 继续 Phase N+1
碰头格式(轻量,不是报告会):
- 成果展示:这个 Phase 做了什么(截图 / 关键改动 / demo)
- 愿景进度:离最终愿景还差什么(哪些 AC 打了勾,哪些还没)
- 下个 Phase 方向:下一步计划做什么,有没有发现新问题
- 方向确认:"方向对吗?有没有要调整的?"
注意区别:
- 碰头 = 愿景方向确认(宏观层,operator需要介入)✅
- "要我继续吗?" = SOP 流程推进(细节层,不要问)❌
小 Feature(1-2 Phase):不需要碰头,直接做到底 → 愿景守护 → close。
../cat-cafe-runtime 是咱们的运行态单实例(通常占用 3003/3004),默认视为在线服务,不是随手重启的实验环境。
硬规则:
- 在 runtime 会话里,禁止执行会触发重启的命令:
pnpm start、pnpm runtime:start、./scripts/start-dev.sh - 做截图/验收/排查前,先复用现有服务(先查
curl -sf http://localhost:3004/health) - 确实要重启,必须先拿到operator明确同意,再显式设置
CAT_CAFE_RUNTIME_RESTART_OK=1执行启动命令
说明:--force 不是重启授权,不能替代第 3 条。
../cat-cafe-alpha 是基于最新 origin/main 的隔离测试环境,供operator和猫猫们验收最新改动,不干扰 runtime。
| 命令 | 作用 |
|---|---|
pnpm alpha:start |
自动同步 origin/main + 拉起 3011/3012/4111/6398 |
pnpm alpha:sync |
只同步不启动 |
pnpm alpha:status |
查看环境状态 |
使用场景:
- 愿景守护:守护猫用 alpha 独立验证已合入 main 的改动,不依赖开发猫提供环境
- operator测试:稳定的测试入口,和 runtime 互不干扰
- PR merge 后验收:确认合入 main 的改动在完整环境中工作正常
注意:alpha = origin/main 镜像,只能验证已合入 main 的改动。未合入改动的自测仍在 feature worktree 上做。已合入改动的验收用 alpha(3011/3012),不得用 runtime(3003/3004)冒充。
../cat-cafe-develop 是基于最新 origin/develop 的日常狗粮环境,用于体验已通过 fork 内部 PR 合入 develop 的集成态。
| 命令 | 作用 |
|---|---|
pnpm develop:start |
自动同步 origin/develop + 用 runtime 默认端口拉起 develop stack |
pnpm develop:sync |
只同步不启动 |
pnpm develop:status |
查看环境状态 |
端口默认与 pnpm start 一致:Web 3003、API 3004、Redis 使用 runtime 默认配置。pnpm start 与 pnpm develop:start 是同一套本地单例端口,不能同时运行;切换前先 pnpm stop。
需要临时隔离端口时,可显式设置 CAT_CAFE_DEVELOP_WORKTREE_PORT_OFFSET,但这不是日常狗粮默认路径。
注意:pnpm start 永远是 runtime 主线入口,仍同步 origin/main。不要为了体验 develop 改写 pnpm start 语义。
⓪ Design Gate → 设计确认(UX→operator/后端→猫猫/架构→两边)
① impl → writing-plans → worktree → tdd
② quality-gate → 自检 + 愿景对照 + 设计稿对照
②½ fresh-context → (可选)author-triggered pre-review scan(finding generator, not approval)
③ review 循环 → 本地 peer review(P1/P2 清零 + reviewer 放行)
④ merge-gate → 门禁 → PR → remote review → squash merge → 清理
⑤ 愿景守护 → 非作者非 reviewer 的猫做愿景三问 → 放行 close / 踢回
⚠️ Design Gate 在 ① 之前! UX 没确认不准开 worktree。PR 在 ③ 之后。⚠️ 全链路自动推进(§17)! SOP 有写下一步 → 直接做,不要停下来问operator。
| Step | 做什么 | Skill | 详情 |
|---|---|---|---|
| ⓪ | 设计确认:前端→operator画 wireframe;后端→猫猫讨论;架构→两边 | feat-lifecycle Design Gate |
Trivial 跳过⓪,按下方例外路径判断 |
| ① | 写实施计划 → 创建 worktree → TDD 实现 | writing-plans → worktree → tdd |
sop-definitions/development.yaml 的 impl.suggested_skill 是 writing-plans;计划写完自动进入 worktree/TDD,禁止直接改 main |
| ② | 愿景对照 + spec 合规 + 跑测试 + 有 .pen 则设计稿对照 | quality-gate |
AC ≠ 完成,问"operator体验如何?" |
| ②½ | (可选) Fresh-context pre-review scan | fresh-context-review |
Author 判断是否需要;非 trivial PR 推荐。Finding generator, not approval authority |
| ③a | 发 review 请求(五件套 + 证据) | request-review |
附原始需求摘录 |
| ③b | 处理 review 反馈(Red→Green) | receive-review |
禁止表演性同意 |
| ④ | 门禁 → PR → remote review → merge → 清理 | merge-gate |
③ 放行后才进入,模板见 refs/pr-template.md |
| ⑤ | 愿景守护 + feat close(feature 最后一个 Phase 时) | feat-lifecycle completion |
守护猫 ≠ 作者 ≠ reviewer,动态选(查 roster) |
改 MCP tool、skill manifest、route、workflow callback 等约定面前,先用 convention graph 查影响面,避免只靠 grep 漏掉注册链或动态消费方。
pnpm convention-graph:index -- --repo .
MCP_TOOL_NAME=replace_with_tool_name
pnpm convention-graph:code-consumers -- --repo . --domain mcp-tool --kind mcp_tool --name "$MCP_TOOL_NAME"查询结果里的 freshness.stale=true 表示图不能当 fresh 证据;先重跑 pnpm convention-graph:index -- --repo .,再做影响面判断。
三个条件全部满足才可跳过:
- operator在当前对话明确同意
- 纯文档 / ≤10 行 bug fix / typo
- 不涉及安全、鉴权、数据、API 变更
四个条件全部满足:
- 纯日志/配置/注释/文档(不涉及业务逻辑)
- diff ≤ 5 行
- 类型检查通过
- 不涉及可测行为
核心问题:F192
cat_cafe_publish_verdict会为每次 scheduled eval 自动开 PR 归档 verdict 证据。这种 PR 不是代码 review request,是 eval evidence artifact。让operator / 通用 reviewer 走 full merge-gate 验收 = 把 operator 当 merge queue + 噪音灾难(PR #2114 实战暴露)。解法:满足以下 9 条硬条件 → 任一非作者猫走 artifact-only merge-gate,跳过 full
pnpm gate+ 跳过remote review;cats 自决 squash merge。operator 不在 reviewers / 不需 sign-off。失败任一条 → 必须走 regular merge-gate(reviewer + cloud + full gate)。
- 路径范围(domain-aware allowlist):PR diff 仅含以下任一允许路径:
docs/harness-feedback/(所有 verdict 的 verdict.md + bundle JSON)generated/capability-wakeup/<verdictId>/(仅 eval:capability-wakeup verdicts;cw generator 的 replayed raw inputstrials.json+summary.json,被 provenance.json 引用,PR-2 R3 P1 cloud 锁住 staging)generated/memory/<verdictId>/(仅 eval:memory verdicts;memory generator 的 replayed raw inputsrecall-metrics.json+library-health.json,被 provenance.json 引用,F192 memory wire-up cloud R8 P1 锁住 staging)- 任何其他路径出现 → 退到 regular merge-gate
- 额外校验:若包含
generated/<domain-slug>/,必须满足 PR 是verdict/auto/eval-<domain-slug>/<verdictId>分支 且<verdictId>匹配 PR title(防止 a2a/sop PR 借 generated/ 路径绕道;适用于 cw + memory)
- 零 code files:无
.ts/.tsx/.js/.mjs/.cjs/.py/.sh等 - 零 root artifacts:复用 Step 0.5 Root Artifact Guard(无根目录 .png / .pen / 媒体文件)
- mergeable + clean:
mergeState == CLEAN+mergeable == MERGEABLE - 非 hotfix:
scripts/check-hotfix-pattern.mjs返回hotfix=false - PR title 模式匹配:title 含
verdict(前缀(如verdict(eval:a2a): 2026-06-06-...) - PR body 模式匹配:body 含字符串
Verdict published via cat_cafe_publish_verdict MCP tool—— 防止被滥用为通用 cat-merge 绕道 - 作者 ≠ merger:保留 cross-individual 原则(生成方猫 = 发起 publish 的 eval cat;merger = 任一非生成方猫)
evidence-onlylabel 必须 present(cloud R6 P2 — 锁住 policy 判断):PR 必须有evidence-onlylabel。computePublishPolicy只对keep_observeverdict 应用该 label;fix/build/delete_sunsetverdict policy 返回regular_pr(无 evidence-only label) → 必须走 regular merge-gate(owner action required)。关键:title 含verdict(前缀和 body 含cat_cafe_publish_verdict字符串只能证明 PR 是 publish-verdict 自动生成的,不能证明该 PR 不需要 owner action。evidence-onlylabel 是 policy 显式判断"这条 verdict 无 actionable 内容"的唯一信号;缺失 → 必须走 regular merge-gate(哪怕 PR 是自动生成的)。
# 1. Detect: 收到 #N PR notification (autonomous via PR review feedback bot, or manual scan)
gh pr view N --json title,body,headRefName,mergeable,mergeStateStatus,changedFiles --jq '.'
# 2. Verify 9 conditions
# Condition #1: paths only in docs/harness-feedback/ OR generated/capability-wakeup/<verdictId>/ OR generated/memory/<verdictId>/
VERDICT_ID=$(gh pr view N --json title --jq '.title' | sed -E 's/.*verdict\([^)]+\): //; s/[[:space:]].*//')
gh pr view N --json files --jq '.files[].path' \
| rg -v "^(docs/harness-feedback/|generated/capability-wakeup/${VERDICT_ID}/|generated/memory/${VERDICT_ID}/)" \
&& echo "FAIL #1: paths outside artifact-allowlist"
PR_NUMBER=N node scripts/check-hotfix-pattern.mjs N | jq -r '.hotfix' # must be false
# (title/body checks: gh pr view ... | grep)
# Condition #9 (cloud R6 P2): require evidence-only label (policy classification check;
# fix/build/delete_sunset verdicts intentionally lack this label → must walk regular gate)
gh pr view N --json labels --jq '.labels[].name' | rg -q '^evidence-only$' \
|| echo "FAIL #9: no evidence-only label — verdict has actionable verdict severity; walk regular merge-gate"
# 3. If all 9 pass: squash merge
gh pr merge N --squash --delete-branch
# 4. NO Phase doc sync needed (artifact PR doesn't change feature spec)
# NO worktree cleanup needed (artifact PR is auto-generated, no local worktree)cat_cafe_publish_verdict 自动给 artifact PR 加 labels:
evidence-only:所有 artifact-only PR 都有此 label(filterable)no-action-needed:keep_observe + 无 actionable findings(rollup mechanism 落地前的 interim 标记)
operator / operator 在 PR list 可按 evidence-only label 过滤掉所有 artifact PR,不必每次看到都问"谁 merge"。
PR-3 是 interim 方案 —— 仍开 per-run PR,只是 label + 猫自决 merge。真正解是 rollup mechanism(daily/weekly batch PR 聚合 N 个 no-action verdict,或 runtime evidence store + 周期 flush archive PR)。独立 Phase 排期,等 PR-3 体感数据反馈后再 design。
动态匹配自运行时猫配置(repo 根 cat-template.json + .cat-cafe/cat-catalog.json overlay):
- 跨 family 优先 | 2. 必须有 peer-reviewer 角色 | 3. 必须 available
- 优先 lead | 5. 优先活跃猫
降级:无跨 family reviewer → 同 family 不同个体 → operator。
铁律:同一个体不能 review 自己的代码。
共享 GitHub 账号澄清:全家共用 zts212653 账号,"个体"判据 = catId(opus-47 / codex / gpt-5.4 等),不看 GitHub login。GitHub dismiss_stale_reviews_on_push 因共享账号视所有猫为同一 pusher → mergeStateStatus=BLOCKED;此时 --admin --match-head-commit 是合规 fast-path,不是 self-review violation,无需纠结或升级 operator。
| 工具 | 命令 | 何时 |
|---|---|---|
| Biome | pnpm check / pnpm check:fix |
开发中 + Step ② |
| TypeScript | pnpm lint |
Step ② 必跑 |
| shared rebuild | pnpm --filter @cat-cafe/shared build |
shared 包改后 |
| 目录卫生 | pnpm check:dir-size + pnpm check:deps |
新增文件时 |
详见 ADR-010(目录卫生)。
新增 process.env.XXX 引用 → 必须在 packages/api/src/config/env-registry.ts 的 ENV_VARS 数组注册。
前端「环境 & 文件」页面自动展示,不注册 = operator看不到 = 不存在。
docs/下.md文件必须有 YAML frontmatter(ADR-011)- 完成后必须同步真相源(详见
feat-lifecycleskill) - 归档查找:(internal reference removed)
开源仓 clowder-ai 的社区 issue 由猫猫 triage,operator决定是否立项。
| 角色 | 谁 | 做什么 |
|---|---|---|
| Triage | 任意猫(收到 @ 或主动巡查) | 给 issue 加 bug / feature label,回复确认收到 |
| F 号分配 | operator拍板 → 猫执行 | 在 ROADMAP.md 加条目,分配下一个可用 F 号 |
| Feature Doc | 分配到的猫 | 按模板写 docs/features/F{NNN}-slug.md |
| 实现 | 任意猫或社区贡献者 | 按 Feature Doc AC 实现 + PR |
社区开 issue → 猫 triage(加 label)→ operator拍板
├─ Feature → ROADMAP.md 加 F{NNN} → Feature Doc → 实现 → 全量 sync 推送
└─ Bug fix → worktree(sync tag) → 修 → sync-hotfix.sh → clowder-ai PR → cherry-pick 回 main
社区报 bug 时,不必等全量 sync,直接走 hotfix lane:
git worktree add -b fix/xxx ../cat-cafe-hotfix-xxx sync/LATEST-TAG- 在 worktree 里修 bug
cd ../cat-cafe-hotfix-xxx && bash scripts/sync-hotfix.sh fix/xxx <changed-files>- 在 clowder-ai 上开 PR、review、merge
- Cherry-pick fix 回 cat-cafe main
intake-from-opensource.sh --record --pr <N> --decision <absorbed|public-only>- 若
--decision absorbed:hotfix 是我们自己 outbound 提的(没有 cat-cafe 的 Intake Intent Issue / absorb PR),必须加--skip-absorbed-guard跳过 strict guard - 若是社区 inbound PR 的 absorbed record(不是本条 hotfix 流程),参见
cat-cafe-skills/refs/opensource-ops-inbound-pr.md,要带--intent-issue <I> --absorb-pr <P> --review-proof <URL|file>
- 若
intake-from-opensource.sh --advance-ledger
详见 Hotfix Lane 设计 (internal)
全量同步到 clowder-ai 时,不能只看家里的 pnpm gate 绿不绿。
source gate green != target/public gate green。
硬规则:
- 先在
cat-cafe导出同一份同步产物到 temp target - 在 temp target 跑完整 public gate:
pnpm check、pnpm lint、build、pnpm --filter @cat-cafe/api run test:public、startup acceptance - 只有 temp target public gate 全绿,才允许碰真实
clowder-ai - 本机 README/macOS smoke 不属于 full sync 主路径;它必须是 sync 完成后的独立步骤,且必须显式隔离端口/Redis
一句话:不要再把真实 clowder-ai 当第一轮验收场,更不能把 runtime 当验收靶子。
公开 release 不要求 cat-cafe 和 clowder-ai 同 SHA;我们要求的是可追溯映射。
硬规则:
- release-intended full sync 必须从家里 source 侧显式传
--release-tag=vX.Y.Z sync-to-opensource.sh在 temp target public gate 通过后,会自动打并 pushclowder-vX.Y.Z-source.sync-provenance.json必须记录:source_commit_sharelease_tagsource_snapshot_tag
- target 仓后续真正切
vX.Y.Z时,必须通过:
bash scripts/publish-release-tag.sh \
--release-tag=vX.Y.Z \
--target-sha <clowder_ai_release_commit_sha> \
--reconciliation-report=docs/ops/reconciliation-vX.Y.Z.md \
--pushpublish-release-tag.sh会强制校验两层门禁:source snapshot tag → .sync-provenance.json → target release tag三点映射reconciliation report必须存在;如果报告把 issue 记为closed,GitHub 上也必须已经是CLOSED
release notes /后续 backport 也必须引用这些锚点,而不是口头约定。
一句话:以后对齐 release,不靠“记得当时是哪次 sync”,靠 source snapshot tag → target release tag → backport commit 三点映射。
- 社区和内部共用一套 F 编号:不另起 P/CEP/社区专属编号系列(2026-03-13 决策,详见 F059 spec D6)
- F 编号唯一源:ROADMAP.md(operator拍板后猫执行分配)
- Bug 不编号:直接用 issue # 追踪,修完 close(D7)
- 贡献者不自选号:CONTRIBUTING.md 已写明,猫猫回复时也要强调(D8)
- 分配 F 号前必须做关联检测:确认 issue 不是现有 feature 的子项/增强(F114-F116 撤销教训,D9)
- 社区贡献者的 PR:猫猫用
community-prskill 引导(编号校验 + Feature Doc 对齐)
开源仓 clowder-ai 的 issue label 统一格式:
| Label | 格式 | 颜色 | 说明 |
|---|---|---|---|
| Feature 关联 | feature:F{NNN} |
#0E8A16 绿 |
关联到 cat-cafe Feature 编号 |
| Bug | bug |
GitHub 默认 | 社区 bug report |
| Enhancement | enhancement |
GitHub 默认 | 社区增强建议 |
注意:
- Feature label 必须用
feature:F{NNN}格式(带feature:前缀 + 大写 F + 三位数字),不要用裸编号如F115 - Label 在 cat-cafe 定义规范,通过 sync 流程同步到 clowder-ai 的 CONTRIBUTING.md
- 新建 label 时统一用绿色
#0E8A16