跳转至

开发者贡献地图与协议入口

给 LoopX 做贡献不只等于修改 Kernel,也不只等于开发 Extension。外部开发者可以改进协议规则、 Capability 与 Domain State、Provider、Host/Runner、Projection、Dashboard、文档、fixture 和 独立分发包。第一步不是挑目录,而是判断这次贡献要交付什么结果、由哪份合同拥有它。

阅读源码最容易走错的路径,是先打开最大的 Python 文件,再沿函数调用不断向下钻。这样能看见 实现,却很难判断一段行为为什么存在、改动后哪些消费者必须保持兼容。更可靠的入口是:

开发任务
  -> 贡献结果与 placement
  -> 所属协议族
  -> 协议拥有的不变量
  -> 对应 bounded context
  -> 当前实现与验证

本章给出一张协议优先的源码地图。它不列完整 API,也不要求你记住当前版本的函数名;目标是让你 在准备一个 Issue 或 PR 时,先说清自己正在改变哪份合同。

本章目标

读完后,你应该能:

  • 判断贡献属于 Control Plane、Capability、Provider、Host/Runner、Projection/Docs 还是 Extension;
  • 记录 capability id、provider id 与 built-in/extension-delivered placement;
  • 把协议级任务归入状态、工作图、Turn/Host 或证据恢复协议族;
  • 区分 canonical contract、read model、host adapter 与 renderer;
  • 根据 change reason 选择 bounded context,而不是根据文件名猜位置;
  • 从公开 Contributor Task、Issue 和协议文档形成可审阅的最小切片;
  • 用协议、不变量和验证描述改动,而不是提交一份函数清单。

先写一张协议卡

开始读代码前,先为问题写一张短卡:

Reader-visible problem:
Current protocol:
Source of truth:
Invariant at risk:
Allowed transition:
Forbidden outcome:
Expected receipt:
Validation surface:

例如,问题是“一个非阻塞用户提醒错误地满足了 publish 权限”:

Current protocol: decision_scope_v0
Source of truth: typed gate and todo requirements
Invariant at risk: a notice cannot grant authority
Allowed transition: matching approved gate consumes only covered scope
Forbidden outcome: unrelated or non-blocking notice unblocks publish
Expected receipt: linked decision and lifecycle event
Validation surface: decision table + quota integration smoke

这张卡比“准备修改 quota.py”更有信息量。文件可能移动,协议责任和错误结果却仍然可以被评审。

先选择贡献结果和放置位置

开始实现前,先回答四个 placement 问题:

Capability id:
Provider id:
Delivery: built-in | extension-delivered | standalone package
Why the nearest existing owner is or is not sufficient:

然后按调用者结果选择贡献面:

贡献面 它拥有的合同 典型交付 不能顺手拥有
Kernel / Control Plane 通用 Goal、Todo、Gate、quota、scheduler 与 lifecycle invariant typed transition、decision rule、recovery 修复 某个领域的全部业务状态
Capability / Domain State 调用者可依赖的 outcome、领域 policy 与结果生命周期 domain command、typed result、admission/read model Provider 凭据或通用控制面复制品
Provider / 外部系统 bounded request、外部调用、observation/effect readback built-in provider 或 extension-delivered implementation Goal authority、完成判断或 service auth 替代品
Host / Runner / Session Runtime typed execution、可见性、resume handle 与 host-owned effect Host adapter、runner、scheduler-owner integration LoopX canonical state 或自验证 completion
Projection / Dashboard / Docs / fixtures 面向读者的 read model、解释与 public-safe evidence CLI renderer、dashboard、协议文档、synthetic fixture browser write authority 或第二套状态机
Extension / package lifecycle 独立安装、启停、doctor、升级、回滚与兼容 standalone package 或 Capability Provider 的交付单元 Capability domain policy 或自动权限授予

这些贡献面可以组合,但不能混成一个模糊的 “plugin”。例如:

  • 新增稳定调用者结果:先定义 Capability 和 Domain State,再决定由 core provider 还是 Extension 实现;
  • 只替换外部服务实现:保留已有 Capability,新增 Provider,并选择 built-in 或 extension-delivered lifecycle;
  • 只增加一张操作看板:从 public-safe projection 读取,不解析项目私有文件,也不创建写路径;
  • 只改 Host continuation:复用 quota、scheduler 与 Turn contracts,不在 runner 内增加第二套 scheduler;
  • 交付一个零权限、确定性的独立命令:可以使用 standalone Extension,不必先创建虚假的 Capability。

新增目录、CLI option 或 schema 前,必须有真实 caller、active call site 或明确 compatibility contract。只有未来可能使用的 provider、runner 或 projection,先留在设计或 Todo 中,不要把 假设性结构提交到 production tree。

五个核心协议族

协议数量会随产品增长,但外部贡献者不需要从目录首字母开始逐个阅读。先按任务选择协议族。

1. 状态与投影

这组协议回答:

事实存在哪里,谁可以写,读模型如何重建?

主要入口:

适合从这组协议开始的任务包括:

  • status 与 event 显示不一致;
  • active-state parser 丢失字段;
  • task graph 缺少 lineage 或 truncation diagnostics;
  • lifecycle writer 在 retry 后重复产生效果;
  • dashboard 想增加一个新字段。

最后一个例子尤其重要。Dashboard 需求通常先回到“这个字段由哪个 source 拥有”,而不是直接给 UI 增加一份可编辑状态。

2. 工作图、权限与 Peer

这组协议回答:

当前谁可以做哪项工作,什么条件阻塞它,结束后由谁继续?

主要入口:

适合从这组协议开始的任务包括:

  • 某个 Gate 错误阻塞全部 Agent;
  • claim 被当成 lock 或全局 authority;
  • handoff 完成后没有 successor;
  • monitor 与 advancement 的 precedence 错误;
  • Host 有能力执行,但缺少所需 decision scope。

评审这类 PR 时,先问“authority 来自哪里”,再问“代码进入哪个分支”。文本里出现 approvedownerwaiting for user,都不能替代 typed scope relation。

3. Quota、Interaction 与调度

这组协议回答:

复杂状态如何被编译成这一轮的 user、agent 和 CLI 责任?

主要入口:

这组协议的核心不是一个 should_run 布尔值,而是有优先级的最终合同:

source facts
  -> normalized projections
  -> ordered policy
  -> interaction_contract
  -> scheduler_hint

一个用户 Gate 可以要求用户回答,同时 agent channel 仍要求执行不依赖该 Gate 的安全工作。把两个 channel 压成一个布尔值,会同时损坏交互和调度。

4. Bounded Turn 与 Host Effect

这组协议回答:

一轮外部执行如何被提议、执行、独立验证并写回?

主要入口:

这里要保持三个责任分离:

责任 所有者 不能替代
选择当前 action LoopX control plane Host 根据 prose 自行猜测
执行 bounded effect Host adapter LoopX 假装外部动作已发生
判断 postcondition 独立 validator Host 的自然语言自报成功

session_handle、raw stdout 和 transcript 可以帮助 Host 恢复,但不能成为 Goal authority 或 completion proof。

5. 证据、恢复与质量

这组合同回答:

如何证明一条规则正确,失败后如何恢复,并确保回执属于当前 revision?

主要入口:

这不是最后才补的“测试部分”。协议卡中的 forbidden outcome 和 expected receipt 会直接决定验证形态。

从协议族落到 bounded context

协议说明跨模块合同;bounded context 说明代码由哪个 change reason 拥有。当前核心地图可以压缩为:

Context 主要责任
goals Goal state、Vision、goal-level planning 与 frontier
todos Todo lifecycle、scope、resume、monitor 与 handoff summary
agents Agent identity、agent-scoped routing 与 capability
quota 把已投影事实编译成当前 interaction decision
scheduler cadence、backoff、reset 与 ACK
runtime Turn/session projection 与 bounded execution state
handoff 跨 runtime handoff、review packet 与 owner route
work_items attention、selection 与 operator-facing work read model

选择位置时问:

什么原因会让这段规则改变?

而不是:

哪个文件现在已经引用了相似字段?

例如:

  • “Gate 是否覆盖 action”属于 authority/todo contract;
  • “已仲裁结果如何显示给用户”属于 projection/renderer;
  • “多久再次唤醒”属于 scheduler;
  • “Host 如何应用一次 effect”属于 adapter;
  • “效果是否满足 acceptance”属于 validator。

一个 PR 可以跨多个 context,但每处修改都应服务同一条协议链。

从贡献面落到仓库 owner

当前仓库的稳定路由应理解为 owner,而不是看到目录名就自动放入:

目标 优先查找
通用控制面规则 loopx/control_plane/<bounded-context>/ 与对应 protocol/decision table
已有 Capability 的结果或领域状态 loopx/capabilities/<capability>/
Capability/Provider 注册与组合 loopx/capabilities/registry.py、catalog 与 manifest contract
Extension 通用 manifest、readiness、runtime loopx/extensions/
独立安装的 package packages/<package-id>/ 或独立 repository
Host/Runner 集成 runtime connector、Turn/Host contracts 与对应 adapter
操作投影 status/frontstage/projection owner;renderer 只消费 typed read model
文档与验证 owning protocol 文档、tests/examples/ 或 public-safe fixture

loopx/capabilities/<name>/ 中有代码不自动证明它是公开 Capability;需要显式注册和真实 caller contract。loopx/extensions/ 也不是“所有外部集成”的收纳箱:只有独立 provider lifecycle 才属于 这里。私有 helper 留在最近的 owner 中,不因为跨了几个文件就升级为新 Capability 或 Extension。

函数名是搜索锚点,不是课程目录

官方核心课程和源码会提供当前版本的搜索入口。使用它们时遵循三条规则:

  1. 先读协议和 decision table,再搜索当前 implementation anchor;
  2. 沿输入和输出确认它仍承担同一责任,不因名字相似就假定 owner;
  3. 在 PR 说明中引用 invariant 和 contract,函数名只用来帮助 reviewer 定位 diff。

例如,当前版本可以从 quota should-run 的 builder、Turn driver 或 task-graph builder 开始搜索。 这些名字未来可能移动到更合适的 bounded context;你的理解不应因此失效。

如果一篇文档需要列二十个函数才能解释行为,通常说明它在复制实现,而没有提炼协议。

选择一个公开贡献入口

外部开发者不应从本地 maintainer state 猜工作。公开入口是:

  1. 阅读 CONTRIBUTOR_TASKS.md
  2. 选择 StarterFocused 或已达成设计共识的任务;
  3. 阅读任务涉及的协议和 validation;
  4. 在关联 Issue 中声明准备处理的最小切片;
  5. 等待 behavior-changing 或大范围任务获得 maintainer 反馈;
  6. 用干净分支完成一条可独立审阅、回滚的协议变更。

不要从这些内容创建公开任务:

  • .loopx/.codex/goals/ 或 live active state;
  • private benchmark trace、raw agent session 或 verifier output;
  • 内部文档、生产凭据、本机路径;
  • maintainer-owned live run 的推测性复刻。

公开贡献需要从 public-safe protocol、Issue 和 fixture 建立上下文。

贡献不要求修改 runtime code。官方任务中也包括:

  • 协议、迁移说明与 contributor walkthrough;
  • deterministic decision table、negative test 与 public-safe replay fixture;
  • read-only dashboard、可访问性与 operator explanation;
  • fake-host、fake-provider 或 no-sink integration example;
  • Extension scaffold、manifest compatibility 与 lifecycle smoke。

无论交付类型是什么,都要说明它改变了哪个读者结果、由哪个 authority 保持事实,以及什么事件会 使文档、fixture 或 compatibility claim 过期。

判断改动是否过大

一个合适的贡献切片通常能用一句协议结果描述:

decision_scope_v0 在缺失 scope relation 时产生 typed repair,而不是把 Gate 当成全局阻塞。

以下描述往往过大:

重构 status、quota、scheduler 和所有测试。

缩小切片不是只减少行数,而是保持一条完整因果链:

source
  -> invariant
  -> decision
  -> projection or effect
  -> receipt
  -> validation

不要只提交链条中间的 helper,也不要为了“未来扩展”提前增加没有调用方的 enum、CLI flag 或 adapter。

本章检查表

准备进入源码前,确认你已经能回答:

  • [ ] 这个问题属于哪个协议族?
  • [ ] canonical source 和 primary writer 是谁?
  • [ ] 哪条 invariant 可能被破坏?
  • [ ] 合法与非法 transition 分别是什么?
  • [ ] 哪个 bounded context 对该 change reason 负责?
  • [ ] 哪个公开 fixture 或 smoke 能证明真实链路?
  • [ ] 任务是否已经公开、可认领且不属于 maintainer-owned live work?
  • [ ] PR 是否可以用一条完整协议结果描述?

下一章选择一个 scoped Gate 场景,沿 source、projection、decision、Turn、receipt 和 replay 走完一条 真实协议链。