开发者贡献地图与协议入口¶
给 LoopX 做贡献不只等于修改 Kernel,也不只等于开发 Extension。外部开发者可以改进协议规则、 Capability 与 Domain State、Provider、Host/Runner、Projection、Dashboard、文档、fixture 和 独立分发包。第一步不是挑目录,而是判断这次贡献要交付什么结果、由哪份合同拥有它。
阅读源码最容易走错的路径,是先打开最大的 Python 文件,再沿函数调用不断向下钻。这样能看见 实现,却很难判断一段行为为什么存在、改动后哪些消费者必须保持兼容。更可靠的入口是:
本章给出一张协议优先的源码地图。它不列完整 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. 状态与投影¶
这组协议回答:
事实存在哪里,谁可以写,读模型如何重建?
主要入口:
event_sourced_state_contract_v0: append-only event、replay、idempotency 与 privacy partition;active_state_structured_projection_v0: 从 active-state workbench 生成 typed、read-only projection;task_graph_projection_v0: 以只读图表达 Todo、Gate、dependency、validation 与 handoff;local_state_write_correctness_v0: revision、lock、idempotency key、conflict 与 durable write。
适合从这组协议开始的任务包括:
- status 与 event 显示不一致;
- active-state parser 丢失字段;
- task graph 缺少 lineage 或 truncation diagnostics;
- lifecycle writer 在 retry 后重复产生效果;
- dashboard 想增加一个新字段。
最后一个例子尤其重要。Dashboard 需求通常先回到“这个字段由哪个 source 拥有”,而不是直接给 UI 增加一份可编辑状态。
2. 工作图、权限与 Peer¶
这组协议回答:
当前谁可以做哪项工作,什么条件阻塞它,结束后由谁继续?
主要入口:
decision_scope_v0: Gate 的 kind、granularity、scope coverage 与 fail-closed 行为;goal_vision_replan_contract_v0: per-Agent Vision、checkpoint、replan 与 bounded route;peer_agent_runtime_v1: equal peer identity、claim、continuation 与协作边界。
适合从这组协议开始的任务包括:
- 某个 Gate 错误阻塞全部 Agent;
- claim 被当成 lock 或全局 authority;
- handoff 完成后没有 successor;
- monitor 与 advancement 的 precedence 错误;
- Host 有能力执行,但缺少所需 decision scope。
评审这类 PR 时,先问“authority 来自哪里”,再问“代码进入哪个分支”。文本里出现
approved、owner 或 waiting for user,都不能替代 typed scope relation。
3. Quota、Interaction 与调度¶
这组协议回答:
复杂状态如何被编译成这一轮的 user、agent 和 CLI 责任?
主要入口:
turn_envelope_v0: 在已完成的 quota decision 上提供 bounded next-action read model;protocol_action_packet_decision_v0: action packet 的决策语义;- Status Data Contract: status、attention 与 operator-facing 数据边界;
- State Machines: Todo、Gate、Quota、Evidence 和 Scheduler 如何组合。
这组协议的核心不是一个 should_run 布尔值,而是有优先级的最终合同:
一个用户 Gate 可以要求用户回答,同时 agent channel 仍要求执行不依赖该 Gate 的安全工作。把两个 channel 压成一个布尔值,会同时损坏交互和调度。
4. Bounded Turn 与 Host Effect¶
这组协议回答:
一轮外部执行如何被提议、执行、独立验证并写回?
主要入口:
loopx_turn_v0: experimental 的 decide、execute、validate、writeback 与 spend transaction;session_runtime_loopx_projection_v0: 外部 runtime 到 LoopX 的 read-only first-screen projection;session_runtime_controlled_writeback_v0: session runtime metadata controlled writeback 的 draft 边界;host_integration_surface_v0: Host lifecycle read、CLI-equivalent controlled write、能力声明和 fallback;rollback_packet_v0: 补偿、回滚与证据链。
这里要保持三个责任分离:
| 责任 | 所有者 | 不能替代 |
|---|---|---|
| 选择当前 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?
主要入口:
model_behavior_qualification_v0: 何时需要真实模型行为验证;release_outcome_baseline_v0: release 与 candidate 结果如何保持可比;- Testing and Quality: unit、contract、smoke、decision replay、canary 与 release gate;
- Public/Private Boundary: 哪些证据可以进入公开仓库。
这不是最后才补的“测试部分”。协议卡中的 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。
函数名是搜索锚点,不是课程目录¶
官方核心课程和源码会提供当前版本的搜索入口。使用它们时遵循三条规则:
- 先读协议和 decision table,再搜索当前 implementation anchor;
- 沿输入和输出确认它仍承担同一责任,不因名字相似就假定 owner;
- 在 PR 说明中引用 invariant 和 contract,函数名只用来帮助 reviewer 定位 diff。
例如,当前版本可以从 quota should-run 的 builder、Turn driver 或 task-graph builder 开始搜索。
这些名字未来可能移动到更合适的 bounded context;你的理解不应因此失效。
如果一篇文档需要列二十个函数才能解释行为,通常说明它在复制实现,而没有提炼协议。
选择一个公开贡献入口¶
外部开发者不应从本地 maintainer state 猜工作。公开入口是:
- 阅读
CONTRIBUTOR_TASKS.md; - 选择
Starter、Focused或已达成设计共识的任务; - 阅读任务涉及的协议和 validation;
- 在关联 Issue 中声明准备处理的最小切片;
- 等待 behavior-changing 或大范围任务获得 maintainer 反馈;
- 用干净分支完成一条可独立审阅、回滚的协议变更。
不要从这些内容创建公开任务:
.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 和所有测试。
缩小切片不是只减少行数,而是保持一条完整因果链:
不要只提交链条中间的 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 走完一条 真实协议链。