机器协议
本页面向 adapter 和 integration author。普通用户应调用生成的宿主能力,并参考命令说明。
当前 JSON contract version 为 2:
- machine-protocol.schema.json 定义公开命令、Action、Outcome、status、error 与 recovery 的形状。
- source-envelope.schema.json 定义 GitHub source transport 形状。
可运行的完整宿主交互见机器协议 v2 教程。
Schema 定义 serialization shape。Runtime 还会验证 JSON Schema 无法完整表达的规则:embedded manifest syntax、ordering、hash、cross-field identity、idempotency、workspace state 与 filesystem safety。集成应验证 schema 并保留 CLI error,不要根据本文重新实现 Go validator。
宿主调用模型、读取仓库、运行工具,并在用户要求时使用 GitHub 凭据。在这套协议交互中,Run/source 路径是本地确定性程序:验证消息、记录 Run、观察 Git 并返回下一操作,不调用模型或访问 GitHub。独立的公开 doctor 命令可能调用用户本机的 gh 做只读诊断。
宿主通常在每一步使用 JSON:
slipway run --budget N --json --root ROOT [--no-review] --goal-file GOAL_FILE [--source-file SOURCE_FILE]slipway protocol submit --run RUN --action ACTION --root ROOT (--outcome-file FILE | --outcome-stdin)slipway protocol answer --run RUN --action ACTION --root ROOT --text-file TEXT_FILEslipway protocol answer --run RUN --action ACTION --root ROOT --confirm-destructive --scope-sha256 DIGEST [--text-file TEXT_FILE]slipway protocol skip --run RUN --action ACTION --root ROOTslipway protocol resume RUN --root ROOT [--budget N]slipway protocol resume RUN --root ROOT (--source-file FILE | --use-pinned-source | --source-choice pinned|adopt --candidate CANDIDATE) [--budget N]slipway protocol material --run RUN --action ACTION --root ROOT --section KEY协议操作是版本化宿主接口。它们有文档且在 help 中可见,但不是另一套 end-user command sequence:应通过 CLI 返回的结构化 next variant 来驱动。
启动 Run
Section titled “启动 Run”Canonical host invocation 不把 exact goal 放入 argv。宿主将其写入私密临时 regular non-symlink file,并解析 start variant 返回的 required goal_file path:
slipway run --budget 8 --json --root /absolute/worktree \ --goal-file /private/temp/goal.txtAd-hoc Run 省略 source field。Issue-backed Run 另行提供私密临时 --source-file。CLI 消费后,宿主删除两个临时文件;Run 此后不依赖这些文件或 GitHub。Human caller 仍可使用一个 positional goal 或 --goal-stdin,但 generated adapter 使用 goal_file,避免 process list/command trace 泄露和平台 command-line length 限制。
Start response 包含 Run state、初始 orient Action 与结构化 next operation。
Action
Section titled “Action”Active Run 包含一个非 null Action:
{ "contract_version": 2, "run_id": "...", "action_id": "...", "kind": "orient", "goal": "...", "brief": "...", "context": "...", "remaining_budget": 7}kind 只能是 orient、clarify、implement、review 或 summarize。
Issue-backed Action 还包含:
- source、manifest 与 requirements revision;
- 有序且范围明确的 section catalog;
- 结构化
protocol materialreader; - 当前 Action 需要的 section key。
Requirements Markdown 不会复制进 context。Material reader 只对 current non-void Action 有效,并在返回内容前验证 digest、byte count 和 section revision。
这些 key 的版本化字段是 requirements.required_for_action。在 protocol v2 中,它等于 requirements.sections 中全部 key 的有序列表;宿主必须保持这种精确相等,不能自行推断更小的子集。
Reader 的 base_argv 才是权威调用形式,并被固定为九个元素的精确序列,以 slipway protocol material --root ROOT --run RUN --action ACTION 开头。请把 section flag 作为独立 argv 元素追加,不要按上文 synopsis 的顺序重排——那里采用的是便于人阅读的 flag 顺序。
Destructive confirmation 授权后重新下发的 Implement Action 会携带第三种可变字段 destructive_authorization。其他任何 Action 都不含此字段,因此不要把上面两种形态当作穷尽集合,也不要仅凭 kind 建模:
| 字段 | 含义 |
|---|---|
request_id |
此授权所回应的 destructive_request 的 UUID。 |
originating_action_id |
发起该请求的 Implement Action。 |
scope_version |
在 contract v2 中恒为 1。 |
scope_sha256 |
规范 scope 的 sha256:<64 hex>。 |
targets |
精确且非空的 target 列表;每项为 path、git_ref、external_resource 或 data_domain。 |
impact |
声明的后果文本。 |
confirmed_at |
确认时刻的 RFC 3339 UTC 时间。 |
Slipway 在每次加载时都会由 request_id、targets 和 impact 重算 scope_sha256,不匹配即拒绝该 Action。授权仅覆盖该 scope,不会更宽。
context 是 active answer 与之前 Outcome summary 的范围明确 projection,不是完整 journal、source、conversation 或 hidden model reasoning。
Outcome
Section titled “Outcome”必须从且仅从一种输入提交 Outcome:
slipway protocol submit --run RUN --action ACTION --root ROOT --outcome-file FILEslipway protocol submit --run RUN --action ACTION --root ROOT --outcome-stdin所有 public Outcome field 都必须存在。空集合仍发送 array;不适用 object branch 使用 JSON null:
{ "contract_version": 2, "action_id": "...", "action_kind": "orient", "status": "completed", "summary": "observed facts", "observations": [], "known_issues": [], "suggested_actions": [], "pause": null, "implementation": null, "review": null}action_kind 必须匹配 outstanding Action。Host status 为 completed、needs_input、partial 或 error;skip 是 CLI operation,不是 Outcome status。
- Orient 或 Clarify 最多建议一个
clarify、implement或summarizeAction。建议只是参考而非预约:当 review 已启用且 Slipway 已观察到代码变更时,会先插入 Review,再处理该建议。 - 非暂停 Implement 使用
implementationbranch,并报告实际文件、attempt、uncertainty 以及 test/type-check/build/lint activity 与 exit code。 - 非暂停 Review 使用
reviewbranch 并报告 finding,不建议 repair work。 - Summary 和所有
needs_inputOutcome 都没有 suggested Action。
合法 Outcome 组合
Section titled “合法 Outcome 组合”| Action | Host status | 必需 result branch | 允许的 pause | 允许的 suggestion |
|---|---|---|---|---|
| Orient | completed / partial / error |
implementation=null、review=null |
无 | 零或一个 Clarify、Implement 或 Summarize |
| Orient | needs_input |
implementation=null、review=null |
decision 或 environment | 无 |
| Clarify | completed / error |
implementation=null、review=null |
无 | 零或一个 Clarify、Implement 或 Summarize |
| Clarify | needs_input |
implementation=null、review=null |
decision 或 environment | 无 |
| Implement | completed |
implementation.result=applied|not_needed、review=null |
无 | 无 |
| Implement | partial |
implementation.result=partial、review=null |
无 | 无 |
| Implement | error |
implementation.result=unable、review=null |
无 | 无 |
| Implement | needs_input |
implementation=null、review=null |
decision、destructive 或 environment | 无 |
| Review | completed |
review.result=no_findings_reported|findings_reported、implementation=null |
无 | 无 |
| Review | partial |
review.result=inconclusive、implementation=null |
无 | 无 |
| Review | error |
review.result=error、implementation=null |
无 | 无 |
| Summarize | completed / error |
implementation=null、review=null |
无 | 无 |
Clarify 有意不允许 partial:一个 Action 只承载一个决定。Review 不能使用 needs_input,也不能建议任何 Action;not_run 只属于 CLI 生成的 Review-skip projection。
needs_input Outcome 只有三种 pause reason:decision_required、destructive_confirmation_required、environment_unavailable。budget_exhausted 只能由 CLI 产生。
Pause 还可以携带可选的 supersedes_answer_action_id,指明其答复被本次 pause 取代的那个较早的 Clarify Action。它只有与 reason: "decision_required" 同时出现才合法。
Destructive confirmation 只对精确 current Implement request 和 scope digest 有效。yes 等自然语言只是 feedback,不是授权。Action 变化、resume、scope 扩大或 mismatch 都会使 grant 失效。
Outcome input 上限 1 MiB,必须是有效 UTF-8,不能含 BOM、duplicate/unknown field 或 trailing data。
结构化 next
Section titled “结构化 next”每个可以继续的 success 或 error 都包含 typed next object:
operation:action、answer、resume、start、command或none;- 初始
workspace_identity; - 零个或多个带
id、base_argv和 typed input 的 variant。
Input type 为 string、path、enum 或 digest。Consumer 选择一个 variant,按 schema 顺序将输入值作为独立 argv element 插入;不得解析或拼接 display command。
Start variant 通过 required goal_file path input 携带 exact goal,不把 goal text 嵌入 base_argv。Decision/feedback variant 同样使用 required text_file path;destructive confirmation note 使用 optional text_file。宿主创建私密临时 regular file,解析 typed variant,并在消费后删除文件。Direct --text 与 stdin mode 仍是 human-facing convenience,不是 generated machine canonical path。
只有所有 required input 已解决的 variant 才能渲染为人类 shell command。POSIX、cmd.exe 和 PowerShell rendering 只用于显示;structured argv 才是 machine value。
当 Windows display command 含有 cmd.exe 无法安全保真的 expansion-sensitive % 或 ! 值时,renderer 使用 PowerShell UTF-16LE EncodedCommand trampoline。这只改变可复制的显示形式;解码后的 process argv 必须与结构化 variant 逐字节等价。
Ended Run 使用 operation: "none" 和空 variant list。
Source envelope
Section titled “Source envelope”Source envelope 上限 16 MiB,通过 repository/Issue node ID 标识一个 github.com Issue。Valid Change 满足:
- body 第一个非空行为
<!-- slipway-level: change/v2 -->; - 下一个非空 block 是唯一严格
slipway-manifestJSON fence; - ordered manifest 有 5–64 个 section entry,并包含 outcome、requirements、acceptance examples、constraints、non-goals role;
- envelope 只且完整包含被引用 comments;
- 每个 comment 以精确 section marker 开头,并匹配声明 digest。
Normalized section 最大 256 KiB,完整 section payload 最大 4 MiB,manifest 最大 256 KiB。缺失、额外、重复、minimized、edited、oversized 或 hash-mismatched reference 会被拒绝。
Top-level source schema 有意允许 invalid refreshed head 使用空或仅含空白的 Issue/comment body,以及空 comments array。这样,缺失 marker、空 referenced section 与 digest mismatch 都可由 CLI 分类,而不是由宿主先拒绝 envelope 或收集无关讨论。Embedded manifest string 与 semantic digest check 由 runtime 验证,不由 top-level schema 单独完成。
CLI 保存稳定 identity、provenance、byte count、revision 和 content-addressed accepted material;不把 raw envelope、title label、source-file path 或 unreferenced comment 写入 journal。
Refresh 与 candidate
Section titled “Refresh 与 candidate”Issue-backed resume 必须明确执行以下一种操作:
- 导入并比较 fresh envelope;
- 继续 pinned snapshot;
- 对精确 current candidate 选择 keep pinned 或 adopt valid candidate。
省略 source option 既不表示“unchanged”,也不会触发隐式网络访问。Issue identity 不同或 amendment parent requirements revision 不同会在不修改 Run 的情况下被拒绝。Candidate ID 与 choice 支持 stale-safe idempotency。
版本化 schema 是封闭的 source_candidate.classification_code、resume_operation 枚举以及 valid/invalid candidate 字段组合的序列化权威。对于 invalid candidate,observation_sha256 是对精确被拒 source observation 进行 domain separation 后的 digest,用于确定性比较;它只是 provenance,不是已接受 Requirements,也不能证明宿主确实从 GitHub 获取了内容。
成功 resume 会按需 void stale outstanding work、重新验证 workspace,并通常返回 fresh Orient。省略 --budget 时保留大于零的 remaining budget,若为零则补充到 max(initial_budget, 3);明确传入 --budget N 会替换为 N。Replacement 只在真正 resume Run 的 mutation 上生效。
只有当前 typed next.operation 为 resume 时才接受 resume。在 active Action 或可 answer 的 decision/destructive pause 中调用会被拒绝,并返回当前 typed recovery,避免成功响应丢失后的重试静默作废更新的工作。用户 take-over/reorder 先使用公开 slipway stop,之后再单独显式 resume。
Workspace 与 Git observation
Section titled “Workspace 与 Git observation”Workspace identity 包含 canonical worktree root、per-worktree Git directory 与 Git common directory。每次 load 或 mutation 都会重新发现并比较这些路径,再修改 journal。
Repository-wide status 是文件系统只读的例外:不创建 namespace 或 lock、不改权限、不修复 journal byte。其他 linked worktree 的 Run 显示为带 workspace_foreign 的 FirstEvent header stub,且不会在 owning worktree 外完整 replay。无法读取的本地 Run directory 会在不带 Run ID 的 status 输出 JSON 中以 unavailable_runs 保留身份;指定读取时会区分损坏与不存在。该列表不是 slipway list——后者报告的是 host adapter,不含任何 Run 数据。
Git observation 保存 index、porcelain status 和 dirty path 的 hash 与范围明确 metadata,不保存文件内容。发现差异只证明 Run start 之后有变化,不能证明当前宿主造成了变化。
Idempotency 与顺序
Section titled “Idempotency 与顺序”- Outcome idempotency 对原始 accepted input bytes 计算 hash;语义相同但 serialization 不同的 JSON 会 conflict。
- Answer、skip、resume 与 candidate operation 都绑定 current ID,并拒绝 stale/conflicting retry。
- 每个 Run 同时只有一个 writer,由平台 lock implementation 强制。
- Journal order 是 recovery record;
run.json可以重建。
Error 与兼容性
Section titled “Error 与兼容性”Machine error 包含 contract_version、稳定 code、human message、exit_code,并在可恢复时带 structured recovery。Consumer 应按 code/version 分支,不能按 message text 分支。
若 mutation 已 commit,但随后 derive、render 或 write response 失败,mutation_committed_output_failed 会报告 committed: true、exact Run ID,以及定向的 slipway status RUN --root ROOT recovery。不得盲目重放 mutation。
exit_code 与进程退出状态一致,只有两个取值:
| 取值 | 含义 |
|---|---|
2 |
Usage error:调用方式本身有误。 |
3 |
Runtime error:调用格式正确,但操作失败。 |
若进程失败但未产生 structured CLI error,则以 1 退出且不输出 JSON。1 应被视为缺陷或环境故障,而不是一种 protocol 结果。
journal_record_too_large 带有严格的 context、size、limit detail 字段;已知 Run ID 时还带该 Run 的只读 status recovery variant。拒绝过大的 record 不会结束 persistent Run,也不会使其失效。
未知 contract version 和 field 会被拒绝。Version 2 不承诺兼容此前未发布的开发格式;未来不兼容变更必须使用新的明确的版本号,不能加入静默 alias。