从聚焦验证到 Pull Request¶
一个 Control-Plane PR 的价值,不由测试数量决定,而由证据是否覆盖了被修改的协议链决定。 只跑一个巨大 smoke 可能找不到语义错误;只写一个 unit test 又可能漏掉 projection、scheduler 或 writeback 的跨层漂移。
从一个坏的结局开始¶
考虑另一个教学情境:一处 authority 写入规则改动通过了单元测试与静态检查,PR 描述因此写成“已验证”。但受影响的 PostgreSQL 路径尚未在隔离实例上运行,durability、事务隔离和并发冲突的证据仍然缺失。
同样,修改默认行为后,测试可能已经按新行为通过,而测试名和说明还在描述旧默认。通过的断言证明了它检查的内容,不能替代未运行的后端验证或未披露的合同变更。
这两个问题都要求把“执行了什么检查”与“结论适用于哪里”分开记录。
本章继续上一章的 Gate scope 修复,组织一份外部贡献者可以公开提交的证据包:
independent invariant
-> focused deterministic proof
-> real public path
-> risk-based cross-surface checks
-> public/private scan
-> reviewable commits and PR
目标并非模仿维护者的本地自动化,而是让 reviewer 能根据协议、不变量和回执判断这项改动。
为什么"跑完全部命令"不够¶
自然的反应是:那就把所有能跑的都跑一遍。这条路在 LoopX 上走不通,原因有三个。
全套验证跑不完。 PR 基线包含 lint、type、output budget smoke、分层的 pytest、canary 和
public/private scan;完整公开 smoke fleet 是另一回事。更慢的是真实路径:影响 PostgreSQL
authority 的改动需要一个一次性隔离实例,跑完整套件是分钟到十几分钟量级。每个 PR 都等最宽矩阵,
代价会摊到所有贡献者身上。
跑得多不等于覆盖对。 一百个命令如果都落在同一层,结论仍然只有一层。开头情境中的检查覆盖的是内存中的规则与静态约束,仍需补充受影响后端的证据。
有些结论需要人工判断。 自动检查可以提示默认行为变化是否有说明,但披露是否准确、证据是否覆盖真实影响,仍需要 review。
所以顺序应当是:先从风险推出需要哪些证据,再决定跑什么。
先建立证据矩阵¶
不要先运行仓库里所有命令。先把改动的风险列成矩阵:
| 风险 | 独立 Oracle | 最近验证 | 跨层验证 | 禁止结果 |
|---|---|---|---|---|
| Missing scope 被误授权 | decision_scope_v0 |
decision table | source-to-quota replay | protected action runs |
| Missing scope 被猜成 global | explicit global scope invariant | negative test | agent frontier smoke | unrelated work freezes |
| Repair 被低层 flag 覆盖 | final interaction contract authority | precedence test | scheduler replay | host runs stale action |
| Repair 重试重复写入 | write correctness contract | idempotency test | interrupted writeback smoke | duplicate event/spend |
| 新字段膨胀热路径 | output contract | shape/budget check | actual CLI diff | agent loses next action |
如果一项验证不能对应风险,它可能只是惯例,而非本 PR 的证据。
六层质量证据¶
Testing and Quality 定义了 LoopX 当前的质量分层。本书按外部贡献者的任务重新组织如下。
1. Unit 与 Contract¶
用于纯规则、schema、transition 和非法状态拒绝。
本案例应直接验证 decision table:
matching scope -> operator gate
unrelated scope -> independent frontier
notice only -> authority remains unmet
ambiguous scope -> typed repair
explicit global scope -> global gate
这层最适合证明具体 invariant,但不证明 CLI、projection 与 scheduler 已正确串联。
2. Focused deterministic smoke¶
通过已交付入口验证一条真实路径,例如:
Smoke 应薄而稳定。它保护已交付行为或历史回归,不应断言临时 builder 的每个字段,也不应包含 raw logs、真实项目状态或 dated research packet。
3. Public-safe decision replay¶
Replay 让 reviewer 看到:
然后用真实产品路径重新计算结果。
Replay 与 snapshot 不同。Snapshot 可能只是保存当前输出;Replay 的 expected outcome 必须来自 协议,而非被测代码。
4. Risk-based canary¶
Canary 根据 Git diff 选择最小的跨 surface 检查:
它适合捕获"scope policy 修好了,但 scheduler、output budget 或另一个 consumer 漂移"的问题。 Canary 不能替代聚焦回归,因为它不一定精确命名本次错误。
5. Full-public smoke fleet¶
完整公开 smoke 适合 main、每日或显式手动运行:
普通 PR 不应默认同步等待最宽矩阵。完整 fleet 的职责是广覆盖、inventory 与健康观察,无法替代 每个 PR 的语义设计。
6. Model behavior 与 Release qualification¶
只有确定性检查无法回答的问题才需要真实模型,例如:Agent 是否正确理解一份压缩后的默认 packet。
本章的 Gate precedence 是确定性规则,模型行为层通常是 not_applicable。让模型裁判 scope
coverage 既昂贵,又会弱化清晰合同。
Release qualification 还要绑定 exact commit、tree、version 与 clean state。普通贡献者 PR 可以提供代码级证据,但不能把它描述成 release 已通过或生产已生效。
先证明语义,再证明实现¶
验证顺序应保持:
Is the intended rule correct?
-> Does the pure implementation conform?
-> Does the shipped path preserve it?
-> Do adjacent surfaces remain compatible?
反过来的危险顺序是:
后一种方式只能做 characterization。若当前输出与协议矛盾,刷新 golden 会把 bug 固化成合同。
一个独立 Oracle 应包含什么¶
至少写清:
- source facts;
- authority owner;
- allowed outcome;
- forbidden outcome;
- 不相关变化;
- freshness/revision 条件。
对 Gate scope 修复:
Authority owner:
valid decision-scope relation and its lifecycle writer
Allowed:
typed repair before normal gated delivery
Forbidden:
approval, implicit global block, or hidden gate
Irrelevant mutations:
wording, unrelated agent gates, unrelated backlog size
Freshness:
decision is recomputed from current source revision
这份 Oracle 可以先由 reviewer 审查,再落成测试。
测试反例,而不只是 happy path¶
Control Plane 的 bug 常来自组合。为每条规则至少设计:
正例¶
它在合法条件下确实触发。
抑制例¶
存在更高优先级 owner 或安全 frontier 时,它不触发。
非法状态¶
缺字段、冲突、重复、过期 revision 时 fail closed 或进入 repair。
Metamorphic 例¶
改变无关输入,输出保持不变。例如:
都不能让 ambiguous Gate 变成授权。
Retry 与 interruption¶
在 prepare、host result、validation、writeback 或 spend 间中断,恢复后不能重复 effect 或记账。
这些维度比十份完整 JSON snapshot 更能保护协议。
测试替身必须服从真实合同¶
Fake Host、fake clock 或 in-memory store 可以降低测试成本,但不能创造新的产品语义。
检查 fake:
- 默认参数是否与真实 adapter 一致;
- observation、housekeeping 与 meaningful effect 是否分开;
- denied、timeout、non-zero 与 malformed result 是否保持不同分支;
- idempotency 与 proposal identity 是否被记录;
- 最终断言是否检查 receipt,而不只检查"调用发生过"。
例如,文件创建或清理可能只是 test setup,不应自动计为 material progress。只有协议明确标记的 effect 和独立验证后的 postcondition,才允许形成 delivery receipt。
如果 fake 与真实 contract 不一致,先修测试基础设施,再判断产品是否回归。
真实路径验证:代价最高的一层¶
前面五层都可以在本机几十秒内跑完。这一层不行,而它恰好覆盖最容易出错的地方。
为什么 fake 不足以证明 authority 写入¶
In-memory fake 可以验证状态规则及调用顺序,但无法单独证明真实后端的 durable write、事务隔离、schema 失败和跨进程竞争。需要在对应后端复现这些边界,才能把规则测试的结论扩展到实际存储路径。
LoopX 对这类改动的门是明确的:重构交付前必须验证受影响的生产入口和真实后端。影响 PostgreSQL
authority 时,配置指向隔离临时实例的 LOOPX_TEST_POSTGRES_URL,运行
npm run test:postgresql-authority-store,并记录精确 commit、后端版本、验证行为与失败或局限。
PostgreSQL Integration workflow 会在临时实例上运行同一条 ladder row 与 service admission
套件,所以这条路径在 CI 与本地都被验证。
隔离是这条门的前提¶
测试必须使用一次性数据库或 tenant、独立 runtime 目录,输入为合成 fixture 或经 owner 授权的 只读快照。禁止连接共享或生产库:集成测试会创建角色并注入 schema 级失败 trigger,这是它发现 问题的机制,也正是它不能对着真实数据跑的原因。
同样禁止为测试晋升正在运行的 goal、切换 provider,或修改其 registry、writer fence、Todo 与 lease。发现并发源变更时只报告,不擅自覆盖或恢复。私有快照和原始输出不进 Git,也不进公开 review。测试结束后停止临时数据库。
环境不可用时的正确动作¶
如果没有安全的隔离实例可用,正确结果是暂停交付并报告证据缺口,跳过这一层继续则失去意义。
通过的测试为它实际执行过的输入、实现路径和断言提供证据。被跳过的真实后端测试则没有验证该后端。单元测试全绿,不能补上未运行的数据库集成验证。
所以 PR 中应分别列出 passed、failed 与 skipped,并说明每层覆盖什么。成功退出、测试数量和绿色汇总都不能扩大证据的适用范围。
写进 PR 的诚实版本是:这一层需要什么环境、当前为什么不可用、哪些结论因此仍然未经验证、 以及谁可以解除这个阻塞。
选择本地验证命令¶
LoopX 官方贡献基线(见测试与质量指南)从
uv sync --extra test 开始,并在 checkout 内用所选解释器运行:
uv sync --extra test
uv run --extra test python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation
uv run --extra test python -m mypy
uv run --extra test python examples/control_plane/cli-output-budget-regression-smoke.py
uv run --extra test python -m pytest -q
git diff --check
若已有一个把当前 checkout 安装进去的显式环境,也可以在该环境里直接运行同样这组 python -m ...
命令;裸 python 可能指向另一个安装版本,先确认 sys.executable 与 loopx --version。
但开发阶段应从最聚焦的命令开始:
changed decision rule
-> related unit/contract test
-> one real-path focused smoke
-> affected output/compile/lint check
-> diff-selected canary
具体 smoke 名称由当前仓库、Issue 和 quality catalog 决定。本书不维护一份易漂移的命令全集。
文档与协议 PR¶
只改 public docs 时,通常至少需要:
协议文档若改变 shipped behavior,还应运行对应 contract/smoke;"只改 Markdown"不代表行为风险为零。
Python 规则 PR¶
至少考虑:
- touched modules 的 lint/type/compile;
- pure decision table;
- focused public smoke;
- CLI output budget(若热路径受影响);
loopx canary premerge --from-git-diff;- public/private scan。
Host、writeback 与 scheduler PR¶
额外覆盖:
- fake Host/clock;
- interrupted phase replay;
- no-effect/no-spend path;
- idempotency 与 revision conflict;
- scheduler ACK 与 reset identity;
- capability/authority denied。
不要用一个成功 happy path 给外部副作用背书。
默认行为变化必须披露¶
默认行为披露在下面的验证结果表里没有对应的命令可跑,也是 review 最容易漏掉的一类。
如果一个规则的默认行为发生了变化,下面三件事必须同时发生:
- 重命名或改写编码旧默认的 smoke,让名字描述新契约;
- 更新 docs 与 release note,写明变化前后的行为;
- 在 PR 描述里点名受影响的 lane。
漏掉第 1 条的症状最隐蔽:测试仍然是红的会被人发现,而名字在说谎的测试永远是绿的。断言 已经跟着实现改了,名字和 release note 却还停在旧契约上,于是仓库里同时存在两句关于同一行为的 真话,其中一句是过期的。
披露还有一层要求容易和它混在一起:"指导"与机器强制义务必须分开写。 一个 must_attempt_work
这类字段是机器会拒绝的状态,而一句"建议先检查"没有这种效力。把后者写成前者会让人以为系统会拦,把前者
写成建议会让 reviewer 以为可以商量。两者都要在合同里显式标注,不能靠散文推断。
这一类没有自动检查,是因为它要求的是关于"当前默认是什么"的判断,而这正是实现本身已经改变 的东西。任何断言都只能读到新值。所以它只能落在 reviewer 身上,这也是它必须写进 PR 描述的原因: reviewer 的输入是描述和 diff,他能发现的边界就是描述里提到的边界。
正确解释验证结果¶
验证并非 passed: true/false 两种状态:
| 结果 | 含义 | PR 中怎么写 |
|---|---|---|
pass |
当前检查满足 | 命令、scope 与结果 |
blocking_failure |
已违反 invariant | 不提交为 ready;修复或缩小范围 |
infra_failure |
环境未形成产品结论 | 记录 runner/provider 问题,不写"产品失败" |
manual_hold |
自动证据不足,需要 owner | 明确问题与所需决定 |
advisory |
风险信号,不构成当前阻断 | 说明为什么仍可继续 |
deferred_gap |
有价值但尚无覆盖 | 写 owner/successor,不伪装 covered |
not_applicable |
该层不适合本语义 | 给稳定理由 |
例如,真实模型服务不可用不能证明 Gate policy 错误;反过来,unit test 已通过也不能覆盖一个 确定性的 canary failure。
在 Git 中保持变更可审阅¶
开始非 trivial 贡献前:
- 从最新默认分支创建干净分支或 worktree;
- 确认工作树没有混入其他任务;
- 只修改完成同一协议结果所需的文件;
- 在 staging 前重新分类所有路径;
- 通过明确 pathspec 暂存,不使用宽泛的
git add .。
推荐先检查:
git status --short --branch
git diff --stat
git diff --name-only
git ls-files --others --exclude-standard
这不属于 Git 形式主义。LoopX 仓库同时可能存在源码、公开 fixture、本地 runtime state 与生成证据, 必须在提交前区分。
提交前的路径分类¶
把每个变化路径归入:
| 类别 | 示例 | 处理 |
|---|---|---|
| Product code | protocol policy、writer、projection | 若属于本 PR,提交 |
| Public docs | protocol、contributor guide | 若解释当前行为,提交 |
| Durable validation | contract test、public-safe smoke | 若保护本规则,提交 |
| Local/private state | .loopx/、.loopx/goals/、live state |
不提交 |
| Generated/raw evidence | logs、transcript、verifier tail | 不提交 |
| Unrelated artifact | 其他实验或格式化 | 留在 PR 外 |
在 staging 前扫描候选路径是否包含:
- credential、token 或 secret;
- 本机绝对路径;
- private Issue、文档或内部链接;
- raw benchmark task、trajectory 或 verifier output;
- active Goal/Todo 的真实本地内容;
- 自动生成的大型日志与截图。
公开 fixture 只保留重现状态机所需的最小合成事实。
如何拆 commit¶
按 reviewer 的判断任务拆分,而非按文件类型机械拆分。
一个小型规则修复可以是单个 cohesive commit:
repair ambiguous decision-scope routing
- policy correction
- focused contract and replay
- protocol clarification only if needed
如果包含行为保持的 mechanical move,通常先单独提交 characterization/move,再提交规则改变:
commit 1: characterize existing protocol behavior
commit 2: move cohesive rule family without behavior change
commit 3: change rule and add negative/replay evidence
不要把 formatter、无关 rename、另一个 Extension 和本次 Gate 修复混在同一提交。
Commit message 应说明结果,例如:
而较差的一种是:
每个 commit 都要有 DCO sign-off¶
PR 分支上的每个 commit 都必须带一行 trailer:
用 git commit -s 生成。漏掉时用 git commit --amend -s,多个 commit 则用 interactive rebase
补齐后更新分支;Sign-off 检查会拒绝未签名的 commit,merge-gate 与它共同构成 required check。
手工 merge commit 与网页端编辑同样需要签名,因为检查只豁免可验证的 GitHub 双父合并提交。
这条要求与测试无关,却和它同级:它认证的是"这个提交由谁做出、以什么许可提交"。一个通过了
全部验证但没有签名的分支,仍然进不了 main。
PR 描述应是一份协议证据包¶
一份高质量 PR 可以按以下结构:
Problem¶
描述 reader-visible 或 state-machine failure,不从文件名开始。
Protocol and invariant¶
说明由哪份合同拥有语义,哪些结果必须允许或禁止。
Change¶
说明 source、projection、decision、effect 或 writeback 中哪一层改变;明确未改变什么。
Validation¶
按风险列出:
- unit/contract;
- focused smoke/replay;
- output/boundary;
- canary;
- 未运行或 not applicable 的层及原因。
Compatibility and recovery¶
说明 public field、migration、retry、rollback、manual hold 或 release 影响。默认行为变化在此点名 受影响的 lane,并链接被重命名的 smoke。
Public boundary¶
确认没有本地状态、私有证据、凭据、raw session 与本机路径。
Reviewer 应能从这份描述回答:
What contract changed?
Why is the new decision correct?
Which consumers were checked?
What remains owner-held?
关联 Issue 与公开任务¶
非 trivial 工作优先关联 Contributor Task Board 或 GitHub Issue:
- 在开始大改前声明准备处理的 slice;
- 保持 scope 接近已认领任务;
- 需要改变 public schema、scoring、permission、release 或 production behavior 时先获得设计/owner 反馈;
- 卡住时公开具体 blocker 与已尝试验证;
- 不复制
Maintainer-ownedlive run。
Issue 是公开协作边界,不能把本地 Goal state 整体粘贴上去。
哪些 PR 必须停下来等待¶
出现以下情况时,不应仅靠多跑测试继续:
- public JSON/schema 字段需要删除或改名;
- canonical state storage 或 migration 要改变;
- permission、production effect 或 credential boundary 要改变;
- benchmark scoring、task semantics、submission 或 leaderboard 行为要改变;
- 默认 agent-facing packet 的 authority 字段要移除;
- 需要 private source 或 maintainer-owned live evidence;
- 结果必须由 release/merge owner 决定;
- first screen、hero 或主要 CTA 需要 owner presentation review。
这些是 decision gate,并非测试缺口。验证无法替用户或 maintainer 授权。
Review feedback 也是协议校验¶
收到 review 后,不要机械修改每条建议。先判断:
- Reviewer 指出的是 invariant、实现、可读性还是 scope 问题?
- 建议是否与当前协议和证据一致?
- 修改会不会影响其他 consumer、migration 或 validation?
- 是否需要补反例,而不只是改代码?
- PR 描述和文档是否也要重组?
如果 review 暴露协议歧义,先达成语义共识;不要让两个相互矛盾的 test 同时"通过"。
review 要执行,不只是阅读¶
上面的判断有一条执行层面的要求。对行为承载的改动,review 不能从标题推断等价性:reviewer 要 在不可变 baseline 上列出旧调用方的合法与非法分支,再用同一批合成输入、经同一 public entrypoint 在精确 head 上对照,覆盖成功与拒绝路径、诊断与修复提示、参数被省略或被清空的情形、持久化回读、 ownership 与 receipt。共享同一套新规则的多个 provider 互相一致,构不成前后兼容证据。
还要证明敏感性:聚焦用例必须在历史缺陷或人为 mutation 上失败、在修复后通过。缺少对照证据时, 不能批准一个以"行为不变"为由的改动。这里的证据必须可执行:baseline、精确 head 与敏感性用例各自 记录可重放命令或脚本调用、真实受影响后端、不可变 fixture 指纹、退出状态与归一化观测指纹。
需要说明的是,这条要求在实现上被投影成 review packet 里的一项检查,而 packet 测试只证明要求 被投影,并不证明 reviewer 真的执行了它,更不证明产品无缺陷。这正是它为什么必须和"默认行为 披露"归为同一类:这类义务的最后一个执行者是 review,绝非 CI。
两个真实社区贡献案例¶
本节与英文对应章节保持语义镜像;案例事实、结论、链接目标或风险边界的实质差异属于文档缺陷。
案例一:把一个 CLI 不一致修成完整小 PR¶
PR #3540
来自一次真实 first-run/deep-use 观察:loopx --format json doctor 可以工作,但更符合用户直觉的
loopx doctor --format json 当时会在 argparse 阶段失败(该写法在今天已经可用)。贡献者没有新建第二套 renderer,而是复用
现有 subcommand format contract。
最终改动只涉及 parser wiring、doctor handler 与一条端到端 CLI regression。验证同时覆盖:
- 新的子命令参数位置;
- 旧的全局参数位置;
- 二者同时出现时的 precedence;
- 非法格式在执行诊断前 fail closed。
这个案例的价值不在"只改了几行",而在于它形成了完整链条:
小 PR 不等于低标准。它只是把同一个用户结果控制在更容易验证和回滚的范围内。
案例二:用反例评审高风险状态写入¶
PR #3529
把 shared-goal coordination 的 aggregate head、file provider 和 claim_work executor 做成一个
provider-neutral Stage 2 切片。第一版已有大量正向测试,但 reviewer 仍构造了更强的非法状态:
partial write 被误报为 applied、损坏 receipt 导致未分类异常、超大 TTL 越过 typed boundary、
Windows 无法导入锁实现,以及无时区时间和 bool-as-int 进入持久状态。
作者没有给这些输入逐个加字符串特判,而是修复它们共同指向的 trust boundary:
- durable write 必须 write-all、fsync、atomic replace,并在不确定时返回
ambiguous; - persisted receipt、timestamp 与 generation 在进入 executor 前完成 typed validation;
- lock 复用仓库已有跨平台 owner;
- RFC、负例测试和 CI 同步记录 machine-enforced obligation。
这个案例说明,review 并非在代码完成后"挑风格"。高价值 review 会提出一个能击穿当前 invariant
的具体 counterexample,并要求修复落在真正的 owner;作者则用新的负例证明同类非法状态不能再次
进入 semantic core。最终 APPROVE 只适用于重新验证后的 exact head。
Merge 后还要验证什么¶
PR 合并不自动证明部署、release 或所有外部 Host 已更新。根据改动类型,后续可能需要:
- main 上的 full-public smoke;
- release qualification;
- packaged install check;
- Host/plugin compatibility;
- documentation site deployment;
- fresh external readback。
在 PR 或发布说明中区分:
不能把前一状态写成后一状态。
代价与边界:这套方法放弃了什么¶
代价一:最贵的那层最慢,而且无法缓存判断。 单元测试给你秒级反馈,隔离实例上的真实后端 测试给你分钟级反馈,后者才是 authority 写入行为的唯一证据。想在开发循环里保持速度,唯一办法 是接受"本地绿"只是中间状态,算不上结论。
代价二:一个测试同时服务两个目标时会失守。 smoke 既要断言行为、又要在名字里说明行为, 默认行为一变,两件事就分开了。代价是每次默认变更都要动到测试名、docs 与 release note,而 这些改动没有编译错误提醒你漏了哪一处。
代价三:证据必须公开安全,这限制了 fixture 的形状。 最有说服力的证据往往是真实运行状态, 而它不能进 Git。合成 fixture 更弱,但它可以被 reviewer 独立复现,这是它被接受的原因。
边界一:完整套件属于 main、每日与手动通道,不属于每个 PR。 这对贡献者是好消息,也意味着
PR 上没见过的最宽矩阵,确实可能在你合并之后才第一次运行。你的选择无关"要不要跑全套",而在于
"有没有点名本改动最高风险的那一层"。
边界二:not_applicable 是一种有效回答,前提是给出理由。 本章的 Gate precedence 是确定性
规则,模型行为层就是 not_applicable。把每一层都跑一遍并不会让结论更强,只会让 PR 更慢。
边界三:release、deploy 与 observed 是三种状态。 合并、发布、部署到目标环境、在目标环境 被观察到,每一步都需要自己的证据。普通贡献者 PR 能提供代码级证据,不能声称生产已生效。
边界四:这一章不替你认领任务。 哪些 slice 可以被外部贡献者拿走,由 Contributor Task Board 和 Issue 决定;需要 private source、maintainer-owned live evidence 或 presentation review 的 改动,验证再多也仍然需要 owner 的决定。
本章检查表¶
打开 PR 前,确认:
- [ ] 每个风险都有独立 Oracle 和禁止结果;
- [ ] Unit、focused smoke、replay、canary 等层按风险选择,数量本身无意义;
- [ ] Characterization 没有被当成 correctness authority;
- [ ] Fake、fixture 与 snapshot 没有发明产品语义;
- [ ] 真实路径(如 PostgreSQL 集成)已在隔离实例上运行,或已把缺口写成阻塞项;
- [ ] 默认行为变化已重命名 smoke、更新 docs/release note,并在 PR 中点名受影响 lane;
- [ ] 每个 commit 都带
Signed-off-bytrailer; - [ ] 验证失败被正确分类,没有把 infra failure 写成产品结论;
- [ ] 所有变化路径已分类并通过显式 pathspec 暂存;
- [ ]
.loopx/、.loopx/goals/、live state、凭据、私有链接、raw logs 和本机路径未提交; - [ ] Commit 与 PR 都以协议结果组织,不以函数列表组织;
- [ ] Compatibility、recovery、未验证项和 owner gate 已明确;
- [ ] PR 关联公开 Issue/任务,且未复制 maintainer-owned work;
- [ ] "merged、released、deployed、observed" 没有混为一谈。
需要为不同风险 surface 选择 deterministic test、decision replay、canary、模型行为验证或 release gate 时,继续阅读 Control-Plane Course 第 10 讲。 课程提供组合风险 case;本章保留从本地证据到公开 PR 的交付主线。
至此,你完成了开发者贡献中的一条 Control-Plane 路径:从贡献地图选择 owner,沿协议链定位 实现,修改一条规则,再以独立证据交付 PR。Capability、Provider、Host/Runner、 Projection/Docs/fixtures 与 Extension 等贡献面会有不同的最近验证,但复用同一原则:先确认 协议与权限 owner,再让证据覆盖真实交付边界。
你不需要记住 LoopX 当前所有函数;你需要能说明事实从哪里来、谁有权改变、哪条不变量保护 决策,以及什么回执足以让下一轮继续。若贡献需要独立版本、可选安装或独立生命周期,再进入 Extension 的放置决策,不要把每项贡献都包装成 Extension。
不变式¶
读完这一章,你应该能带走五句可以自己检查的话。
- 每一项验证都要对应一个具名风险。 对应不上的命令属于惯例,构不成本 PR 的证据。
- 期望值先于实现。 从当前输出反推的断言只能做 characterization,不能作为 correctness authority。
- 跳过不等于通过。 拿不到隔离环境时,正确动作是报告证据缺口并暂停交付。
- 默认行为变化有三件必做:重命名 smoke、更新 docs/release note、点名受影响 lane。 漏掉第一件的测试仍然是绿的,这正是它危险的原因。
- merged、released、deployed、observed 是四种状态。 不能用前一种的证据宣称后一种。
这五条回答的是同一个问题:当"我本地跑过了"既是贡献者最有力的说法、也是最容易误导别人的 说法时,reviewer 凭什么判断这项改动真的被证明过了?