Skip to main content
写清一个可观测的 runtime outcome 和验收标准,让 Orbi 能够实现、测试、审查并交付。 Orbi 用和它运行一样的方式开发:任务是 GitHub Issue,交付是 PR,仓库契约(AGENTS.md)同样适用于人类贡献者。

Issue 粒度

一个 Issue 是一个 runtime outcome,二选一形状: 修复(当 X,应该 Y,实际 Z)或 变更(当 X,用户应该能够 Y;今天不能,因为 Z): 一个可观测行为、一小批相关文件、含测试。标题应该能当测试名用。根因或期望 行为确定后再开 Issue——不要作为模糊愿望。
  • Issue 之间的依赖用 GitHub 原生 blockedBy 关系(gh issue edit N --add-blocked-by M);不要在 body 里写 Depends on #N——Runner 不 解析 body 依赖。
  • 多任务工作组织为 Epic(见工作流):Epic 负责协调, 子 Issue 负责交付。

最小实现(KISS/LEAN)

Orbi 只实现满足 Issue 验收标准的最小完整变更——KISS 和 LEAN 是 开发契约(AGENTS.md,Issue #118):
  • 不做 speculative feature、无收益抽象、额外框架层、fallback、未来功能 (future-proofing),不扩张验收标准之外的范围。
  • 如无必要勿增实体:每个新增文件、依赖、状态、label、命令和抽象都必须 对应 Issue 的一个验收条件。
  • 两个设计都满足需求时,选更简单的:概念更少、文件更少。
  • MVP 边界保持不变:无数据库、无队列、无 DAG、无 daemon、无风险模型、 无 fallback。

创建 Issue

通过创建 Issue 并加 ai-ready 标签来给 Orbi 派活(CLI 一步完成两 件事):
或手工:
好的 body 写清背景、期望行为、验收标准,(bug 时)复现步骤。调研型票 (「先调研,不要直接写实现」)改派为 ops 票——ai-ready + ai-ops-only:dev 票照办不提交会撞交付判据、被烧成 ai-blocked (见 workflow 页)。Orbi 在 改任何东西之前会读 Issue、仓库的 AGENTS.md、要改的文件及其调用方和 相关测试——README 和仓库其余部分只在任务确实相关时才读(Issue #180)。

面向用户的验收(User-centered acceptance)

每个新 Issue 使用同一组四个部分:User outcome(用户结果)、 Preconditions(前置条件)、Acceptance(验收) 和 Evidence(证据)。 写清用户执行的命令和配置、系统实际动作、用户看到的成功结果。必须同时 写 success path 和 failure path:说明用户看到的具体错误以及 repair action (修复动作)。单元测试只是局部证据,不能替代真实用户路径。 验收深度按影响面匹配:文档变更检查渲染后的文档页面/预览和链接,provider 变更做真实 provider/configuration 检查,concurrency 变更做竞争场景,setup 变更走 setup 入口,UI 变更走真实浏览器流程,纯内部 refactor 使用现有 public caller 和回归测试。证据记录在测试、 journal、Issue/PR 或 UI 中,不为形式上的 E2E 增加基础设施。

报告 bug

开一个带 bug 标签的 Issue,包含:
  • 失败的命令及其返回码 / stdout / stderr;
  • journal 现场(失败前后的 journalctl --user -u [email protected] -u [email protected], 或带 run id 的 run_failed 行);
  • Issue/PR 状态(标签)和进度评论里的 run id;
  • 环境:OS、Python 版本、Pi 版本、模型 endpoint 类型。
带 bug 标签的 ai-ready Issue 先于新 feature 被领取,带 p0 标签 的紧急 Issue 最先被领取(见工作流页),所以坏掉的交付循环——或生产 故障——最先被修。

贡献代码

  1. 读 AGENTS.md——它是开发契约(TDD、分层覆盖率门禁(Issue #234): 全仓库 line >= 95% 且 branch >= 95% 分别检查、变更 Python 代码与核心 路径 100% 行/分支覆盖、fail fast、无数据库/队列/daemon/fallback、 无业务任务 timeout)。
  2. 在 feature branch 上工作;从不直接 push 保护分支。
  3. 先写失败测试,再写最小实现,再重构。外部接口(CLI flag、HTTP path、配置字段)对照官方文档或一次真实调用断言——从不对照猜出来的 形状。
  4. 本地运行完整契约(精确命令见测试)。本地环境怎么搭是 贡献者自己的事——不是仓库契约,仓库不维护本地测试链(Issue #569)。
  5. 一个 Issue 一个 PR。PR 描述必须包含 Fixes #<issue-number>, merge 时 GitHub 原生关闭 Issue(完整契约:工作流, PR body 契约)。
  6. CI 必须绿(与本地同一契约)。Orbi 派发的任务由 Runner 执行独立 审查和合并;人类 PR 的 review 和 merge 走仓库正常的 GitHub 流程。

外部 PR(public 仓库)

Orbi 是 public 仓库:外部 Issue/PR 是主流程输入,不是边缘场景。 分支命名完全自由——整合责任在系统,不在贡献者(Issue #608)。 一个外部 PR 会被这样处理:
  1. CI 对每个 PR 运行,与维护者自己的分支同一契约。
  2. CI 红会为每个失败的 job 建一张 triage 票,票面必附 PR 链接。 外部 PR(任何不属于 Runner 内部 orbi/<owner>-<repo>-issue-<n> 交付命名的分支名)还会在票面被明确标注——Runner 和人类评审都不会 把它误当成内部重做。
  3. 交付循环认领该票后,先评审外部 PR——与 Runner 自有交付同一套 独立评审循环(review 发现直接在你的分支上修复,CI 全绿要求不变)。 评审结论是引擎的最后一步:结论(改了什么 / 风险 / 测试覆盖 / CI 状态)会发到 triage 票上,票停在 ai-blocked 等维护者处理。 引擎绝不合并外部 PR,也绝不为其挑选 milestone——是否接纳、 排入哪个版本由维护者裁定(Issue #842)。
  4. 只有被放弃、过期或不可修的 PR 才会被内部重做取代——取代时 PR 会话里会向贡献者说明取代关系。被贡献者撤回或被拒绝的外部 PR 会 自动把 triage 票放回就绪队列。维护者手动合并外部 PR 后,triage 票 作为已交付关闭。
评审与合并按维护者的节奏进行;除了一条之外不做任何时限承诺:外部 PR 在 open 期间绝不会被静默重做,triage 链路(带 PR 链接的票)始终是 状态可查的地方。单仓协作是当前模式——fork 工作流不在循环之内。

不要加什么

MVP 边界是刻意的:无数据库、无消息队列、无 daemon 循环、无 Web UI、 无任务 DAG、无风险模型、无 fallback 路径、无业务任务 timeout。想加 其中任何一项的提案,应先解释为什么某个真实、重复出现的失败需要它。