@cr1992/agentkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.en.md +107 -0
- package/README.md +103 -0
- package/bin/agentkit.mjs +4 -0
- package/bin/cli.mjs +273 -0
- package/core/atomic-fs.mjs +23 -0
- package/core/cli-help.mjs +54 -0
- package/core/content-digest.mjs +66 -0
- package/core/digest.mjs +67 -0
- package/core/json-schema-lite.mjs +60 -0
- package/core/legacy-entry.mjs +37 -0
- package/core/reflection.mjs +142 -0
- package/core/runtime-bundle.mjs +101 -0
- package/docs/loop/embedded-review-adapter.md +41 -0
- package/docs/loop/loop-state-machine.md +43 -0
- package/docs/loop/recovery-and-fuses.md +34 -0
- package/docs/orchestrate/dispatch-contract.md +92 -0
- package/docs/orchestrate/failure-routing-and-recovery.md +46 -0
- package/docs/orchestrate/host-capability-cache.md +170 -0
- package/docs/orchestrate/isolation-fallback.md +18 -0
- package/docs/orchestrate/model-routing-config.md +186 -0
- package/docs/orchestrate/orchestration-runtime.md +261 -0
- package/docs/orchestrate/review-budget.md +90 -0
- package/docs/orchestrate/task-playbooks.md +85 -0
- package/docs/orchestrate/user-facing-reporting.md +14 -0
- package/docs/verify/evidence-schema.md +167 -0
- package/docs/verify/input-preparation.md +44 -0
- package/docs/verify/verification-protocol.md +76 -0
- package/docs/worktree/batch-integration.md +176 -0
- package/docs/worktree/delivery-identity.md +41 -0
- package/docs/worktree/profile.md +107 -0
- package/docs/worktree/reclaim-and-watch.md +96 -0
- package/docs/worktree/review-lifecycle.md +92 -0
- package/docs/worktree/spawn-and-stack.md +74 -0
- package/domains/loop/loop-runtime.mjs +1056 -0
- package/domains/orchestrate/contract-tool.mjs +169 -0
- package/domains/orchestrate/host_capability_cache.mjs +437 -0
- package/domains/orchestrate/orchestration-ledger.mjs +332 -0
- package/domains/orchestrate/orchestration-metadata.mjs +4 -0
- package/domains/orchestrate/orchestration-reflection.mjs +119 -0
- package/domains/orchestrate/resolve_model_policy.mjs +311 -0
- package/domains/orchestrate/review-budget.mjs +162 -0
- package/domains/orchestrate/worker-capability-preflight.mjs +227 -0
- package/domains/verify/verification-runtime.mjs +1638 -0
- package/domains/worktree/worktree-archive.mjs +135 -0
- package/domains/worktree/worktree-artifact.mjs +123 -0
- package/domains/worktree/worktree-batch-integrate.mjs +713 -0
- package/domains/worktree/worktree-batch-plan.mjs +198 -0
- package/domains/worktree/worktree-batch-result.mjs +241 -0
- package/domains/worktree/worktree-core.mjs +908 -0
- package/domains/worktree/worktree-doctor.mjs +493 -0
- package/domains/worktree/worktree-history.mjs +377 -0
- package/domains/worktree/worktree-learning.mjs +110 -0
- package/domains/worktree/worktree-lifecycle.mjs +786 -0
- package/domains/worktree/worktree-merge-preview.mjs +409 -0
- package/domains/worktree/worktree-mgr.mjs +261 -0
- package/domains/worktree/worktree-process.mjs +55 -0
- package/domains/worktree/worktree-profile.mjs +800 -0
- package/domains/worktree/worktree-provider-gitlab.mjs +59 -0
- package/domains/worktree/worktree-reclaim.mjs +683 -0
- package/domains/worktree/worktree-review-refresh.mjs +574 -0
- package/domains/worktree/worktree-review-watch.mjs +661 -0
- package/domains/worktree/worktree-scan.mjs +510 -0
- package/domains/worktree/worktree-trace-test-worker.mjs +23 -0
- package/domains/worktree/worktree-trace.mjs +478 -0
- package/manage-worktrees/SKILL.md +87 -0
- package/manage-worktrees/agents/openai.yaml +4 -0
- package/manage-worktrees/scripts/worktree-mgr.mjs +10 -0
- package/manage-worktrees/scripts/worktree-scan.mjs +10 -0
- package/orchestrate-subagents/SKILL.md +173 -0
- package/orchestrate-subagents/agents/openai.yaml +4 -0
- package/orchestrate-subagents/scripts/contract-tool.mjs +10 -0
- package/orchestrate-subagents/scripts/host_capability_cache.mjs +10 -0
- package/orchestrate-subagents/scripts/orchestration-ledger.mjs +10 -0
- package/orchestrate-subagents/scripts/orchestration-reflection.mjs +10 -0
- package/orchestrate-subagents/scripts/resolve_model_policy.mjs +10 -0
- package/orchestrate-subagents/scripts/review-budget.mjs +10 -0
- package/orchestrate-subagents/scripts/worker-capability-preflight.mjs +10 -0
- package/package.json +48 -0
- package/run-agent-verify-loop/SKILL.md +127 -0
- package/run-agent-verify-loop/agents/openai.yaml +4 -0
- package/run-agent-verify-loop/scripts/loop-runtime.mjs +10 -0
- package/schemas/artifact-ref-v1.schema.json +23 -0
- package/schemas/batch-result-v1.schema.json +138 -0
- package/schemas/controller-recheck-record-v1.schema.json +22 -0
- package/schemas/convergence-report-v1.schema.json +9 -0
- package/schemas/effective-worker-capability-v1.schema.json +36 -0
- package/schemas/embedded-verification-record-v1.schema.json +32 -0
- package/schemas/evidence-package-v1.schema.json +41 -0
- package/schemas/improvement-proposal-v1.schema.json +18 -0
- package/schemas/loop-state-v1.schema.json +34 -0
- package/schemas/model-policy-resolution-v1.schema.json +41 -0
- package/schemas/orchestration-ledger-v1.schema.json +110 -0
- package/schemas/reflection-record-v1.schema.json +24 -0
- package/schemas/review-result-v1.schema.json +37 -0
- package/schemas/task-contract-v1.schema.json +83 -0
- package/schemas/verification-profile-v1.schema.json +60 -0
- package/schemas/worker-capability-requirements-v1.schema.json +21 -0
- package/schemas/worktree-binding-v1.schema.json +14 -0
- package/shell-manifest.json +79 -0
- package/verify-agent-output/SKILL.md +119 -0
- package/verify-agent-output/agents/openai.yaml +4 -0
- package/verify-agent-output/scripts/verification-runtime.mjs +10 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orchestrate-subagents
|
|
3
|
+
description: "编排实际派生的多个子 Agent,负责拆分、并发、派发契约、运行控制和验收。仅在用户明确要求子 Agent、并行或委派,或任务已确定需要多个 Agent 时使用;单 Agent 和单 Artifact 一次性验收不适用。"
|
|
4
|
+
metadata:
|
|
5
|
+
requires:
|
|
6
|
+
bins: ["agentkit"]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# orchestrate-subagents:子 Agent 编排控制协议
|
|
10
|
+
|
|
11
|
+
提供宿主无关的拆解、派发、控制和验收协议。最强适配模型持续担任 controller,掌握
|
|
12
|
+
`Plan → Delegate → Observe → Re-plan → Verify → Finish`;不得派生另一个 agent 接管控制面或最终判断。
|
|
13
|
+
|
|
14
|
+
## 组合协议
|
|
15
|
+
|
|
16
|
+
本 skill 是组合栈的控制面。先建立任务图,再按已确认的事实启用专项能力:
|
|
17
|
+
|
|
18
|
+
| 条件 | 动作 |
|
|
19
|
+
|---|---|
|
|
20
|
+
| 固定单一 Artifact、单个只读 reviewer、只验一次 | 不启动本 skill;直接使用 `verify-agent-output`,由当前 controller 消费 Evidence |
|
|
21
|
+
| reviewer 是多节点任务图的一部分,或需要并发、不同权限、多个 critic | 本 skill 建任务图;节点的一次性 Evidence 可由 `verify-agent-output` 提供 |
|
|
22
|
+
| 用户明确要求实现者与验收者反复收敛,或 freeze 前已经能合理预期“验收失败→修复→新 Artifact”会发生多轮且修复已获授权 | `run-agent-verify-loop` 可用时用它执行有界循环;Loop 内的一次性验证只作为 provider 调用,不再创建第二个全局 orchestrator |
|
|
23
|
+
| 已确认同仓存在多个并行写入者、写路径碰撞,或写入归属不明且相交 / 丢失代价高,或用户明确要求 worktree | `manage-worktrees` 可用时用它建立和维护隔离;不可用时执行第 3 节安全下限 |
|
|
24
|
+
| 只有一个写入者,其他 Agent 只读 | 共享树,不使用 `manage-worktrees` |
|
|
25
|
+
| 普通批量、仓库 dirty、理论上可能并发 | 不足以启用其他专项 skill |
|
|
26
|
+
|
|
27
|
+
controller 只维护一份公共合同和台账;专项 skill 分别只提供 Evidence、Loop 状态或隔离/Artifact 身份,
|
|
28
|
+
不得重建任务图、改变授权或夺取最终判断。按**收敛对象**路由:固定 SHA 一次裁决走 verify;同一目标
|
|
29
|
+
连续产生新 Artifact 才走 Loop;多个独立任务才走本 skill。terminal Evidence 不得覆盖;后获修复授权时
|
|
30
|
+
保留旧 Evidence,另冻 Loop limits 和新 iteration。
|
|
31
|
+
|
|
32
|
+
## 控制面不变量与派发台账
|
|
33
|
+
|
|
34
|
+
controller 始终拥有闭环对象、完成标准、任务图、依赖/barrier、文件与资源 owner、执行配置、权限、
|
|
35
|
+
隔离、预算、重试、re-plan、集成和最终裁决。定修复方向前先查缺陷登记、决策记录或计划真源;偏离先例
|
|
36
|
+
必须说明理由并交用户裁决。worker 只做有界执行,返回结构化结论、证据和 commit/MR、制品或稳定报告;
|
|
37
|
+
没有稳定产物不得验收,高风险结论可交独立 critic 证伪但不能下放最终判断。
|
|
38
|
+
|
|
39
|
+
派生后维护“活跃 Agent”“本批已完成”,存在并行时再维护“工作进展”;在派发、批次收口、用户询问
|
|
40
|
+
和最终答复时更新,无活跃 worker 明示为 0,不虚构百分比。字段与状态变换见
|
|
41
|
+
[编排运行时](../docs/orchestrate/orchestration-runtime.md)「派发台账的三张表」。台账也是回收清单:收口前
|
|
42
|
+
确认没有孤儿 worker/worktree/运行时资源。任务图与台账只写仓库外会话状态;完整档用 mechanical
|
|
43
|
+
ledger,轻量档用单一 JSON 快照,闭环后清理。
|
|
44
|
+
|
|
45
|
+
### 档位无关的有效能力预检
|
|
46
|
+
|
|
47
|
+
先列每个节点真正需要的 `required_capabilities`,再用 `agentkit orchestrate preflight check` 校验;
|
|
48
|
+
只有 `allowed` 可用。输入已随合同完整提供、节点不依赖额外宿主能力时 requirements 可为空,
|
|
49
|
+
此时记 `not_required` 及依据即可。同机、本地或过去恒过都不构成豁免。探针只在比 controller 自做或
|
|
50
|
+
缩小节点更便宜时派发,并计入 worker 与 Token 预算。能力键前缀、binding 与复用规则、反应矩阵见
|
|
51
|
+
[编排运行时](../docs/orchestrate/orchestration-runtime.md)「Worker 有效能力预检」。
|
|
52
|
+
|
|
53
|
+
### 显式轻量档
|
|
54
|
+
|
|
55
|
+
`orchestration_mode: lightweight` 只用于不超过 3 个互相独立的只读 worker:单 stage、无 barrier/Loop/
|
|
56
|
+
递归/重试,不创建 worktree 或其他待回收资源,不执行发布、部署、消息或外部写入,controller 能在当前
|
|
57
|
+
上下文验收全部输出,且所需能力已有本轮事实或新鲜且 binding 匹配的记录证明。
|
|
58
|
+
|
|
59
|
+
轻量档仍冻结每个节点的目标、范围、事实/假设、输出合同、验收、证据和停止条件,并在仓库外维护
|
|
60
|
+
单一 JSON 快照;它只记录事实,不伪造 journal。资格失效时停止新派发,把现状和产物收养进完整 ledger。
|
|
61
|
+
Reflection 使用 `agentkit orchestrate reflection record/propose`,通用 Skill 缺口不得写入宿主能力缓存。
|
|
62
|
+
快照 schema、收养步骤和 Reflection 约束见 [编排运行时](../docs/orchestrate/orchestration-runtime.md)。
|
|
63
|
+
|
|
64
|
+
### 完整档机械台账工具
|
|
65
|
+
|
|
66
|
+
不满足轻量档时使用 `orchestration_mode: full`。先用 `agentkit contract normalize / validate / digest /
|
|
67
|
+
review-view / diff` 固定公共 Task Contract,再以仓库外 state root 初始化 `agentkit orchestrate ledger`。
|
|
68
|
+
脚本不直接派发 Agent,controller 把宿主回执写入 `dispatch-record`。节点必须选择
|
|
69
|
+
`worker_self_check`、`controller_recheck`、`independent_evidence`,只读 critic/scout 用
|
|
70
|
+
`not_applicable`;依赖/barrier 未通过不派下游。命令、schema、`--expected-revision`、state root 信任
|
|
71
|
+
边界和批级熔断见 [编排运行时](../docs/orchestrate/orchestration-runtime.md)。
|
|
72
|
+
Reflection 只记证据化观察,Improvement Proposal 永远保持 `proposed`,不能改变当前运行。
|
|
73
|
+
|
|
74
|
+
## 1. 先过闸门
|
|
75
|
+
|
|
76
|
+
**默认单干。** 只有广度超出单上下文/串行成本、关键结论需要独立证伪,或大批同构工作需要流水线时
|
|
77
|
+
才编排;单文档、单函数、单点事实和小机械修改不编排。先服从用户与宿主授权:少量轻量只读任务可在
|
|
78
|
+
授权内并行;大 pool、结构化 Workflow、递归派生,以及超预期成本、写入或外部动作必须明确 opt-in。
|
|
79
|
+
|
|
80
|
+
## 2. 规模从结构推导
|
|
81
|
+
|
|
82
|
+
规模来自真正独立且单个上下文装不下的工作块,不来自话题数;删掉不影响答案的节点。常规盘点/审计
|
|
83
|
+
一轮总 Agent 数 `≤10`。扫描与核验配比、
|
|
84
|
+
合并判据与各档规模见 [任务类型剧本](../docs/orchestrate/task-playbooks.md)。
|
|
85
|
+
|
|
86
|
+
## 3. 派发前决定环境
|
|
87
|
+
|
|
88
|
+
多数宿主默认共享文件系统、Git index、进程和外部服务;`writable_paths` 是契约,不是物理沙箱。先只读扫描当前树、已有 worktree、分支占用、近期改动和任务认领;发现目标路径相交时直接选 worktree,不得自动 stash、reset、checkout 或覆盖用户改动。
|
|
89
|
+
|
|
90
|
+
派发新写 worker 前先清点历史 worktree / 分支,按下文“回收”红线判断能否回收;无归属标记的一律按来源不明处理,只清点报告 `KEEP + 原因`、不回收——全 KEEP 是预期行为,不是判断失败。
|
|
91
|
+
|
|
92
|
+
| 场景 | 环境决策 |
|
|
93
|
+
|---|---|
|
|
94
|
+
| 只读侦察、审阅、核验 | 共享当前树,`read_only` |
|
|
95
|
+
| 同一目标仓仅 1 个写 worker;无人同时写;树归本任务;改动小、路径清楚、容易重做 | 可共享当前树,只允许指定路径 |
|
|
96
|
+
| 同仓存在多个并行写入者;人或 controller 同时写;目标文件与非本任务 dirty change 重叠;目标分支被另一活动任务占用 | 每个写 worker 一棵 worktree |
|
|
97
|
+
| 写入 owner 或现有改动归属无法确认,且目标路径确实相交或丢失代价高 | 选 worktree |
|
|
98
|
+
|
|
99
|
+
仓库 dirty、任务大或包含新文件本身都不足以要求隔离;先确认第二写入者、归属冲突或路径相交。
|
|
100
|
+
裁决隔离后使用 `manage-worktrees`,它不改变任务图、权限或验收。不可用时必须先读
|
|
101
|
+
[无 manage-worktrees 时的隔离下限](../docs/orchestrate/isolation-fallback.md)。
|
|
102
|
+
|
|
103
|
+
共享树中 worker 不得切换分支,只按路径 stage / commit;禁止 `git add -A`、`git commit -am`、裸 `stash`、`reset --hard`、`checkout -- .` 和并发 merge,controller 是唯一 integrator。
|
|
104
|
+
|
|
105
|
+
## 4. 选择编排方式
|
|
106
|
+
|
|
107
|
+
2-3 个独立任务用宿主轻量并行;循环、条件、逐项管线或预算驱动才使用结构化编排。多 stage 默认逐条
|
|
108
|
+
pipeline,只有跨条去重、聚合、比较或早退才设 barrier。截断、采样或不重试必须披露覆盖缺口。
|
|
109
|
+
barrier、critic 面板与 loop-until-dry 的具体用法见
|
|
110
|
+
[编排运行时](../docs/orchestrate/orchestration-runtime.md)「编排原语选择」。具体 API 服从宿主编排工具说明。
|
|
111
|
+
|
|
112
|
+
## 5. 派发可验收的任务契约
|
|
113
|
+
|
|
114
|
+
按“可独立验收的责任”拆分,不按宽泛话题拆分。每个节点至少冻结 `objective / scope / inputs(已知事实
|
|
115
|
+
与允许假设分栏)/ output_contract / acceptance / evidence / required_capabilities / verification /
|
|
116
|
+
stop_conditions`;写任务再冻结权限、精确仓库/workdir/branch 和 writable paths。worker 返回
|
|
117
|
+
`status / conclusion / evidence / changes / risks / next_action`,发现合同事实与现场矛盾时升级,不替
|
|
118
|
+
controller 圆场。
|
|
119
|
+
|
|
120
|
+
派发写 worker、完整档、独立 Evidence 或失败后重派前,必须读取
|
|
121
|
+
[节点派发合同](../docs/orchestrate/dispatch-contract.md) 并使用完整 envelope。轻量只读节点可只使用上述最小合同。
|
|
122
|
+
|
|
123
|
+
## 6. 控制运行态与升级
|
|
124
|
+
|
|
125
|
+
用户可见台账只用 `运行中 / 阻塞 / 待验收`;`partial` 由 controller 决定继续、转阻塞或停止后判
|
|
126
|
+
未通过。只有 controller 能给出 `通过 / 未通过 / 取消`。台账术语不进用户汇报,对外说法见
|
|
127
|
+
[面向用户的汇报词表](../docs/orchestrate/user-facing-reporting.md)。
|
|
128
|
+
|
|
129
|
+
只在结论交付、需要输入、scope/写入冲突、预算将尽、新依赖、失败或置信不足时介入;“等待中”不是
|
|
130
|
+
状态包。能力故障、业务失败、中断与 contract gap 分开处理,不按失败次数机械升档。失败、重派、中断
|
|
131
|
+
或 controller 接手时读取[失败路由与恢复](../docs/orchestrate/failure-routing-and-recovery.md)。合同失真、
|
|
132
|
+
新授权、不可逆动作、资源/结论冲突或重试耗尽必须升级,不得自行扩 scope。
|
|
133
|
+
|
|
134
|
+
## 7. 验证、收敛与停止
|
|
135
|
+
|
|
136
|
+
回收后依次 `normalize → deduplicate → validate → synthesize`。研究要求直达来源,代码要求文件 / 符号证据,实现要求 diff 与约定测试;关键 claim 由 controller 用外部可观察证据重验,不采信 worker 自述。
|
|
137
|
+
|
|
138
|
+
四种保证不能混写:`worker_self_check` 只证明稳定输出;`controller_recheck` 绑定覆盖当前稳定输出的
|
|
139
|
+
复核记录;`independent_evidence` 绑定唯一 Artifact 与标准 Evidence;只读 critic/scout 用
|
|
140
|
+
`not_applicable`,附一份 report 即收口。失败、不可判定、安全阻塞、
|
|
141
|
+
human gate 或错绑 Evidence 均不能通过。节点专属验收合同只能用 `agentkit contract project` 从公共
|
|
142
|
+
合同切出 acceptance 子集;完整门禁见 [编排运行时](../docs/orchestrate/orchestration-runtime.md)「合同投影」。
|
|
143
|
+
|
|
144
|
+
快速演进分支的迭代期只读 review 最多算 `controller_recheck`;到 RC/合入候选才冻结唯一 Artifact,
|
|
145
|
+
运行 `verify-agent-output` 生成 `independent_evidence`。
|
|
146
|
+
|
|
147
|
+
聚合状态可能掩蔽条目失败,验收必须下钻到最小可观察单元。critic 必须主动寻找反例:多数判假可作为淘汰信号,多数判真仍不是接受证明。**处方核验**:finding 的事实核验不等于处方核验——采信任何「要求改变现状」的 finding 前,controller 先从裁决真源独立推导预期态,推不出或与处方矛盾时处方不进契约、升级人裁;finding 自己的证据已解释掉大部分偏差而结论未降级的,按证伪信号处理。验收比对对象永远是真源,不是修复目标、MR 描述或契约里转抄的处方。完成但缺少 acceptance 证据时,worker 状态保持 `partial`;停止重试后只有 controller 可判 `未通过`。
|
|
148
|
+
|
|
149
|
+
必要节点全部验收通过、连续 K 轮无新增、剩余工作不会改变决策、需要新授权 / 外部状态变化,或预算耗尽且已披露覆盖缺口时停止;不要把预算耗尽伪装成全面完成。
|
|
150
|
+
|
|
151
|
+
### Reviewer 与 Token 预算
|
|
152
|
+
|
|
153
|
+
独立 reviewer 是高成本资源,不与 worker 1:1 配对。对同一 Artifact 默认只允许一次 primary review;
|
|
154
|
+
第二次必须由 `undecidable`、证据冲突或协议歧义触发,使用不同 lens 且可能改变处置。smoke 未通过、
|
|
155
|
+
同 lens 重复、输入超出预算或已有 `blocked_safety` 时不派。考虑任何 critic/reviewer 时必须读取
|
|
156
|
+
[Reviewer 数量与 Token 预算](../docs/orchestrate/review-budget.md),冻结 `extensions.review_policy`,并在派发前运行
|
|
157
|
+
`agentkit orchestrate review-budget evaluate`。提高 reviewer 数量或输入上限属于 re-contract。
|
|
158
|
+
|
|
159
|
+
最终答复前用 `闭环项 / 标准 / 证据 / 结果` 审计:闭环对象与外部状态已重查;必要节点已验收且活跃
|
|
160
|
+
子 Agent 为 0;自建资源已回收;外部资源列 `KEEP + owner + 原因`;剩余事项明确归类。需要新授权或
|
|
161
|
+
外部状态变化时只能报告“已完成可自主部分,整体未闭环”,并给出唯一解阻动作。
|
|
162
|
+
|
|
163
|
+
## 8. 模型路由与宿主自适配
|
|
164
|
+
|
|
165
|
+
controller 持续掌握目标、任务图、re-plan、失败分类和最终验收;worker 不自选模型或下一次配置。
|
|
166
|
+
派发、首次建 tier、失败后调档或切模型时读[模型路由](../docs/orchestrate/model-routing-config.md),按任务类型
|
|
167
|
+
选档再读[任务剧本](../docs/orchestrate/task-playbooks.md):使用本地配置中最低可靠 tier,model/effort 只取
|
|
168
|
+
用户配置与实时 schema,每次保存精确配置、attempt lineage、理由和预算;扩大授权或显著增费先确认。
|
|
169
|
+
|
|
170
|
+
`agents/openai.yaml` 和缓存都不是能力证明。runtime/path/tool 要求先做有效能力预检;能力快照的创建、
|
|
171
|
+
刷新和复用读[宿主能力缓存](../docs/orchestrate/host-capability-cache.md)。实时 schema 优先,unknown 不能被
|
|
172
|
+
缓存补成 allowed,缓存不能扩大授权。`protocol_version`、`runtime_version`、`content_digest` 分别表示
|
|
173
|
+
协议兼容性、实现版本和精确安装内容,不得互相替代。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/contract-tool.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/contract-tool.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/contract-tool.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/host_capability_cache.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/host_capability_cache.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/host_capability_cache.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/orchestration-ledger.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/orchestration-ledger.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/orchestration-ledger.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/orchestration-reflection.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/orchestration-reflection.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/orchestration-reflection.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/resolve_model_policy.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/resolve_model_policy.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/resolve_model_policy.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/review-budget.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/review-budget.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/review-budget.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/orchestrate/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/orchestrate/worker-capability-preflight.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/orchestrate/worker-capability-preflight.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/orchestrate/worker-capability-preflight.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cr1992/agentkit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Agent engineering toolkit: orchestration, git worktree isolation, independent verification and bounded verify loops.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/cr1992/agentkit.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/cr1992/agentkit#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/cr1992/agentkit/issues"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"registry": "https://registry.npmjs.org/"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"bin": {
|
|
20
|
+
"agentkit": "./bin/agentkit.mjs"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"validate": "node tools/validate-skills.mjs",
|
|
27
|
+
"test": "node tools/validate-skills.mjs && node --test tests/*.test.mjs domains/*/*.test.mjs scripts/*.test.mjs",
|
|
28
|
+
"pack:check": "npm pack --dry-run"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"CHANGELOG.md",
|
|
32
|
+
"shell-manifest.json",
|
|
33
|
+
"bin/",
|
|
34
|
+
"domains/",
|
|
35
|
+
"!domains/**/*.test.mjs",
|
|
36
|
+
"core/",
|
|
37
|
+
"schemas/",
|
|
38
|
+
"docs/worktree/",
|
|
39
|
+
"docs/verify/",
|
|
40
|
+
"docs/orchestrate/",
|
|
41
|
+
"docs/loop/",
|
|
42
|
+
"orchestrate-subagents/",
|
|
43
|
+
"manage-worktrees/",
|
|
44
|
+
"verify-agent-output/",
|
|
45
|
+
"run-agent-verify-loop/"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {}
|
|
48
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-agent-verify-loop
|
|
3
|
+
description: "运行有界的 Agent 实现—独立验收循环,记录 Artifact、Evidence、失败指纹和熔断状态。仅在用户明确要求反复修复验收,或已预期同一目标会产生多轮新 Artifact 时使用;一次性验收和普通批量不适用。"
|
|
4
|
+
metadata:
|
|
5
|
+
requires:
|
|
6
|
+
bins: ["agentkit"]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# run-agent-verify-loop:显式实现—验收循环
|
|
10
|
+
|
|
11
|
+
只在 controller 已明确选择循环模式后运行。Loop 不是普通任务、一次性验收或四 Skill 组合的总入口,
|
|
12
|
+
不拥有 Agent 派发、provider 选择、Git 生命周期和全局完成授权。
|
|
13
|
+
|
|
14
|
+
## 启动闸门
|
|
15
|
+
|
|
16
|
+
命中以下任一才启动:
|
|
17
|
+
|
|
18
|
+
- 用户明确要求反复修复并由独立 reviewer 验收;
|
|
19
|
+
- 用户显式调用 `/run-agent-verify-loop <目标>`;
|
|
20
|
+
- controller 在 freeze 前已有证据表明同一收敛对象很可能需要连续新 Artifact,且用户已经授权该修复范围与有界重试。
|
|
21
|
+
|
|
22
|
+
启动前固定顺序:
|
|
23
|
+
|
|
24
|
+
1. controller 补齐 objective、scope、acceptance、权限、非目标和停止条件;
|
|
25
|
+
2. 缺少可观察验收标准时不创建 Loop;
|
|
26
|
+
3. freeze 前完成 capability discovery 和 provider 选择;
|
|
27
|
+
4. 冻结 Task Contract、Verification Profile、Skill content digest、limits 与 H gate;
|
|
28
|
+
5. 创建 Loop State,再开始 implement → artifact → verify → decide。
|
|
29
|
+
|
|
30
|
+
不要先手工串多次 `verify-agent-output` 再把结果伪装成一个 Loop。若一次性 verification 已 terminal 后
|
|
31
|
+
才获得循环授权,旧 Evidence 保持不可变;新建 Loop、冻结 limits,并把后续新 Artifact 作为正式
|
|
32
|
+
iteration。Loop 可以把旧 Evidence 当背景/失败证据,但不得重写其 run_id、revision 或 verdict。
|
|
33
|
+
|
|
34
|
+
普通 Loop 不自动创建宿主持久 Goal。只有用户明确要求持续追踪 Goal 时,controller 才创建外部 Goal
|
|
35
|
+
并把不透明 `goal_ref` 绑定进 Loop;Loop completed 仍只是 Goal 的完成证据之一。
|
|
36
|
+
|
|
37
|
+
## Provider
|
|
38
|
+
|
|
39
|
+
### 标准组合模式
|
|
40
|
+
|
|
41
|
+
安装 `verify-agent-output` 时选择 `provider: verify-agent-output`。每轮为冻结 Artifact 创建一个新的
|
|
42
|
+
verification run,消费其标准 Evidence Package。Loop 不执行或复制完整 verifier 协议。
|
|
43
|
+
|
|
44
|
+
### Embedded 独立模式
|
|
45
|
+
|
|
46
|
+
没有专项 verifier 时,可在 freeze 前明确选择 `provider: embedded`:
|
|
47
|
+
|
|
48
|
+
- `loop-runtime` 在 clean pinned workdir 执行单阶段 L0;
|
|
49
|
+
- 宿主提供新上下文 reviewer,或用户中继第二会话;
|
|
50
|
+
- reviewer 仍输出共享 Review Result v1;
|
|
51
|
+
- runtime 只生成 `embedded_verification_record`,不能导出、转换或冒充 Evidence Package;
|
|
52
|
+
- 无独立 reviewer 时停止,不用实现者自审产生 pass。
|
|
53
|
+
|
|
54
|
+
进入 embedded L1 前读取 [内嵌 review 适配器](../docs/loop/embedded-review-adapter.md)。
|
|
55
|
+
verifier 行为语义以 [验收协议](../docs/verify/verification-protocol.md) 为唯一真源;独立安装本 Skill
|
|
56
|
+
时,adapter 只携带绑定和最低输入要求,不重定义 verdict。
|
|
57
|
+
|
|
58
|
+
## Runtime 流程
|
|
59
|
+
|
|
60
|
+
状态默认放仓库外:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
agentkit loop init \
|
|
64
|
+
--contract contract.json --profile profile.json \
|
|
65
|
+
--provider verify-agent-output --state-root <state-root> \
|
|
66
|
+
--max-iterations 3 --consecutive-identical-signature 2
|
|
67
|
+
agentkit loop record-artifact \
|
|
68
|
+
--loop <loop-dir> --artifact artifact.json --verification-run-id <run-id>
|
|
69
|
+
agentkit loop record-evidence \
|
|
70
|
+
--loop <loop-dir> --evidence evidence.json
|
|
71
|
+
agentkit loop next --loop <loop-dir>
|
|
72
|
+
agentkit loop status --loop <loop-dir>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Embedded 模式在 `record-artifact` 后执行:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
run-embedded-l0 → 新上下文 reviewer → record-embedded-review
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
所有状态写命令可带 `--expected-revision <n>`;revision 不匹配时拒绝写入。详细状态迁移见
|
|
82
|
+
[Loop 状态机](../docs/loop/loop-state-machine.md),恢复和熔断见
|
|
83
|
+
[恢复与熔断](../docs/loop/recovery-and-fuses.md)。只有发生复制/移动、journal 恢复、
|
|
84
|
+
reflection 或提案时才使用 `adopt-root / record-reflection / convergence-report / propose-improvement --help`。
|
|
85
|
+
|
|
86
|
+
## 决策规则
|
|
87
|
+
|
|
88
|
+
- `pass`:无 H gate 时进入 `completed`;有 H gate 时只能 `waiting_human`;
|
|
89
|
+
- `fail`:记录稳定 failure signature,再按 policy 进入下一轮或熔断;
|
|
90
|
+
- `undecidable` / `blocked_safety`:立即 `stopped` 并升级;
|
|
91
|
+
- verification operational abort:`stopped`,不增加 iteration、不生成 failure signature;
|
|
92
|
+
- resume 只允许 controller 为 verification abort 绑定新的 verification run;
|
|
93
|
+
- max iterations、连续相同失败阈值和 H gate 不能由 implementer 提高或绕过;
|
|
94
|
+
- Loop completed 不等于外部 Goal 或全局任务完成。
|
|
95
|
+
|
|
96
|
+
失败指纹只使用失败 L0 的 `check_id` 和 L1 的 `{contract_item_id, class}`,不对自然语言做猜测归类。
|
|
97
|
+
|
|
98
|
+
## 状态与证据
|
|
99
|
+
|
|
100
|
+
- event journal 是真源,snapshot 丢失或落后时从最后完整 event 恢复;
|
|
101
|
+
- state root 级扫描所有 Loop journal,原子拒绝重复消费同一 Evidence `run_id`;
|
|
102
|
+
- freeze 后每次推进前重算本 Skill content digest;漂移时停止并要求 re-contract;
|
|
103
|
+
- full Evidence 与 embedded record 使用不同文件、digest 字段和 assurance,consumer 不得混用;
|
|
104
|
+
- runtime 不派发 Agent、不修改业务 Artifact、不创建 worktree、不下载依赖。
|
|
105
|
+
|
|
106
|
+
### 信任与恢复边界
|
|
107
|
+
|
|
108
|
+
state root 只应由 controller/operator 与本 runtime 写入。journal digest chain 能发现部分、追加、乱序
|
|
109
|
+
和意外损坏,但不是签名或外部不可变锚;能重写整棵 state root 的 writer 可构造另一条自洽历史。
|
|
110
|
+
Review nonce 只拒绝未经修改的跨 run 重放,`host_reported` assurance 是调用方声明。当前 Loop 内
|
|
111
|
+
`blocked_safety` 优先且不可抵消;跨新 Loop/run 的同一 Artifact 安全记忆属于上层台账/维护流程。
|
|
112
|
+
state-root identity 只拒绝未修改的复制或移动;`adopt-root` 会检查已有 Loop journal 与冻结 envelope,
|
|
113
|
+
然后代表 operator 显式重新授权当前位置,它不是针对 state-root writer 的防复制证明。doctor 会在身份
|
|
114
|
+
错误时返回 `state_root_identity_invalid` 和恢复命令。
|
|
115
|
+
Embedded L0 会冻结 executable 与所有实际存在的 argv 文件参数;workdir 内文件同时受 clean pinned
|
|
116
|
+
Git Artifact 约束,被 gitignore 的 runner 也不能绕过内容冻结。
|
|
117
|
+
|
|
118
|
+
`completed` / `stopped` 状态转换会自动 write-new 一个不可变 Convergence Report;`waiting_human`
|
|
119
|
+
不是终态,不生成完整报告。Reflection 只绑定可重算摘要的事件、Evidence、Artifact 或诊断文件;
|
|
120
|
+
Proposal 永远停留在 `proposed`,不得改变 failure fuse、H gate、verdict 或既有报告。
|
|
121
|
+
|
|
122
|
+
## 批量边界
|
|
123
|
+
|
|
124
|
+
一个 Loop 只维护一个收敛对象,不接受批队列。普通批量由 controller / orchestrator 为每个 work
|
|
125
|
+
item 建立独立 Loop;批状态、断点续跑、失败上限和连续同因熔断由 orchestration ledger 的
|
|
126
|
+
`batch-init / batch-record / batch-status / batch-fuse` 管理。Loop 的 Convergence Report 与稳定
|
|
127
|
+
failure signature 是批台账输入,但批台账不能反向改写单个 Loop 的终态。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// 1.x 兼容入口。本 Skill 的运行时已迁入 domains/loop/,此处只做固定转发,不含实现。
|
|
3
|
+
// 直接执行时行为与 domains/loop/loop-runtime.mjs 逐字节一致;被 import 时只透传导出。
|
|
4
|
+
import { forwardLegacyEntry } from '../../core/legacy-entry.mjs';
|
|
5
|
+
import { runCli } from '../../domains/loop/loop-runtime.mjs';
|
|
6
|
+
|
|
7
|
+
export * from '../../domains/loop/loop-runtime.mjs';
|
|
8
|
+
|
|
9
|
+
const status = forwardLegacyEntry(import.meta.url, runCli);
|
|
10
|
+
if (status !== undefined) process.exitCode = status;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://agent-skills.example/schemas/artifact-ref-v1.schema.json",
|
|
4
|
+
"title": "Artifact Ref v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schema_version", "provider", "repository_id", "object_format", "base_sha", "artifact_sha"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schema_version": { "const": 1 },
|
|
9
|
+
"provider": { "enum": ["manage-worktrees", "caller-supplied"] },
|
|
10
|
+
"repository_id": { "type": "string", "minLength": 1 },
|
|
11
|
+
"object_format": { "enum": ["sha1", "sha256"] },
|
|
12
|
+
"base_sha": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
|
|
13
|
+
"artifact_sha": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
|
|
14
|
+
"branch_hint": { "type": "string" },
|
|
15
|
+
"worktree_id": { "type": "string", "minLength": 1 },
|
|
16
|
+
"ownership_epoch": { "type": "integer", "minimum": 1 },
|
|
17
|
+
"target_sha": { "type": "string" },
|
|
18
|
+
"ordered_input_shas": { "type": "array", "items": { "type": "string" } },
|
|
19
|
+
"batch_fingerprint": { "type": "string" }
|
|
20
|
+
},
|
|
21
|
+
"allOf": [{ "if": { "properties": { "provider": { "const": "manage-worktrees" } } }, "then": { "required": ["worktree_id", "ownership_epoch"] } }],
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://agent-skills.example/schemas/batch-result-v1.schema.json",
|
|
4
|
+
"title": "Batch Result v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"outcome",
|
|
10
|
+
"candidate_sha",
|
|
11
|
+
"fingerprint",
|
|
12
|
+
"target_ref",
|
|
13
|
+
"target_sha",
|
|
14
|
+
"ordered_input_shas",
|
|
15
|
+
"evidence_manifest_digest",
|
|
16
|
+
"evidence_manifest",
|
|
17
|
+
"reason",
|
|
18
|
+
"result_digest",
|
|
19
|
+
"recorded_at"
|
|
20
|
+
],
|
|
21
|
+
"properties": {
|
|
22
|
+
"schema_version": { "const": 1 },
|
|
23
|
+
"outcome": { "enum": ["passed", "failed", "stale"] },
|
|
24
|
+
"candidate_sha": { "$ref": "#/$defs/objectId" },
|
|
25
|
+
"fingerprint": { "$ref": "#/$defs/digest" },
|
|
26
|
+
"target_ref": { "type": "string", "minLength": 1 },
|
|
27
|
+
"target_sha": { "$ref": "#/$defs/objectId" },
|
|
28
|
+
"ordered_input_shas": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"minItems": 1,
|
|
31
|
+
"items": { "$ref": "#/$defs/objectId" }
|
|
32
|
+
},
|
|
33
|
+
"evidence_manifest_digest": {
|
|
34
|
+
"oneOf": [{ "$ref": "#/$defs/digest" }, { "type": "null" }]
|
|
35
|
+
},
|
|
36
|
+
"evidence_manifest": {
|
|
37
|
+
"oneOf": [{ "$ref": "#/$defs/evidenceManifest" }, { "type": "null" }]
|
|
38
|
+
},
|
|
39
|
+
"reason": { "type": ["string", "null"], "minLength": 1, "maxLength": 500 },
|
|
40
|
+
"result_digest": { "$ref": "#/$defs/digest" },
|
|
41
|
+
"recorded_at": { "type": "string", "format": "date-time" }
|
|
42
|
+
},
|
|
43
|
+
"allOf": [
|
|
44
|
+
{
|
|
45
|
+
"if": { "properties": { "outcome": { "enum": ["passed", "failed"] } } },
|
|
46
|
+
"then": {
|
|
47
|
+
"properties": {
|
|
48
|
+
"evidence_manifest_digest": { "$ref": "#/$defs/digest" },
|
|
49
|
+
"evidence_manifest": {
|
|
50
|
+
"allOf": [
|
|
51
|
+
{ "$ref": "#/$defs/evidenceManifest" },
|
|
52
|
+
{
|
|
53
|
+
"properties": {
|
|
54
|
+
"contract_digest": { "$ref": "#/$defs/digest" }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"if": { "properties": { "outcome": { "const": "stale" } } },
|
|
64
|
+
"then": { "properties": { "reason": { "type": "string", "minLength": 1 } } }
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"$defs": {
|
|
68
|
+
"objectId": { "type": "string", "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$" },
|
|
69
|
+
"digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
|
70
|
+
"evidenceManifest": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"required": ["schema_version", "contract_digest", "checks"],
|
|
74
|
+
"properties": {
|
|
75
|
+
"schema_version": { "const": 1 },
|
|
76
|
+
"contract_digest": { "oneOf": [{ "$ref": "#/$defs/digest" }, { "type": "null" }] },
|
|
77
|
+
"checks": {
|
|
78
|
+
"type": "array",
|
|
79
|
+
"minItems": 1,
|
|
80
|
+
"maxItems": 100,
|
|
81
|
+
"items": { "$ref": "#/$defs/check" }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"check": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"required": ["name", "environment", "argv", "outcome", "exit_code", "evidence_refs"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"name": { "$ref": "#/$defs/text120" },
|
|
91
|
+
"environment": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"maxProperties": 50,
|
|
94
|
+
"propertyNames": {
|
|
95
|
+
"allOf": [
|
|
96
|
+
{ "pattern": "^[a-z][a-z0-9_.-]{0,63}$" },
|
|
97
|
+
{ "not": { "pattern": "(?:secret|token|password|credential|private[_-]?key|api[_-]?key)" } }
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"additionalProperties": {
|
|
101
|
+
"oneOf": [
|
|
102
|
+
{ "type": "string", "maxLength": 500, "pattern": "^[^\\u0000\\r\\n]*$" },
|
|
103
|
+
{ "type": "number" },
|
|
104
|
+
{ "type": "boolean" }
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"argv": {
|
|
109
|
+
"type": "array",
|
|
110
|
+
"minItems": 1,
|
|
111
|
+
"maxItems": 100,
|
|
112
|
+
"items": { "$ref": "#/$defs/text1000NoNewline" }
|
|
113
|
+
},
|
|
114
|
+
"outcome": { "enum": ["passed", "failed", "undecidable"] },
|
|
115
|
+
"exit_code": { "type": "integer", "minimum": 0, "maximum": 255 },
|
|
116
|
+
"evidence_refs": {
|
|
117
|
+
"type": "array",
|
|
118
|
+
"minItems": 1,
|
|
119
|
+
"maxItems": 20,
|
|
120
|
+
"items": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"additionalProperties": false,
|
|
123
|
+
"required": ["kind", "id", "digest"],
|
|
124
|
+
"properties": {
|
|
125
|
+
"kind": { "$ref": "#/$defs/text40" },
|
|
126
|
+
"id": { "$ref": "#/$defs/text1000" },
|
|
127
|
+
"digest": { "$ref": "#/$defs/digest" }
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"text40": { "type": "string", "minLength": 1, "maxLength": 40, "pattern": "^[^\\u0000-\\u001f\\u007f]+$" },
|
|
134
|
+
"text120": { "type": "string", "minLength": 1, "maxLength": 120, "pattern": "^[^\\u0000-\\u001f\\u007f]+$" },
|
|
135
|
+
"text1000": { "type": "string", "minLength": 1, "maxLength": 1000, "pattern": "^[^\\u0000-\\u001f\\u007f]+$" },
|
|
136
|
+
"text1000NoNewline": { "type": "string", "minLength": 1, "maxLength": 1000, "pattern": "^[^\\u0000\\r\\n]+$" }
|
|
137
|
+
}
|
|
138
|
+
}
|