Omi 开源贡献指南:从 Product Fit 到 PR 合入的完整工程实践

📅 发布时间:2026/9/14 21:18:05
Omi 开源贡献指南:从 Product Fit 到 PR 合入的完整工程实践
Omi 开源贡献指南从 Product Fit 到 PR 合入的完整工程实践【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/FriendOmi 是一个AI 看你的屏幕、听你的对话并告诉你该做什么的开源可穿戴 AI 项目本仓库GitHub_Trending/fr/Friend包含了其 Flutter 移动端、Python 后端、桌面端、固件与插件生态的全部源码。本文以仓库根目录的 CONTRIBUTING.md 及其完整贡献指南 docs/doc/developer/Contribution.mdx 为骨架结合 AGENTS.md、Makefile、scripts/pr-preflight、scripts/failure-class 与 product/invariants 等源码级证据系统讲解如何向 Omi 提交高质量、可合入、可被维护者信任的 PR。读完本文你将掌握贡献前如何做 Product Fit 自查、如何引用产品不变式invariant、如何用make preflight与scripts/pr-preflight通过本地确定性检查、如何声明 Failure-Class、以及面向 AI Agent 的工程规范Definition of Done。第一步贡献前的 Product Fit 自查读 PRODUCT.md 与产品不变式注册表在写任何代码之前先确认你的想法与产品方向一致。贡献指南要求按顺序阅读PRODUCT.md定义产品北极星——记忆优先memory-first的闭环、跨表面共享的单一聊天心智one shared chat mind、信任优于机灵trust over cleverness、集成 harness、品味底线taste floor等原则。product/invariants产品不变式注册表其中locked状态的不变式例如跨 notch 与主聊天共享同一份 transcript即INV-CHAT-1是有约束力的——凡是改动其路径 globs 的 PR必须在 PR 描述中写出对应的不变式 ID。从注册表product/invariants/README.md可以看到完整索引INV-CHAT-1共享 transcript、INV-CHAT-2聊天启动位置与阅读位置、INV-MEM-1恰好三个产品记忆层级、INV-MEM-3canonical 选择后无遗留回退、INV-UI-1界面禁用紫色、INV-INT-1集成用 harness 而非启发式等。每个不变式文档如 product/invariants/chat-continuity.md、product/invariants/brand-ui.md都包含MUST NOT / Surfaces / Guard tests / Path globs / PR rule五个段落其中 Guard tests 会在每次 PR 上由 .github/scripts/check_product_invariants.py 持续校验而不是只在提升时校验一次。大型或模糊功能先从 Issue 开始如果功能大型或方向模糊应当先开一个 GitHub issue让维护者在投入主要实现工作之前对齐范围与方向。维护者若以方向或品味为由拒绝某个 PR会引用一个不变式 ID 或在同一周内提出一个新不变式提案——这样项目方向始终是书面化的而非靠口耳相传。四步贡献流程完整指南给出的贡献流程如下Fork 仓库点击仓库页面的 Fork 按钮。做出修改Clone 你的 fork创建分支实现你的改动。测试改动添加有重点的测试并在 PR 中写明你用来验证改动的命令或手动步骤。Push 之前先起草 PR 描述然后运行make preflight再运行scripts/pr-preflight --pr-body-file /path/to/draft-pr-body.md来校验不变式引用与必需的 failure-class 声明。起草描述之前可以先用scripts/pr-preflight --suggest拿到可直接粘贴的不变式段落与 failure-class 指引。这些基于 manifest 的检查在本地与 CI 中行为完全一致。创建 Pull Request提交 PR 并说明它关联的 issue命名你的改动影响到的产品不变式。本地确定性检查make preflight 与 scripts/pr-preflightmake preflightMakefile 中的preflight目标实际执行preflight: $(PYTHON_RUNNER) .github/scripts/pr_preflight.py --lane local --base origin/main也就是以--lane local本地通道基于origin/main运行前检脚本其选区selection包括已暂存、未暂存与未跟踪文件基于 commit 的检查需要在提交后再跑一次最终确认。新增的确定性 diff 作用域检查应当注册在 .github/checks-manifest.yaml永远不要直接写进 workflow YAML。scripts/pr-preflight 的完整用法scripts/pr-preflight 是一个薄壳脚本它解析仓库根目录兼容 linked worktree解析 Python 环境后转调 .github/scripts/pr_preflight.py。从源码pr_preflight.py可以看到其支持的全部参数参数作用--pr-body-file path从本地草稿文件读取 PR 描述未提交 PR 时必需--suggest输出可直接粘贴的产品不变式与 failure-class 指引退出码 0--metadata-only仅校验与 PR 元数据标题/描述/label相关的契约一次报告全部失败CI 对标题、描述、label 的编辑使用此模式--base/--head指定 diff 基准与头部默认origin/main/HEAD--lane local|ci本地或 CI 通道--repository/--pr-number通过 GitHub API 加载当前 PR 元数据须成对使用--event-payload-file仅在 GitHub API 瞬时失败时回退到触发事件快照--list只打印被选中的检查不实际运行PR 元数据的解析顺序pr_preflight.py优先--pr-body-file其次--repository/--pr-numberAPI失败可回退事件文件再次用gh从当前分支读取已有 PR 描述也可以通过环境变量OMI_PR_BODY_FILE指定描述文件。--metadata-only模式下元数据校验通过只代表 PR 描述合格不代表源码检查通过。--suggest模式的输出由两个部分组成check_product_invariants.py --changed-files ... --suggest输出的不变式引用块以及scripts/failure-class prepare --format json生成的 Failure-Class 声明补丁含 HTML 注释形式的候选列表。该命令刻意不根据路径或 diff 推断分类——分类决策始终由作者本人做出。PR 质量门槛什么才算好的 PR回归测试是硬要求Bug 修复必须包含能抓住该 bug 的回归测试。小型功能范围清晰可以直接提 PR测试核心路径与主错误路径并描述你做过的任何手动验证。展示你的验证在 PR 描述中列出你运行的命令以及它们展示了什么。它能编译不是证据——真正执行用户可见路径才算。测试必须是封闭的hermeticCI 中运行的测试必须封闭——不依赖线上服务、不联网。针对线上服务的验证可以当作额外证据但永远不能是 PR 生效的唯一证明。这一要求也写进了 AGENTS.md 的 Testing 一节。Backend Hermetic Merge Gate每个 PR 都要报告Backend Hermetic Merge Gate状态后端、lockfile 与 gate 工作流的改动会运行后端 E2E harness 加两套 emulator gauntlet其他改动则显式报告out-of-scope 通过而不是让一个必检项一直 pending。新 guard 要回答为什么不是共享原语在添加任何检查或 ratchet 之前PR 描述中必须回答为什么这不是一个共享原语shared primitive新 guard 必须引用它本可抓住的真实已合入 PR 或事故没有真实实例的检查不允许落地。产品不变式引用如果你改动了某个 locked 不变式列出的路径必须在 PR 描述中写出该不变式 ID例如INV-CHAT-1。这是基于路径而非基于意图的匹配——用scripts/pr-preflight --suggest可以发现所有匹配的 ID。整个为什么要有引用的机制在 product/invariants/README.md 有详细说明引用的持久价值不是吸引注意力而是上下文路由——检查失败时会打印匹配不变式的 Statement 与 MUST NOT 列表让规则直接呈现在正在编辑这些文件的人或 Agent面前。Failure-Class 协议让修复落在契约边界上修复的单位是被违反的契约Omi 的 bug 修复体系以failure class失败类别为工作单元——修复的对象不只是症状出现的代码行而是被违反的契约。声明就是一次普通实例修复的 PR 记录修复前先检查同一子系统近期的修复。分类规则AGENTS.mdfix:commit响应某个触发缺陷必须在 PR 描述中声明Failure-Class: FC-slug | new | none三选一。harden:commit加固某个边界或契约但没有触发事故可以引用某个类别但不需要声明。校验器validator是离线且必需的它的report命令是建议性的只识别可供维护者标记为dormant的类别。从 scripts/failure-class 的源码failure-class可以看到声明的三种合法形式它们必须分行书写不能用|连接Failure-Class: FC-lower-kebab-slug Failure-Class: new Failure-Class: none历史上常见错误是把旧模板的|当作值的一部分写成FC-my-slug | new校验器会针对这个具体错误给出提示。failure-class 命令族scripts/failure-class 转调同名 Python CLI定义存放在 .github/failure-classes每个 ID 一个 JSON 文件。子命令包括scripts/failure-class prepare --base origin/main --head HEAD --pr-body-file file返回一个非破坏性的 PR 描述补丁若 diff 中存在fix:commit 则提示需要声明可用--all-candidates列出全部定义否则只列出scope_hints与本次改动路径重叠的类别仅作展示收窄不是分类。scripts/failure-class explain FC-slug --format json返回单个类别的定义violated_contract、canonical_prevention、evidence_prs、status等字段。scripts/failure-class validate --pr-body-file file离线校验定义与声明的一致性检查fix:commit 必须有声明、new必须恰好新增一个合法定义、dormant类别必须显式 reopen 后才能用于新实例、实例修复 PR 不得修改注册表仅允许更新声明类别的canonical_prevention_artifact。scripts/failure-class report --since 14d [--events-file ...] [--now ...]基于本地事件 fixture 生成建议性的复发报告判定哪些类别进入静默期后可关闭状态绝不自动变更状态。类别生命周期dormant 与 reopen要标记某类别为 dormant需单独提交一个纯注册表 PR把status设为dormant并带上 UTC ISO-8601 的dormant_since时间戳。当report在该时间戳之后标记出复发时先合并另一个纯注册表的 reopen PRstatus: open并移除dormant_since再对实例修复进行分类。ID 使用稳定的语义化小写 kebab-slug如FC-malformed-doc-read可用scripts/failure-class prepare或explain查看精确字段与相关上下文。实例修复 PR 保持紧凑已有类别的声明替换掉根因 持久防护的长篇叙述只有声明new、改变类别的 canonical 预防原语或 owner、或做纯注册表生命周期转换时才需要扩展叙述。优先原语而非防护在检查/ratchet 之外还有一条相关准则见 AGENTS.md Bug Fixes 一节修复时先识别失败的所有权人、身份、状态转换或边界契约——不要在所有者的真正问题是所有权缺失时再加一个观察者、回退布尔或调用点异常。若两个以上近期修复共享同一原因在同一 PR 中增加可复用的防护面类型化状态/策略模型、行为契约测试、故障 harness 或窄静态检查器。回归测试必须通过可控接缝执行生产行为断言源码字符串顺序只是静态绊线static tripwire不是行为覆盖。面向 AI Agent 的贡献规范Omi 是agent-friendly的仓库AGENTS.md 是仓库所有 Agent 指令的单一事实来源CLAUDE.md只做薄指针其顶部声明了对 Claude Code、Codex 等所有 Agent 生效。Contributing with an AI agent 一节明确若使用 AI 编码 Agent它会自动读取仓库根目录的 AGENTS.md 以及各组件指南——backend/AGENTS.md、app/AGENTS.md、desktop/macos/AGENTS.md、web/app/AGENTS.md 等。其中的工程标准尤其是Definition of Done清单适用于你的每个 PR。Definition of Done每个 PR 都必须满足AGENTS.md 定义的八条 DoD行为改变 → 测试改变bug 修复包含能抓住该 bug 的回归测试新功能测试核心路径与主错误路径不多不少。组件测试套件通过在提交前本地运行backend/test.sh、app/test.sh 或组件文档中的等价命令。你亲自执行过改动跑过真实用户路径而不只是编译或 lint 通过实在做不到就明确说明不要暗示它有效。验证证据被写下来在 commit message 或 PR 描述中写明运行的命令与结果。无孤儿延期标记新增的TODO/FIXME/HACK要么引用跟踪 issue要么在合并前解决。文档随代码移动setup、测试命令、服务边界、env var 或 Agent 相关行为的改动须在同一 PR 中更新对应指南。Failure-class 声明起草fix:PR 描述前运行scripts/pr-preflight --suggest每个fix:commit 声明Failure-Class并用scripts/failure-class校验。打开 PR 前契约通过运行make preflight与 CI 执行同一份确定性检查 manifest.github/checks-manifest.yaml用scripts/pr-preflight --pr-body-file或--suggest校验。注意AGENTS.md 中关于维护者机器、直接合入main等规则不适用于 fork 式贡献——在 fork 中按你自己的流程落地改动即可。文档贡献文档贡献与代码贡献同等重要。仓库的文档位于docs/目录例如本文所依据的 docs/doc/developer/Contribution.mdx此外还有 docs/doc 下大量产品与开发文档并在文档站上实时同步。可以 Fork 仓库后直接点击编辑图标、预览并提交 PR。贡献奖励与付费赏金Omi 对获得批准的、有显著贡献的 PR 提供奖励以下规则均来自贡献指南原文具体领取方式以指南为准累计 PR 数奖励1 个 PR免费 DevKit 设备项链或眼镜视贡献领域而定2 个 PR$100 转写额度5 个 PR$500 转写额度 Discord 特殊 Contributor 角色10 个 PR与 Based Hardware 团队线下交流的机会显著贡献的判定标准时间投入投入 5 小时以上可累加多个小贡献、影响新功能或重大 bug 修复、质量清晰说明、有重点的测试与验证记录的优质代码。此外带有 Paid Bounty 标签的公开 issue 提供付费赏金规则包括代码必须合入 master 分支、赏金资格由项目方自行裁定、你合入第一个 PR 之后才能锁定某个 bounty 任务、领取时按指南要求提供 bounty 链接与收款账户。若当前没有可领取的付费赏金也可以在无 bounty 标签的 open issue 下评论建议添加。实战清单一次合规 PR 的完整路径综合以上全部机制一次可被维护者信任的贡献流程可以收敛为读 PRODUCT.md 与 product/invariants确认方向匹配大型/模糊功能先开 issue。Fork 仓库创建分支实现改动先运行make setup安装 Git hooks含自动格式化 pre-commit hook。写有重点的测试修复带回归测试并亲自执行用户可见路径。起草 PR 描述运行scripts/pr-preflight --suggest获取不变式引用块与 failure-class 指引。在 PR 描述中写入匹配的INV-*不变式 ID 与Failure-Class声明fix:提交必需。运行make preflight与scripts/pr-preflight --pr-body-file draft.md确认所有本地确定性检查通过其与 CI 共用同一份 .github/checks-manifest.yaml manifest。提交 PR在描述中列出验证命令与结果报告 Backend Hermetic Merge Gate 状态。这套从产品方向到 CI 检查、从人工规范到 Agent 自动化、从修复分类到奖励机制的完整闭环正是 Omi 能持续接收高质量外部贡献的制度基础——它把方向和质量都变成了仓库内可审计、可执行的书面契约。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考