Skip to content

Latest commit

 

History

History
339 lines (249 loc) · 18.9 KB

File metadata and controls

339 lines (249 loc) · 18.9 KB
feature_ids
F042
topics
sop
doc_kind note
created 2026-02-26
updated 2026-05-23

Cat Café 开发 SOP

三猫开发全流程的导航图。每步的详细操作在对应 skill 内。 Stage id / suggested skill / hard rules / pitfalls 的机器真相源是 sop-definitions/development.yaml;本文件保留人类可读叙事。 冲突时先修 SopDefinition 单一源,再同步本文件和相关 skill。

愿景驱动(核心原则)

Cat Café 的开发是愿景驱动的。和operator确认了 feature 的愿景后:

  • 没达成愿景 = 没完成,必须继续做,不能半路停下来问"要不要继续"(§17)
  • 唯一停下来的理由:发现了原本没发现的、确实解决不了的阻塞(技术限制/外部依赖不可用),此时升级operator
  • SOP 每步自动推进,全链路闭环到愿景守护通过为止

大 Feature 碰头机制(3+ Phase)

大 scope feature 不能等最后才对齐愿景。每个 Phase merge 后,主动和operator碰头:

Phase N merge → 碰头(不是"要不要继续",是"方向对不对")→ 继续 Phase N+1

碰头格式(轻量,不是报告会):

  1. 成果展示:这个 Phase 做了什么(截图 / 关键改动 / demo)
  2. 愿景进度:离最终愿景还差什么(哪些 AC 打了勾,哪些还没)
  3. 下个 Phase 方向:下一步计划做什么,有没有发现新问题
  4. 方向确认:"方向对吗?有没有要调整的?"

注意区别

  • 碰头 = 愿景方向确认(宏观层,operator需要介入)✅
  • "要我继续吗?" = SOP 流程推进(细节层,不要问)❌

小 Feature(1-2 Phase):不需要碰头,直接做到底 → 愿景守护 → close。

Runtime 单实例保护(P0)

../cat-cafe-runtime 是咱们的运行态单实例(通常占用 3003/3004),默认视为在线服务,不是随手重启的实验环境。

硬规则:

  1. 在 runtime 会话里,禁止执行会触发重启的命令:pnpm startpnpm runtime:start./scripts/start-dev.sh
  2. 做截图/验收/排查前,先复用现有服务(先查 curl -sf http://localhost:3004/health
  3. 确实要重启,必须先拿到operator明确同意,再显式设置 CAT_CAFE_RUNTIME_RESTART_OK=1 执行启动命令

说明:--force 不是重启授权,不能替代第 3 条。

Alpha 验收通道

../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)冒充。

Develop 狗粮通道

../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 startpnpm develop:start 是同一套本地单例端口,不能同时运行;切换前先 pnpm stop

需要临时隔离端口时,可显式设置 CAT_CAFE_DEVELOP_WORKTREE_PORT_OFFSET,但这不是日常狗粮默认路径。

注意pnpm start 永远是 runtime 主线入口,仍同步 origin/main。不要为了体验 develop 改写 pnpm start 语义。

完整流程(5 步)

⓪ 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-plansworktreetdd sop-definitions/development.yamlimpl.suggested_skillwriting-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)

约定面改动预检(F242)

改 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 .,再做影响面判断。

例外路径

跳过remote review(Step ④ 中的 PR 环节)

三个条件全部满足才可跳过:

  1. operator在当前对话明确同意
  2. 纯文档 / ≤10 行 bug fix / typo
  3. 不涉及安全、鉴权、数据、API 变更

极微改动直接 main(跳过全流程)

四个条件全部满足:

  1. 纯日志/配置/注释/文档(不涉及业务逻辑)
  2. diff ≤ 5 行
  3. 类型检查通过
  4. 不涉及可测行为

Artifact-only PR merge-gate(F192 Phase H 收尾 PR-3 codified)

核心问题: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)。

9 条硬条件

  1. 路径范围(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 inputs trials.json + summary.json,被 provenance.json 引用,PR-2 R3 P1 cloud 锁住 staging)
    • generated/memory/<verdictId>/仅 eval:memory verdicts;memory generator 的 replayed raw inputs recall-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)
  2. 零 code files:无 .ts / .tsx / .js / .mjs / .cjs / .py / .sh
  3. 零 root artifacts:复用 Step 0.5 Root Artifact Guard(无根目录 .png / .pen / 媒体文件)
  4. mergeable + cleanmergeState == CLEAN + mergeable == MERGEABLE
  5. 非 hotfixscripts/check-hotfix-pattern.mjs 返回 hotfix=false
  6. PR title 模式匹配:title 含 verdict( 前缀(如 verdict(eval:a2a): 2026-06-06-...
  7. PR body 模式匹配:body 含字符串 Verdict published via cat_cafe_publish_verdict MCP tool —— 防止被滥用为通用 cat-merge 绕道
  8. 作者 ≠ merger:保留 cross-individual 原则(生成方猫 = 发起 publish 的 eval cat;merger = 任一非生成方猫)
  9. evidence-only label 必须 present(cloud R6 P2 — 锁住 policy 判断):PR 必须有 evidence-only label。computePublishPolicy 只对 keep_observe verdict 应用该 label;fix / build / delete_sunset verdict policy 返回 regular_pr(无 evidence-only label) → 必须走 regular merge-gate(owner action required)。关键:title 含 verdict( 前缀和 body 含 cat_cafe_publish_verdict 字符串只能证明 PR 是 publish-verdict 自动生成的,不能证明该 PR 不需要 owner actionevidence-only label 是 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)

决策标签(PR-3 publish-policy)

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"。

Future Phase 占位

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。

Reviewer 配对规则

动态匹配自运行时猫配置(repo 根 cat-template.json + .cat-cafe/cat-catalog.json overlay):

  1. 跨 family 优先 | 2. 必须有 peer-reviewer 角色 | 3. 必须 available
  2. 优先 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.tsENV_VARS 数组注册。 前端「环境 & 文件」页面自动展示,不注册 = operator看不到 = 不存在。

文档规范

  • docs/.md 文件必须有 YAML frontmatter(ADR-011)
  • 完成后必须同步真相源(详见 feat-lifecycle skill)
  • 归档查找:(internal reference removed)

开源社区 Issue 处理(F059)

开源仓 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

Hotfix Lane(Bug 快修通道)

社区报 bug 时,不必等全量 sync,直接走 hotfix lane:

  1. git worktree add -b fix/xxx ../cat-cafe-hotfix-xxx sync/LATEST-TAG
  2. 在 worktree 里修 bug
  3. cd ../cat-cafe-hotfix-xxx && bash scripts/sync-hotfix.sh fix/xxx <changed-files>
  4. 在 clowder-ai 上开 PR、review、merge
  5. Cherry-pick fix 回 cat-cafe main
  6. 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>
  7. intake-from-opensource.sh --advance-ledger

详见 Hotfix Lane 设计 (internal)

Full Sync Gate(Source-Owned)

全量同步到 clowder-ai 时,不能只看家里的 pnpm gate 绿不绿
source gate green != target/public gate green

硬规则:

  1. 先在 cat-cafe 导出同一份同步产物到 temp target
  2. 在 temp target 跑完整 public gate:pnpm checkpnpm lintbuildpnpm --filter @cat-cafe/api run test:public、startup acceptance
  3. 只有 temp target public gate 全绿,才允许碰真实 clowder-ai
  4. 本机 README/macOS smoke 不属于 full sync 主路径;它必须是 sync 完成后的独立步骤,且必须显式隔离端口/Redis

一句话:不要再把真实 clowder-ai 当第一轮验收场,更不能把 runtime 当验收靶子。

Release Provenance(三点映射)

公开 release 不要求 cat-cafeclowder-ai 同 SHA;我们要求的是可追溯映射

硬规则:

  1. release-intended full sync 必须从家里 source 侧显式传 --release-tag=vX.Y.Z
  2. sync-to-opensource.sh 在 temp target public gate 通过后,会自动打并 push clowder-vX.Y.Z-source
  3. .sync-provenance.json 必须记录:
    • source_commit_sha
    • release_tag
    • source_snapshot_tag
  4. 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 \
  --push
  1. publish-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-pr skill 引导(编号校验 + Feature Doc 对齐)

Issue Label 命名规范

开源仓 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