cohorte 2.10.0 → 3.0.0-dev.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.
Files changed (211) hide show
  1. package/README.md +7 -0
  2. package/assets/manifest.json +193 -0
  3. package/assets/migrations/config/README.md +12 -0
  4. package/assets/migrations/state/0001_init.sql +154 -0
  5. package/assets/prompts/README.md +11 -0
  6. package/assets/prompts/agents/fixer.md +7 -0
  7. package/assets/prompts/agents/implementer.md +12 -0
  8. package/assets/prompts/agents/reviewer.md +8 -0
  9. package/assets/prompts/agents/security-reviewer.md +7 -0
  10. package/assets/prompts/phases/build.md +5 -0
  11. package/assets/prompts/phases/review.md +5 -0
  12. package/assets/prompts/phases/test.md +5 -0
  13. package/assets/prompts/system.md +11 -0
  14. package/assets/schemas/agent-output.schema.json +225 -0
  15. package/assets/schemas/auth-status.schema.json +87 -0
  16. package/assets/schemas/command-result.schema.json +192 -0
  17. package/assets/schemas/commands.schema.json +952 -0
  18. package/assets/schemas/config.schema.json +2259 -0
  19. package/assets/schemas/doctor-report.schema.json +104 -0
  20. package/assets/schemas/events.schema.json +8514 -0
  21. package/assets/schemas/fake-script.schema.json +549 -0
  22. package/assets/schemas/inspect.schema.json +3133 -0
  23. package/assets/schemas/manifest.schema.json +79 -0
  24. package/assets/schemas/ownership.schema.json +52 -0
  25. package/assets/schemas/policy-verdict.schema.json +282 -0
  26. package/assets/schemas/project-model.schema.json +783 -0
  27. package/assets/schemas/project-status.schema.json +217 -0
  28. package/assets/schemas/reconcile-plan.schema.json +155 -0
  29. package/assets/schemas/run-diff.schema.json +177 -0
  30. package/assets/schemas/run-snapshot-manifest.schema.json +2104 -0
  31. package/assets/schemas/run-state.schema.json +1755 -0
  32. package/assets/schemas/runtime-capabilities.schema.json +1545 -0
  33. package/assets/schemas/sandbox-capabilities.schema.json +116 -0
  34. package/assets/schemas/skill.schema.json +87 -0
  35. package/assets/schemas/spec.schema.json +202 -0
  36. package/assets/schemas/tool-catalogue.schema.json +655 -0
  37. package/assets/schemas/trust-record.schema.json +38 -0
  38. package/assets/skills/README.md +9 -0
  39. package/assets/skills/inspect-surface.md +4 -0
  40. package/dist/agent-host.mjs +50 -0
  41. package/dist/agent-host.mjs.map +1 -0
  42. package/dist/bundle-manifest.json +102 -0
  43. package/dist/chunks/__host-DgGPyco9.mjs +18 -0
  44. package/dist/chunks/__host-DgGPyco9.mjs.map +1 -0
  45. package/dist/chunks/approve-Cv135UqI.mjs +19 -0
  46. package/dist/chunks/approve-Cv135UqI.mjs.map +1 -0
  47. package/dist/chunks/auth-BT5oVp76.mjs +132 -0
  48. package/dist/chunks/auth-BT5oVp76.mjs.map +1 -0
  49. package/dist/chunks/auth-D8rCVY33.mjs +84 -0
  50. package/dist/chunks/auth-D8rCVY33.mjs.map +1 -0
  51. package/dist/chunks/brainstorm-CU10T1tm.mjs +7 -0
  52. package/dist/chunks/brainstorm-CU10T1tm.mjs.map +1 -0
  53. package/dist/chunks/cancel-KV_cpsqS.mjs +15 -0
  54. package/dist/chunks/cancel-KV_cpsqS.mjs.map +1 -0
  55. package/dist/chunks/canonical-C8UxeEmB.mjs +57 -0
  56. package/dist/chunks/canonical-C8UxeEmB.mjs.map +1 -0
  57. package/dist/chunks/catalogue-BvwSrM_j.mjs +1549 -0
  58. package/dist/chunks/catalogue-BvwSrM_j.mjs.map +1 -0
  59. package/dist/chunks/compose-Cr0hP0qm.mjs +7303 -0
  60. package/dist/chunks/compose-Cr0hP0qm.mjs.map +1 -0
  61. package/dist/chunks/config-DefHA2Lw.mjs +96 -0
  62. package/dist/chunks/config-DefHA2Lw.mjs.map +1 -0
  63. package/dist/chunks/contract-B0ra2-bm.mjs +295 -0
  64. package/dist/chunks/contract-B0ra2-bm.mjs.map +1 -0
  65. package/dist/chunks/contract-vYbwYr0Y.mjs +123 -0
  66. package/dist/chunks/contract-vYbwYr0Y.mjs.map +1 -0
  67. package/dist/chunks/deny-ClTxSvHJ.mjs +15 -0
  68. package/dist/chunks/deny-ClTxSvHJ.mjs.map +1 -0
  69. package/dist/chunks/diff-Qw0II0sj.mjs +101 -0
  70. package/dist/chunks/diff-Qw0II0sj.mjs.map +1 -0
  71. package/dist/chunks/discover-30Ciya_0.mjs +20 -0
  72. package/dist/chunks/discover-30Ciya_0.mjs.map +1 -0
  73. package/dist/chunks/doctor-DfCrKpfT.mjs +222 -0
  74. package/dist/chunks/doctor-DfCrKpfT.mjs.map +1 -0
  75. package/dist/chunks/fix-D4Tj8RVA.mjs +18 -0
  76. package/dist/chunks/fix-D4Tj8RVA.mjs.map +1 -0
  77. package/dist/chunks/gc-BBXlBF5w.mjs +161 -0
  78. package/dist/chunks/gc-BBXlBF5w.mjs.map +1 -0
  79. package/dist/chunks/init-Okz4mlhW.mjs +30 -0
  80. package/dist/chunks/init-Okz4mlhW.mjs.map +1 -0
  81. package/dist/chunks/inspect-Buby4cQD.mjs +22 -0
  82. package/dist/chunks/inspect-Buby4cQD.mjs.map +1 -0
  83. package/dist/chunks/logs-Giq5sUau.mjs +25 -0
  84. package/dist/chunks/logs-Giq5sUau.mjs.map +1 -0
  85. package/dist/chunks/migrate-DRoFUg53.mjs +19 -0
  86. package/dist/chunks/migrate-DRoFUg53.mjs.map +1 -0
  87. package/dist/chunks/models-Btp6X2YZ.mjs +24 -0
  88. package/dist/chunks/models-Btp6X2YZ.mjs.map +1 -0
  89. package/dist/chunks/pause-BASBfKLO.mjs +16 -0
  90. package/dist/chunks/pause-BASBfKLO.mjs.map +1 -0
  91. package/dist/chunks/policy-DUIgzF3W.mjs +139 -0
  92. package/dist/chunks/policy-DUIgzF3W.mjs.map +1 -0
  93. package/dist/chunks/providers-Dx78imKj.mjs +19 -0
  94. package/dist/chunks/providers-Dx78imKj.mjs.map +1 -0
  95. package/dist/chunks/reconcile-BfD785gd.mjs +26 -0
  96. package/dist/chunks/reconcile-BfD785gd.mjs.map +1 -0
  97. package/dist/chunks/render-DyZr5Lgi.mjs +53 -0
  98. package/dist/chunks/render-DyZr5Lgi.mjs.map +1 -0
  99. package/dist/chunks/resume-GJQRb2Eb.mjs +15 -0
  100. package/dist/chunks/resume-GJQRb2Eb.mjs.map +1 -0
  101. package/dist/chunks/retry-CLrUem1H.mjs +15 -0
  102. package/dist/chunks/retry-CLrUem1H.mjs.map +1 -0
  103. package/dist/chunks/review-BDdjb6kB.mjs +17 -0
  104. package/dist/chunks/review-BDdjb6kB.mjs.map +1 -0
  105. package/dist/chunks/run-CgTWYlcd.mjs +82 -0
  106. package/dist/chunks/run-CgTWYlcd.mjs.map +1 -0
  107. package/dist/chunks/run-tool-C3rAv4XF.mjs +26 -0
  108. package/dist/chunks/run-tool-C3rAv4XF.mjs.map +1 -0
  109. package/dist/chunks/schema-C9QbUW4H.mjs +578 -0
  110. package/dist/chunks/schema-C9QbUW4H.mjs.map +1 -0
  111. package/dist/chunks/send-BdnJ85Nz.mjs +19 -0
  112. package/dist/chunks/send-BdnJ85Nz.mjs.map +1 -0
  113. package/dist/chunks/ship-DTuLGoaJ.mjs +19 -0
  114. package/dist/chunks/ship-DTuLGoaJ.mjs.map +1 -0
  115. package/dist/chunks/shutdown-BM92Iyv2.mjs +15 -0
  116. package/dist/chunks/shutdown-BM92Iyv2.mjs.map +1 -0
  117. package/dist/chunks/skip-DZG5kpcH.mjs +18 -0
  118. package/dist/chunks/skip-DZG5kpcH.mjs.map +1 -0
  119. package/dist/chunks/spec-Bq0P3jVh.mjs +20 -0
  120. package/dist/chunks/spec-Bq0P3jVh.mjs.map +1 -0
  121. package/dist/chunks/src-CId6kMsY.mjs +1689 -0
  122. package/dist/chunks/src-CId6kMsY.mjs.map +1 -0
  123. package/dist/chunks/src-CfAOde7C.mjs +5403 -0
  124. package/dist/chunks/src-CfAOde7C.mjs.map +1 -0
  125. package/dist/chunks/src-Cu3TxNob.mjs +783 -0
  126. package/dist/chunks/src-Cu3TxNob.mjs.map +1 -0
  127. package/dist/chunks/src-DcU4IXMe.mjs +117 -0
  128. package/dist/chunks/src-DcU4IXMe.mjs.map +1 -0
  129. package/dist/chunks/src-JxawBQBn.mjs +446 -0
  130. package/dist/chunks/src-JxawBQBn.mjs.map +1 -0
  131. package/dist/chunks/src-s7YRvk0t.mjs +2116 -0
  132. package/dist/chunks/src-s7YRvk0t.mjs.map +1 -0
  133. package/dist/chunks/status-SMjiOMYy.mjs +29 -0
  134. package/dist/chunks/status-SMjiOMYy.mjs.map +1 -0
  135. package/dist/chunks/tail-BuhT-2PH.mjs +25 -0
  136. package/dist/chunks/tail-BuhT-2PH.mjs.map +1 -0
  137. package/dist/chunks/update-BXIppsbi.mjs +16 -0
  138. package/dist/chunks/update-BXIppsbi.mjs.map +1 -0
  139. package/dist/cli.mjs +175 -0
  140. package/dist/cli.mjs.map +1 -0
  141. package/package.json +17 -32
  142. package/CHANGELOG.md +0 -1453
  143. package/bin/cli.js +0 -812
  144. package/bin/report.js +0 -141
  145. package/core/adapter/render.js +0 -389
  146. package/core/agents/implementer.template.md +0 -142
  147. package/core/agents/profile-reader.md +0 -50
  148. package/core/agents/release.md +0 -58
  149. package/core/agents/review.md +0 -179
  150. package/core/commands/cohorte-align-ds.md +0 -33
  151. package/core/commands/cohorte-audit.md +0 -58
  152. package/core/commands/cohorte-brainstorm.md +0 -70
  153. package/core/commands/cohorte-build.md +0 -219
  154. package/core/commands/cohorte-doctor.md +0 -170
  155. package/core/commands/cohorte-fix.md +0 -80
  156. package/core/commands/cohorte-fleet.md +0 -103
  157. package/core/commands/cohorte-init-pipeline.md +0 -31
  158. package/core/commands/cohorte-intake.md +0 -92
  159. package/core/commands/cohorte-patch.md +0 -118
  160. package/core/commands/cohorte-refactor.md +0 -59
  161. package/core/commands/cohorte-retro.md +0 -85
  162. package/core/commands/cohorte-review.md +0 -270
  163. package/core/commands/cohorte-ship.md +0 -122
  164. package/core/commands/cohorte-spec.md +0 -101
  165. package/core/commands/cohorte-update-pipeline.md +0 -134
  166. package/core/hooks/gate.py +0 -580
  167. package/core/runtimes/claude.json +0 -74
  168. package/core/runtimes/codex.json +0 -83
  169. package/core/runtimes/cursor.json +0 -76
  170. package/core/runtimes/gemini.json +0 -76
  171. package/core/runtimes/opencode.json +0 -73
  172. package/core/templates/agent-handoff.md +0 -34
  173. package/core/templates/brainstorm-return.md +0 -36
  174. package/core/templates/decisions.template.md +0 -42
  175. package/core/templates/design-brief.md +0 -44
  176. package/core/templates/patch.template.md +0 -86
  177. package/core/templates/pr-body.md +0 -25
  178. package/core/templates/review-feedback.md +0 -38
  179. package/core/templates/spec.template.md +0 -87
  180. package/core/templates/steps/init-pipeline/01-detect-stack.md +0 -44
  181. package/core/templates/steps/init-pipeline/02-interview-gaps.md +0 -55
  182. package/core/templates/steps/init-pipeline/03-draft-profile.md +0 -10
  183. package/core/templates/steps/init-pipeline/04-write-render.md +0 -115
  184. package/core/templates/steps/init-pipeline/05-report.md +0 -12
  185. package/core/workflows/audit.js +0 -240
  186. package/core/workflows/loop.js +0 -641
  187. package/core/workflows/refactor.js +0 -276
  188. package/core/workflows/review.js +0 -456
  189. package/install.ps1 +0 -103
  190. package/install.sh +0 -114
  191. package/lib/doctor.js +0 -504
  192. package/lib/runtime.js +0 -134
  193. package/lib/versions.js +0 -149
  194. package/lib/yaml.js +0 -129
  195. package/profile/PIPELINE.template.md +0 -251
  196. package/profile/SCHEMA.md +0 -698
  197. package/profile/cohorte.config.template.yaml +0 -43
  198. package/scripts/assert-gate-hook.mjs +0 -75
  199. package/scripts/kanban-move.sh +0 -313
  200. package/scripts/metrics/collect.mjs +0 -531
  201. package/scripts/metrics/prices.json +0 -42
  202. package/scripts/new-feature.sh.template +0 -98
  203. package/scripts/preflight.sh +0 -124
  204. package/scripts/remove-feature.sh.template +0 -56
  205. package/scripts/test-adapter.mjs +0 -368
  206. package/scripts/test-gate.mjs +0 -428
  207. package/scripts/test-kanban.mjs +0 -304
  208. package/scripts/test-lib.mjs +0 -310
  209. package/scripts/test-metrics.mjs +0 -156
  210. package/scripts/test-workflows.mjs +0 -758
  211. package/scripts/validate-core.mjs +0 -320
@@ -0,0 +1,2116 @@
1
+ import { t as canonicalJson } from "./canonical-C8UxeEmB.mjs";
2
+ import { B as ErrorInfo, C as PhaseRunId, D as SurfaceId, E as SpecId, O as ToolCallId, S as IsoInstant, T as Sha256, V as JsonValueSchema, _ as CommandId, b as FindingId, d as ModelRef, f as MonetaryCost, g as ArtifactId, h as ApprovalId, i as Redaction, l as AuthMode, m as AgentId, n as QuotaInfo, o as err, p as ThinkingLevel, r as TokenUsage, s as ok, t as BudgetCounters, u as ModelCapability, v as EffectId, w as RunId, y as EventId } from "./src-Cu3TxNob.mjs";
3
+ import { Type } from "typebox";
4
+ import { Compile } from "typebox/compile";
5
+ //#region ../../packages/protocol/src/open-enum.ts
6
+ /** The keyword a PUBLISHED schema carries instead of `enum`: the values this version knows, as documentation. */
7
+ const OPEN_ENUM_KEYWORD = "x-cohorte-known";
8
+ const checked = (values, what) => {
9
+ if (values.length === 0) throw new RangeError(`${what}: at least one value is required`);
10
+ if (new Set(values).size !== values.length) throw new RangeError(`${what}: duplicate value in [${values.join(", ")}]`);
11
+ return [...values];
12
+ };
13
+ /**
14
+ * OPEN enums (values may be added in a minor): strict compile -> enum [...known];
15
+ * published schema -> { type: 'string', 'x-cohorte-known': [...] } (compile.ts does the rewrite).
16
+ * The authored form carries BOTH keywords: `enum` is what the writer-side validator enforces, the marker is what
17
+ * tells the generator that this enum, unlike a closed one, must lose its `enum` when published.
18
+ */
19
+ function OpenEnum(known, opts = {}) {
20
+ const values = checked(known, "OpenEnum");
21
+ return Type.Unsafe({
22
+ type: "string",
23
+ enum: values,
24
+ [OPEN_ENUM_KEYWORD]: [...values],
25
+ ...opts
26
+ });
27
+ }
28
+ /** A CLOSED string enum: adding a value is a MAJOR. One `enum` keyword rather than an `anyOf` of constants. */
29
+ function ClosedEnum(values, opts = {}) {
30
+ return Type.Unsafe({
31
+ type: "string",
32
+ enum: checked(values, "ClosedEnum"),
33
+ ...opts
34
+ });
35
+ }
36
+ /** The known values of an authored or published open enum; undefined for anything else. */
37
+ function knownValuesOf(schema) {
38
+ if (typeof schema !== "object" || schema === null) return void 0;
39
+ const known = schema[OPEN_ENUM_KEYWORD];
40
+ return Array.isArray(known) && known.every((value) => typeof value === "string") ? known : void 0;
41
+ }
42
+ const PipelineProfile = OpenEnum([
43
+ "feature",
44
+ "bugfix",
45
+ "review"
46
+ ]);
47
+ const ACTIVE_PIPELINE_STATES = [
48
+ "BRAINSTORM",
49
+ "SPEC",
50
+ "PREFLIGHT",
51
+ "BUILD",
52
+ "TEST",
53
+ "REVIEW",
54
+ "FIX",
55
+ "SHIP"
56
+ ];
57
+ /** spec 11.1 + the two states spec 10.1 names */
58
+ const SUSPENDED_STATES = [
59
+ "PAUSED",
60
+ "WAITING_APPROVAL",
61
+ "AUTH_REQUIRED",
62
+ "QUOTA_EXCEEDED"
63
+ ];
64
+ /** FAILED: recoverable checkpoint (spec 24). BLOCKED: human inspection mandatory. */
65
+ const HALTED_STATES = ["FAILED", "BLOCKED"];
66
+ const TERMINAL_STATES = ["COMPLETED", "CANCELLED"];
67
+ const PIPELINE_STATES = [
68
+ "IDLE",
69
+ ...ACTIVE_PIPELINE_STATES,
70
+ ...SUSPENDED_STATES,
71
+ ...HALTED_STATES,
72
+ ...TERMINAL_STATES
73
+ ];
74
+ const ActivePipelineState = ClosedEnum(ACTIVE_PIPELINE_STATES);
75
+ ClosedEnum(SUSPENDED_STATES);
76
+ const HaltedState = ClosedEnum(HALTED_STATES);
77
+ ClosedEnum(TERMINAL_STATES);
78
+ const PipelineState = ClosedEnum(PIPELINE_STATES);
79
+ const TransitionReason = ClosedEnum([
80
+ "start",
81
+ "ready",
82
+ "built",
83
+ "tests-pass",
84
+ "tests-fail",
85
+ "review-approved",
86
+ "review-findings",
87
+ "review-delivered",
88
+ "fixed",
89
+ "shipped",
90
+ "needs-human",
91
+ "approval-resolved",
92
+ "pause-command",
93
+ "resume-command",
94
+ "cancel-command",
95
+ "retry-command",
96
+ "skip-command",
97
+ "auth-required",
98
+ "auth-restored",
99
+ "quota-exceeded",
100
+ "quota-reset",
101
+ "stop-rule",
102
+ "security-violation",
103
+ "unexpected-error"
104
+ ]);
105
+ const StopReason = ClosedEnum([
106
+ "review-clean",
107
+ "iteration-limit",
108
+ "budget-exhausted",
109
+ "timeout",
110
+ "identical-failure",
111
+ "no-progress",
112
+ "policy-violation",
113
+ "approval-required",
114
+ "unexpected-repo-change",
115
+ "runtime-incompatible",
116
+ "auth-required",
117
+ "quota-exceeded",
118
+ "paused",
119
+ "cancelled",
120
+ "agent-dead",
121
+ "unreviewed",
122
+ "internal-error",
123
+ "check-environment"
124
+ ]);
125
+ const AgentState = ClosedEnum([
126
+ "declared",
127
+ "planned",
128
+ "spawning",
129
+ "running",
130
+ "waiting",
131
+ "paused",
132
+ "completed",
133
+ "failed",
134
+ "retrying",
135
+ "escalated",
136
+ "cancelled"
137
+ ]);
138
+ const NodeStatus = ClosedEnum([
139
+ "pending",
140
+ "running",
141
+ "completed",
142
+ "failed",
143
+ "paused",
144
+ "waiting-approval",
145
+ "cancelled",
146
+ "skipped",
147
+ "blocked"
148
+ ]);
149
+ /** The eleven roles of spec 8, and `verifier`: the id is reserved, the adversarial cross-check is off in V3.0 (2.9). */
150
+ const COHORTE_ROLES = [
151
+ "discoverer",
152
+ "brainstormer",
153
+ "architect",
154
+ "spec-author",
155
+ "implementer",
156
+ "tester",
157
+ "reviewer",
158
+ "security-reviewer",
159
+ "fixer",
160
+ "release-manager",
161
+ "reconciler",
162
+ "verifier"
163
+ ];
164
+ OpenEnum(COHORTE_ROLES);
165
+ /** Closed: for data Cohorte itself authors and switches over (the escalation ladder). */
166
+ const KnownCohorteRole = ClosedEnum(COHORTE_ROLES);
167
+ const Severity = ClosedEnum([
168
+ "critical",
169
+ "major",
170
+ "minor",
171
+ "info"
172
+ ]);
173
+ const Actor = Type.Object({
174
+ kind: ClosedEnum([
175
+ "human",
176
+ "client",
177
+ "system"
178
+ ]),
179
+ id: Type.String(),
180
+ transport: OpenEnum(["cli"])
181
+ });
182
+ const GuardOutcome = Type.Object({
183
+ id: Type.String(),
184
+ ok: Type.Boolean(),
185
+ detail: Type.Optional(Type.String())
186
+ });
187
+ const StopRecord = Type.Object({
188
+ reason: StopReason,
189
+ detail: Type.String(),
190
+ resumable: Type.Boolean(),
191
+ resumeRequires: Type.Optional(OpenEnum([
192
+ "approval",
193
+ "auth-login",
194
+ "quota-reset",
195
+ "budget-raise",
196
+ "human-ack",
197
+ "repo-repair",
198
+ "reinstall-pinned-version",
199
+ "environment-repair"
200
+ ]))
201
+ });
202
+ const EscalationStep = Type.Union([
203
+ Type.Object({
204
+ kind: Type.Literal("model-tier"),
205
+ role: KnownCohorteRole,
206
+ from: ModelCapability,
207
+ to: ModelCapability
208
+ }),
209
+ Type.Object({
210
+ kind: Type.Literal("role"),
211
+ from: KnownCohorteRole,
212
+ to: KnownCohorteRole
213
+ }),
214
+ Type.Object({ kind: Type.Literal("human") })
215
+ ]);
216
+ /** Data: used by config AND by `escalation.applied`. Defaults: sameFailureCount 2, maxPerRun 2. */
217
+ const EscalationPolicy = Type.Object({
218
+ sameFailureCount: Type.Integer({ minimum: 1 }),
219
+ ladder: Type.Array(EscalationStep),
220
+ maxPerRun: Type.Integer({ minimum: 0 })
221
+ });
222
+ /**
223
+ * DESIGN 2.3.3. Declared HERE and re-exported by refs.ts: CheckResult needs it, and refs.ts needs the states and the
224
+ * profile of this file. Schemas are values, so an import cycle between the two files would read a const before it is set.
225
+ */
226
+ const ArtifactRef = Type.Object({
227
+ artifactId: ArtifactId,
228
+ kind: OpenEnum([
229
+ "diff",
230
+ "file",
231
+ "log",
232
+ "report",
233
+ "agent-output",
234
+ "transcript",
235
+ "context",
236
+ "prompt",
237
+ "patch"
238
+ ]),
239
+ path: Type.String(),
240
+ sha256: Sha256,
241
+ bytes: Type.Integer({ minimum: 0 })
242
+ });
243
+ const CheckResult = Type.Object({
244
+ name: Type.String(),
245
+ status: ClosedEnum([
246
+ "passed",
247
+ "failed",
248
+ "errored",
249
+ "skipped"
250
+ ]),
251
+ argv: Type.Array(Type.String()),
252
+ exitCode: Type.Optional(Type.Integer()),
253
+ durationMs: Type.Number({ minimum: 0 }),
254
+ treeDigest: Type.String(),
255
+ output: Type.Optional(ArtifactRef)
256
+ });
257
+ //#endregion
258
+ //#region ../../packages/protocol/src/agent-output.ts
259
+ const AGENT_OUTPUT_MAX_SUMMARY = 2e3;
260
+ const confidence = () => Type.Number({
261
+ minimum: 0,
262
+ maximum: 1
263
+ });
264
+ const lineNumber = () => Type.Integer({ minimum: 1 });
265
+ const Finding = Type.Object({
266
+ /** assigned by Cohorte */
267
+ id: Type.Optional(FindingId),
268
+ severity: Severity,
269
+ kind: ClosedEnum([
270
+ "spec-violation",
271
+ "security",
272
+ "quality",
273
+ "complexity",
274
+ "check-failure"
275
+ ]),
276
+ rule: Type.String(),
277
+ location: Type.Optional(Type.Object({
278
+ file: Type.String(),
279
+ line: Type.Optional(lineNumber()),
280
+ endLine: Type.Optional(lineNumber()),
281
+ symbol: Type.Optional(Type.String())
282
+ })),
283
+ reproduction: Type.Optional(Type.String()),
284
+ expected: Type.String(),
285
+ actual: Type.String(),
286
+ confidence: confidence(),
287
+ suggestedFix: Type.Optional(Type.String()),
288
+ scope: ClosedEnum(["in-scope", "deferred"]),
289
+ outOfScopeReason: Type.Optional(Type.String())
290
+ });
291
+ const AgentOutput = Type.Object({
292
+ status: ClosedEnum([
293
+ "completed",
294
+ "failed",
295
+ "blocked",
296
+ "needs-input"
297
+ ]),
298
+ summary: Type.String({ maxLength: AGENT_OUTPUT_MAX_SUMMARY }),
299
+ artifacts: Type.Array(Type.Object({
300
+ path: Type.String(),
301
+ kind: ClosedEnum([
302
+ "diff",
303
+ "file",
304
+ "test",
305
+ "report",
306
+ "contract"
307
+ ]),
308
+ /** ignored; Cohorte recomputes. A plain string on purpose: a wrong digest from a model must not fail its output. */
309
+ sha256: Type.Optional(Type.String())
310
+ })),
311
+ findings: Type.Array(Finding, { maxItems: 30 }),
312
+ /** claims; TEST is the truth */
313
+ checks: Type.Array(Type.Object({
314
+ name: Type.String(),
315
+ status: ClosedEnum([
316
+ "passed",
317
+ "failed",
318
+ "skipped",
319
+ "not-run"
320
+ ]),
321
+ command: Type.Optional(Type.String())
322
+ })),
323
+ questions: Type.Array(Type.String()),
324
+ confidence: confidence(),
325
+ assumptions: Type.Optional(Type.Array(Type.Object({
326
+ gap: Type.String(),
327
+ decision: Type.String()
328
+ }))),
329
+ remediationAddressed: Type.Optional(Type.Array(Type.Object({
330
+ findingId: Type.String(),
331
+ how: Type.String()
332
+ })))
333
+ });
334
+ const count$4 = () => Type.Integer({ minimum: 0 });
335
+ /** Computed by core, never read from a model (2.9 rule 5). */
336
+ const ReviewResult = Type.Object({
337
+ verdict: ClosedEnum([
338
+ "approved",
339
+ "findings",
340
+ "needs-human"
341
+ ]),
342
+ kept: Type.Array(Finding),
343
+ refuted: Type.Array(Finding),
344
+ deferred: Type.Array(Finding),
345
+ needsInvestigation: Type.Array(Finding),
346
+ blocking: count$4(),
347
+ blockingItems: Type.Array(Type.String()),
348
+ /** sha256(items)[0:16]; '' when there is nothing to fix */
349
+ fingerprint: Type.String({ pattern: "^(?:[0-9a-f]{16})?$" }),
350
+ unreviewed: Type.Array(SurfaceId),
351
+ clean: Type.Boolean(),
352
+ counts: Type.Object({
353
+ critical: count$4(),
354
+ major: count$4(),
355
+ minor: count$4(),
356
+ info: count$4()
357
+ })
358
+ });
359
+ //#endregion
360
+ //#region ../../packages/protocol/src/refs.ts
361
+ const count$3 = () => Type.Integer({ minimum: 0 });
362
+ const PhaseRef = Type.Object({
363
+ phaseRunId: PhaseRunId,
364
+ state: ActivePipelineState,
365
+ iteration: count$3()
366
+ });
367
+ /** `role` is a plain string here (DESIGN 2.3.3): a reader must be able to show an agent whose role it does not know. */
368
+ const AgentRef = Type.Object({
369
+ agentId: AgentId,
370
+ role: Type.String(),
371
+ surface: Type.Optional(SurfaceId),
372
+ incarnation: count$3(),
373
+ attempt: count$3()
374
+ });
375
+ /** R8: optional wherever it appears, and opaque. A client never needs it. */
376
+ const RuntimeRef = Type.Object({
377
+ runtime: Type.String(),
378
+ version: Type.String(),
379
+ sessionId: Type.String(),
380
+ transcriptRef: Type.String()
381
+ });
382
+ const FileTouch = Type.Object({
383
+ /** worktree-relative, POSIX */
384
+ path: Type.String(),
385
+ op: ClosedEnum([
386
+ "read",
387
+ "create",
388
+ "modify",
389
+ "delete"
390
+ ]),
391
+ beforeSha256: Type.Optional(Sha256),
392
+ afterSha256: Type.Optional(Sha256),
393
+ bytes: Type.Optional(count$3())
394
+ });
395
+ const SandboxReport = Type.Object({
396
+ level: OpenEnum(["L0-process", "L1-os"]),
397
+ backend: OpenEnum([
398
+ "none",
399
+ "seatbelt",
400
+ "bubblewrap"
401
+ ]),
402
+ filesystem: OpenEnum([
403
+ "enforced",
404
+ "partial",
405
+ "advisory"
406
+ ]),
407
+ network: OpenEnum([
408
+ "enforced-off",
409
+ "partial",
410
+ "unenforced"
411
+ ])
412
+ });
413
+ const RunPlan = Type.Object({
414
+ profile: PipelineProfile,
415
+ runtime: Type.Object({
416
+ id: Type.String(),
417
+ version: Type.String()
418
+ }),
419
+ /** 2.10.1: WHO consented to every security-loosening key of the project file */
420
+ trust: Type.Object({
421
+ policySha256: Sha256,
422
+ loosenedKeys: Type.Array(Type.String()),
423
+ grantedBy: OpenEnum([
424
+ "none-needed",
425
+ "user-config",
426
+ "cli-flag",
427
+ "trust-record"
428
+ ])
429
+ }),
430
+ models: Type.Array(Type.Object({
431
+ role: Type.String(),
432
+ requested: ModelRef,
433
+ thinking: ThinkingLevel,
434
+ authMode: AuthMode,
435
+ billing: ClosedEnum(["plan-limits", "metered"]),
436
+ reason: Type.String()
437
+ })),
438
+ apiBillingEnabled: Type.Boolean(),
439
+ /** non-empty => the plan printed to the human names per-token billing */
440
+ meteredProviders: Type.Array(Type.String()),
441
+ sandbox: SandboxReport,
442
+ sandboxRequire: ClosedEnum(["native", "best-effort"]),
443
+ brainIsolation: ClosedEnum(["os", "process"]),
444
+ budgets: Type.Object({
445
+ run: BudgetCounters,
446
+ perPhase: BudgetCounters,
447
+ perAgent: BudgetCounters,
448
+ perProvider: Type.Record(Type.String(), BudgetCounters),
449
+ perTool: Type.Record(Type.String(), BudgetCounters)
450
+ }),
451
+ network: Type.Object({ provisioning: Type.Boolean() }),
452
+ promptOverrides: Type.Array(Type.String()),
453
+ unattended: Type.Boolean()
454
+ });
455
+ /** R6 — everything a human needs without reading a transcript */
456
+ const ApprovalRequest = Type.Object({
457
+ approvalId: ApprovalId,
458
+ kind: OpenEnum([
459
+ "tool",
460
+ "shared-path",
461
+ "ship",
462
+ "budget",
463
+ "loop-stalled",
464
+ "contract-change",
465
+ "spec-not-ready",
466
+ "review-leftovers",
467
+ "unowned-path",
468
+ "api-billing",
469
+ "blocked-ack",
470
+ "provision-network"
471
+ ]),
472
+ agent: Type.Optional(AgentRef),
473
+ phase: Type.Optional(PhaseRef),
474
+ tool: Type.Optional(Type.String()),
475
+ /** sealed */
476
+ args: Type.Optional(JsonValueSchema),
477
+ affectedPaths: Type.Array(Type.String()),
478
+ /** sealed; agent-controlled text: clients MUST render it through the sanitiser of 2.3.6 */
479
+ preview: Type.Object({
480
+ kind: ClosedEnum([
481
+ "diff",
482
+ "command",
483
+ "text"
484
+ ]),
485
+ text: Type.String()
486
+ }),
487
+ /** only for the `approval_request` tool: the answers the agent offered; `approve.answer` must be one of them */
488
+ options: Type.Optional(Type.Array(Type.String())),
489
+ ruleId: Type.String(),
490
+ reason: Type.String(),
491
+ asks: Type.Array(Type.Object({
492
+ stage: Type.String(),
493
+ ruleId: Type.String(),
494
+ reason: Type.String()
495
+ })),
496
+ allowedDecisions: Type.Array(ClosedEnum([
497
+ "allow-once",
498
+ "allow-for-run",
499
+ "deny"
500
+ ])),
501
+ /** what the decision is bound to (4.5): the target's beforeSha256 (write/patch) or the slot's treeDigest (command) */
502
+ preStateSha256: Type.Optional(Sha256),
503
+ expiresAt: Type.Optional(IsoInstant),
504
+ unattended: ClosedEnum(["deny", "wait"]),
505
+ /** literal "cohorte approve <id>" */
506
+ cli: Type.String()
507
+ });
508
+ const ResumeReport = Type.Object({
509
+ takeover: Type.Boolean(),
510
+ hostId: Type.String(),
511
+ fencingToken: count$3(),
512
+ locks: Type.Object({
513
+ rebuilt: Type.Array(Type.String()),
514
+ conflicts: Type.Array(Type.String())
515
+ }),
516
+ orphans: Type.Array(Type.Object({
517
+ agentId: Type.Optional(AgentId),
518
+ incarnation: Type.Optional(count$3()),
519
+ pid: count$3(),
520
+ kind: ClosedEnum(["brain", "command"]),
521
+ killed: Type.Boolean()
522
+ })),
523
+ worktrees: Type.Array(Type.Object({
524
+ slot: Type.String(),
525
+ path: Type.String(),
526
+ verdict: OpenEnum([
527
+ "ok",
528
+ "re-added",
529
+ "ledger-explained",
530
+ "quarantined-reset",
531
+ "unexplained-change",
532
+ "missing-branch"
533
+ ])
534
+ })),
535
+ effects: Type.Array(Type.Object({
536
+ effectId: EffectId,
537
+ kind: Type.String(),
538
+ replayClass: ClosedEnum([
539
+ "idempotent",
540
+ "verifiable",
541
+ "at-most-once"
542
+ ]),
543
+ verdict: OpenEnum([
544
+ "done",
545
+ "failed",
546
+ "re-executed",
547
+ "in-doubt",
548
+ "compensated"
549
+ ])
550
+ })),
551
+ approvalsCarried: Type.Array(ApprovalId),
552
+ commandsApplied: Type.Array(CommandId),
553
+ inDoubt: Type.Array(EffectId),
554
+ /** 4.5 parked path */
555
+ approvedReplays: Type.Array(Type.Object({
556
+ approvalId: ApprovalId,
557
+ toolCallId: ToolCallId,
558
+ outcome: OpenEnum([
559
+ "executed",
560
+ "binding-changed",
561
+ "denied-by-gate"
562
+ ])
563
+ }))
564
+ });
565
+ const Durability = ClosedEnum(["durable", "ephemeral"]);
566
+ const EnvelopeBase = Type.Object({
567
+ protocolVersion: Type.Literal("1.0"),
568
+ eventId: EventId,
569
+ /** durable: own gapless per-run sequence (1..n). ephemeral: sequence of the last COMMITTED durable event when it is STAMPED */
570
+ sequence: Type.Integer({ minimum: 0 }),
571
+ /** durable: 0. ephemeral: 1.. after that durable sequence */
572
+ sub: Type.Integer({ minimum: 0 }),
573
+ durability: Durability,
574
+ timestamp: IsoInstant,
575
+ runId: RunId,
576
+ /** narrowed per event */
577
+ type: Type.String({ minLength: 1 }),
578
+ source: ClosedEnum([
579
+ "cohorte",
580
+ "runtime",
581
+ "client",
582
+ "human"
583
+ ]),
584
+ phase: Type.Optional(PhaseRef),
585
+ agent: Type.Optional(AgentRef),
586
+ /** eventId or commandId that caused this event */
587
+ causationId: Type.Optional(Type.String()),
588
+ /** one line, sealed; EventWriter replaces control characters by U+FFFD BEFORE validation */
589
+ summary: Type.String({
590
+ maxLength: 200,
591
+ pattern: "^[^\\u0000-\\u001f\\u007f-\\u009f]*$"
592
+ }),
593
+ severity: ClosedEnum([
594
+ "info",
595
+ "success",
596
+ "warning",
597
+ "error",
598
+ "progress"
599
+ ]),
600
+ /** narrowed per event */
601
+ payload: Type.Unknown(),
602
+ redactions: Type.Array(Redaction)
603
+ });
604
+ /** Total order of a stream. */
605
+ function compareOrder(a, b) {
606
+ return a.sequence - b.sequence || a.sub - b.sub;
607
+ }
608
+ //#endregion
609
+ //#region ../../packages/protocol/src/compile.ts
610
+ const SCHEMA_DIALECT = "https://json-schema.org/draft/2020-12/schema";
611
+ const SCHEMA_MAPS = /* @__PURE__ */ new Set([
612
+ "properties",
613
+ "patternProperties",
614
+ "$defs",
615
+ "definitions",
616
+ "dependentSchemas"
617
+ ]);
618
+ const SCHEMA_LISTS = /* @__PURE__ */ new Set([
619
+ "anyOf",
620
+ "oneOf",
621
+ "prefixItems"
622
+ ]);
623
+ const SCHEMA_SINGLES = /* @__PURE__ */ new Set([
624
+ "items",
625
+ "additionalItems",
626
+ "additionalProperties",
627
+ "unevaluatedProperties",
628
+ "unevaluatedItems",
629
+ "not",
630
+ "if",
631
+ "then",
632
+ "else",
633
+ "contains",
634
+ "propertyNames"
635
+ ]);
636
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
637
+ /** TypeBox keeps its own bookkeeping under non-enumerable or `~`-prefixed keys: a JSON round trip leaves the JSON Schema. */
638
+ const plain = (schema) => JSON.parse(JSON.stringify(schema));
639
+ /** Post-order map over every SCHEMA of a document: `post` sees a node whose sub-schemas are already mapped. */
640
+ function mapSchemas(node, post, closable = true) {
641
+ if (!isObject(node)) return node;
642
+ const out = {};
643
+ for (const [keyword, value] of Object.entries(node)) if (SCHEMA_MAPS.has(keyword) && isObject(value)) out[keyword] = Object.fromEntries(Object.entries(value).map(([name, member]) => [name, mapSchemas(member, post)]));
644
+ else if ((SCHEMA_LISTS.has(keyword) || keyword === "items") && Array.isArray(value)) out[keyword] = value.map((member) => mapSchemas(member, post));
645
+ else if (keyword === "allOf" && Array.isArray(value)) out[keyword] = value.map((member) => mapSchemas(member, post, false));
646
+ else if (SCHEMA_SINGLES.has(keyword) && isObject(value)) out[keyword] = mapSchemas(value, post);
647
+ else out[keyword] = value;
648
+ return post(out, closable);
649
+ }
650
+ function rewrite(node, mode) {
651
+ return mapSchemas(node, (out, closable) => {
652
+ if (mode === "open") {
653
+ if (out.additionalProperties === false) delete out.additionalProperties;
654
+ if (knownValuesOf(out) !== void 0) delete out.enum;
655
+ } else if (closable && isObject(out.properties) && !("additionalProperties" in out)) out.additionalProperties = false;
656
+ return out;
657
+ });
658
+ }
659
+ /**
660
+ * TypeBox inlines a `Type.Cyclic` at EVERY use as `{ $defs: { X: { $id: 'X', … } }, $ref: 'X' }`. Its own compiler
661
+ * accepts the repetition; a second implementation (ajv) refuses two schemas with one `$id` in one document, and the
662
+ * published schema exists for second implementations (AC-07). So a published DOCUMENT carries each such definition
663
+ * once, under the root `$defs`, without its `$id`, and every reference becomes a pointer. Two different definitions
664
+ * under one name are an authoring error, never merged. The result is a whole document: embed authored schemas in a
665
+ * bigger one, not published ones (their pointers are relative to the root).
666
+ */
667
+ function hoistDefinitions(document) {
668
+ const hoisted = {};
669
+ const hoist = (name, definition) => {
670
+ const { $id: _id, ...body } = definition;
671
+ const found = hoisted[name];
672
+ if (found !== void 0 && JSON.stringify(found) !== JSON.stringify(body)) throw new TypeError(`two different definitions are named ${JSON.stringify(name)} in one published schema`);
673
+ hoisted[name] = body;
674
+ };
675
+ const lifted = mapSchemas(document, (out) => {
676
+ if (!isObject(out.$defs)) return out;
677
+ const kept = {};
678
+ for (const [name, member] of Object.entries(out.$defs)) if (isObject(member) && member.$id === name) hoist(name, member);
679
+ else kept[name] = member;
680
+ if (Object.keys(kept).length > 0) out.$defs = kept;
681
+ else delete out.$defs;
682
+ return out;
683
+ });
684
+ if (!isObject(lifted) || Object.keys(hoisted).length === 0) return lifted;
685
+ const own = isObject(lifted.$defs) ? lifted.$defs : {};
686
+ for (const name of Object.keys(hoisted)) if (name in own) throw new TypeError(`two different definitions are named ${JSON.stringify(name)} in one published schema`);
687
+ return mapSchemas({
688
+ ...lifted,
689
+ $defs: {
690
+ ...own,
691
+ ...hoisted
692
+ }
693
+ }, (out) => {
694
+ if (typeof out.$ref === "string" && Object.hasOwn(hoisted, out.$ref)) out.$ref = `#/$defs/${out.$ref}`;
695
+ return out;
696
+ });
697
+ }
698
+ /** Writer side. Closes every object that declares `properties`, whether or not its author remembered to. */
699
+ function toStrictSchema(schema) {
700
+ return rewrite(plain(schema), "strict");
701
+ }
702
+ function validatorOf(jsonSchema) {
703
+ const compiled = Compile(jsonSchema);
704
+ return (value) => {
705
+ if (compiled.Check(value)) return ok(value);
706
+ const issues = [];
707
+ for (const issue of compiled.Errors(value)) issues.push({
708
+ path: issue.instancePath,
709
+ keyword: issue.keyword,
710
+ message: issue.message
711
+ });
712
+ return err(issues);
713
+ };
714
+ }
715
+ const strictCache = /* @__PURE__ */ new WeakMap();
716
+ /** The STRICT validator of any authored schema: commands, documents, agent output. Compiled once per schema object. */
717
+ function compileSchema(schema) {
718
+ let found = strictCache.get(schema);
719
+ if (!found) {
720
+ found = validatorOf(toStrictSchema(schema));
721
+ strictCache.set(schema, found);
722
+ }
723
+ return found;
724
+ }
725
+ const rowOf = (events, type) => {
726
+ if (!Object.hasOwn(events, type)) throw new RangeError(`no event type ${JSON.stringify(type)} in this catalogue`);
727
+ return events[type];
728
+ };
729
+ /** Writer side: the payload of one event type, unknown keys rejected. Generic over the table, so a catalogue only adds rows. */
730
+ function compileStrict(events, type) {
731
+ return compileSchema(rowOf(events, type).payload);
732
+ }
733
+ /**
734
+ * The properties that make a base envelope the envelope of ONE row: the discriminant, the narrowed body and whatever
735
+ * the row pins (an event pins its durability). Shared by the strict and the open form, so the two cannot disagree.
736
+ */
737
+ function narrowed(base, discriminant, type, body, bodySchema, pinned) {
738
+ if (!isObject(base) || !isObject(base.properties)) throw new TypeError("an envelope schema must be an object schema");
739
+ const properties = {
740
+ ...base.properties,
741
+ [discriminant]: { const: type },
742
+ [body]: bodySchema
743
+ };
744
+ for (const [name, value] of Object.entries(pinned)) properties[name] = { const: value };
745
+ return {
746
+ ...base,
747
+ properties
748
+ };
749
+ }
750
+ const envelopeCache = /* @__PURE__ */ new WeakMap();
751
+ /** Writer side: the WHOLE envelope of one event type — closed, its `type` and its durability pinned by the table. */
752
+ function compileStrictEnvelope(events, type) {
753
+ const row = rowOf(events, type);
754
+ let perTable = envelopeCache.get(events);
755
+ if (!perTable) {
756
+ perTable = /* @__PURE__ */ new Map();
757
+ envelopeCache.set(events, perTable);
758
+ }
759
+ let found = perTable.get(type);
760
+ if (!found) {
761
+ found = validatorOf(narrowed(toStrictSchema(EnvelopeBase), "type", type, "payload", toStrictSchema(row.payload), { durability: row.durability }));
762
+ perTable.set(type, found);
763
+ }
764
+ return found;
765
+ }
766
+ /**
767
+ * The published form of a table of types: the open base envelope, then a `oneOf` with one branch per KNOWN type and a
768
+ * catch-all branch for the types of a later minor. Exactly one branch matches any envelope, because the base requires
769
+ * the discriminant. Used for events here and for commands in commands.ts.
770
+ */
771
+ function toOpenTableSchema(options) {
772
+ const base = rewrite(plain(options.base), "open");
773
+ if (!isObject(base)) throw new TypeError("an envelope schema must be an object schema");
774
+ const known = options.rows.map((row) => row.type);
775
+ const branches = options.rows.map((row) => {
776
+ const branch = narrowed({ properties: {} }, options.discriminant, row.type, options.body, rewrite(plain(row.body), "open"), row.pinned ?? {});
777
+ return {
778
+ title: row.type,
779
+ ...branch
780
+ };
781
+ });
782
+ branches.push({
783
+ title: "a type added by a later minor version: readers MUST ignore it",
784
+ properties: { [options.discriminant]: { not: { enum: known } } }
785
+ });
786
+ return hoistDefinitions({
787
+ $schema: SCHEMA_DIALECT,
788
+ $id: options.$id,
789
+ title: options.title,
790
+ ...base,
791
+ oneOf: branches
792
+ });
793
+ }
794
+ /** Generator side of DESIGN 2.3.2, over any events table. */
795
+ function toOpenJsonSchema(events, options = {}) {
796
+ return toOpenTableSchema({
797
+ $id: options.$id ?? "https://cohorte.dev/schemas/3/events.schema.json",
798
+ title: options.title ?? "Cohorte Protocol event envelope",
799
+ base: EnvelopeBase,
800
+ discriminant: "type",
801
+ body: "payload",
802
+ rows: Object.entries(events).map(([type, row]) => ({
803
+ type,
804
+ body: row.payload,
805
+ pinned: { durability: row.durability }
806
+ }))
807
+ });
808
+ }
809
+ /** The exact signatures of DESIGN 2.3.2, bound to one table: `bindCatalogue(EVENTS)` is all a catalogue has to write. */
810
+ function bindCatalogue(events) {
811
+ return {
812
+ compileStrict: (type) => compileStrict(events, type),
813
+ compileStrictEnvelope: (type) => compileStrictEnvelope(events, type),
814
+ toOpenJsonSchema: () => toOpenJsonSchema(events)
815
+ };
816
+ }
817
+ //#endregion
818
+ //#region ../../packages/protocol/src/events/declare.ts
819
+ const durable = (payload) => ({
820
+ payload,
821
+ durability: "durable"
822
+ });
823
+ const ephemeral = (payload) => ({
824
+ payload,
825
+ durability: "ephemeral"
826
+ });
827
+ const count$2 = () => Type.Integer({ minimum: 0 });
828
+ const milliseconds = () => Type.Number({ minimum: 0 });
829
+ /** `{ ref; sha; treeDigest }`: what a review looked at, and what an approval of it is bound to. */
830
+ const ReviewRef = Type.Object({
831
+ ref: Type.String(),
832
+ sha: Type.String(),
833
+ treeDigest: Type.String()
834
+ });
835
+ const REPLAY_CLASSES = [
836
+ "idempotent",
837
+ "verifiable",
838
+ "at-most-once"
839
+ ];
840
+ //#endregion
841
+ //#region ../../packages/protocol/src/events/agent.ts
842
+ const AGENT_STATE_CHANGE_REASONS = [
843
+ "planned",
844
+ "spawned",
845
+ "tool-wait",
846
+ "approval-wait",
847
+ "quota-wait",
848
+ "peer-wait",
849
+ "paused",
850
+ "resumed",
851
+ "completed",
852
+ "failed",
853
+ "cancelled",
854
+ "retry",
855
+ "escalation",
856
+ "recovery",
857
+ "park",
858
+ "pause-expiry"
859
+ ];
860
+ const MESSAGE_ROLES = [
861
+ "assistant",
862
+ "user",
863
+ "tool-result"
864
+ ];
865
+ const MESSAGE_CHANNELS = [
866
+ "text",
867
+ "thinking",
868
+ "tool-input"
869
+ ];
870
+ const MESSAGE_STOPS = [
871
+ "stop",
872
+ "length",
873
+ "tool-use",
874
+ "error",
875
+ "aborted"
876
+ ];
877
+ const MESSAGE_DELIVERIES = ["steer", "follow-up"];
878
+ const MESSAGE_DELTA_MAX_LENGTH = 8192;
879
+ /**
880
+ * R9. The shapes of the context manifest (DESIGN 2.2.4), declared here a second time: protocol imports no other
881
+ * package than base (C4). Exported because `inspect { kind: 'context' }` returns this payload as it is.
882
+ */
883
+ const ContextBuiltPayload = Type.Object({
884
+ agent: AgentRef,
885
+ manifestSha256: Sha256,
886
+ tokenEstimate: count$2(),
887
+ tokenLimit: count$2(),
888
+ entries: Type.Array(Type.Object({
889
+ id: Type.String(),
890
+ tier: ClosedEnum([
891
+ "system",
892
+ "doctrine",
893
+ "data",
894
+ "task",
895
+ "prior-results"
896
+ ]),
897
+ trust: ClosedEnum([
898
+ "cohorte",
899
+ "human",
900
+ "untrusted-repository",
901
+ "agent-output"
902
+ ]),
903
+ source: Type.Object({
904
+ kind: ClosedEnum([
905
+ "asset",
906
+ "project-file",
907
+ "artifact",
908
+ "event-summary",
909
+ "inline"
910
+ ]),
911
+ ref: Type.String()
912
+ }),
913
+ sha256: Sha256,
914
+ bytes: count$2(),
915
+ tokenEstimate: count$2()
916
+ })),
917
+ reductions: Type.Array(Type.Object({
918
+ entryId: Type.String(),
919
+ strategy: ClosedEnum([
920
+ "excerpt",
921
+ "outline",
922
+ "summary-with-refs",
923
+ "dropped"
924
+ ]),
925
+ fromBytes: count$2(),
926
+ toBytes: count$2()
927
+ })),
928
+ exclusions: Type.Array(Type.Object({
929
+ pattern: Type.String(),
930
+ reason: ClosedEnum([
931
+ "secret",
932
+ "outside-scope",
933
+ "size",
934
+ "binary"
935
+ ])
936
+ })),
937
+ manifest: ArtifactRef
938
+ });
939
+ const AGENT_EVENTS = {
940
+ "agent.declared": durable(Type.Object({
941
+ agent: AgentRef,
942
+ parentAgentId: Type.Optional(AgentId),
943
+ owner: Type.String(),
944
+ ownedPaths: Type.Array(Type.String()),
945
+ grantsDigest: Sha256,
946
+ requestedModel: ModelRef,
947
+ thinking: ThinkingLevel,
948
+ routingReason: Type.String(),
949
+ budget: BudgetCounters
950
+ })),
951
+ "agent.spawned": durable(Type.Object({
952
+ agent: AgentRef,
953
+ worktree: Type.Optional(Type.Object({
954
+ slot: Type.String(),
955
+ path: Type.String(),
956
+ branch: Type.String(),
957
+ baseSha: Type.String()
958
+ })),
959
+ tools: Type.Array(Type.String()),
960
+ systemPromptSha256: Sha256,
961
+ effectiveSystemPromptSha256: Sha256,
962
+ authMode: AuthMode,
963
+ isolation: SandboxReport,
964
+ runtimeRef: Type.Optional(RuntimeRef)
965
+ })),
966
+ "agent.started": durable(Type.Object({
967
+ agent: AgentRef,
968
+ taskSha256: Sha256
969
+ })),
970
+ "agent.state.changed": durable(Type.Object({
971
+ agent: AgentRef,
972
+ from: AgentState,
973
+ to: AgentState,
974
+ reason: OpenEnum(AGENT_STATE_CHANGE_REASONS),
975
+ pausedAt: Type.Optional(ClosedEnum(["tool-boundary", "model-boundary"])),
976
+ attemptConsumed: Type.Boolean()
977
+ })),
978
+ "agent.completed": durable(Type.Object({
979
+ agent: AgentRef,
980
+ status: AgentOutput.properties.status,
981
+ summary: Type.String(),
982
+ confidence: Type.Number({
983
+ minimum: 0,
984
+ maximum: 1
985
+ }),
986
+ output: ArtifactRef,
987
+ artifacts: Type.Array(ArtifactRef),
988
+ findings: count$2(),
989
+ questions: Type.Array(Type.String()),
990
+ usage: BudgetCounters
991
+ })),
992
+ "agent.failed": durable(Type.Object({
993
+ agent: AgentRef,
994
+ error: ErrorInfo,
995
+ willRetry: Type.Boolean(),
996
+ nextIncarnation: Type.Optional(count$2())
997
+ })),
998
+ "agent.turn.started": ephemeral(Type.Object({ turn: count$2() })),
999
+ "agent.turn.completed": durable(Type.Object({
1000
+ turn: count$2(),
1001
+ toolCalls: count$2()
1002
+ })),
1003
+ /** R1 */
1004
+ "agent.message.started": ephemeral(Type.Object({
1005
+ messageId: Type.String(),
1006
+ role: ClosedEnum(MESSAGE_ROLES)
1007
+ })),
1008
+ "agent.message.delta": ephemeral(Type.Object({
1009
+ messageId: Type.String(),
1010
+ channel: ClosedEnum(MESSAGE_CHANNELS),
1011
+ contentIndex: count$2(),
1012
+ delta: Type.String({ maxLength: MESSAGE_DELTA_MAX_LENGTH })
1013
+ })),
1014
+ "agent.message.completed": durable(Type.Object({
1015
+ messageId: Type.String(),
1016
+ role: ClosedEnum(MESSAGE_ROLES),
1017
+ preview: Type.String({ maxLength: 512 }),
1018
+ textSha256: Sha256,
1019
+ bytes: count$2(),
1020
+ stop: Type.Optional(ClosedEnum(MESSAGE_STOPS))
1021
+ })),
1022
+ /** the runtime took a `send` (host note, nudge, or `agent.send`) into its queue */
1023
+ "agent.message.accepted": durable(Type.Object({
1024
+ agent: AgentRef,
1025
+ messageId: Type.String(),
1026
+ delivery: ClosedEnum(MESSAGE_DELIVERIES)
1027
+ })),
1028
+ /** non-fatal runtime diagnostics (unmapped stop reason, stale auth snapshot, degraded capability); `message` is sealed */
1029
+ "runtime.warning": durable(Type.Object({
1030
+ agent: Type.Optional(AgentRef),
1031
+ code: Type.String(),
1032
+ message: Type.String()
1033
+ })),
1034
+ "model.requested": durable(Type.Object({
1035
+ requestId: Type.String(),
1036
+ model: ModelRef,
1037
+ expectedAuthMode: AuthMode,
1038
+ contextSha256: Type.Optional(Sha256),
1039
+ attempt: count$2()
1040
+ })),
1041
+ "model.responded": durable(Type.Object({
1042
+ requestId: Type.String(),
1043
+ requestedModel: ModelRef,
1044
+ effectiveModel: Type.Object({
1045
+ provider: Type.String(),
1046
+ model: Type.String(),
1047
+ api: Type.Optional(Type.String()),
1048
+ baseUrl: Type.Optional(Type.String())
1049
+ }),
1050
+ authMode: AuthMode,
1051
+ authSource: ClosedEnum([
1052
+ "oauth",
1053
+ "api-key",
1054
+ "none"
1055
+ ]),
1056
+ status: ClosedEnum(["ok", "error"]),
1057
+ httpStatus: Type.Optional(Type.Integer({
1058
+ minimum: 100,
1059
+ maximum: 599
1060
+ })),
1061
+ durationMs: milliseconds(),
1062
+ tokens: TokenUsage,
1063
+ monetaryCost: MonetaryCost,
1064
+ quota: QuotaInfo,
1065
+ attempt: count$2(),
1066
+ error: Type.Optional(ErrorInfo)
1067
+ })),
1068
+ "context.built": durable(ContextBuiltPayload),
1069
+ "escalation.applied": durable(Type.Object({
1070
+ agent: AgentRef,
1071
+ step: EscalationStep,
1072
+ because: Type.String()
1073
+ }))
1074
+ };
1075
+ const Lock = Type.Object({
1076
+ scope: ClosedEnum([
1077
+ "project",
1078
+ "zone",
1079
+ "run",
1080
+ "integration",
1081
+ "slot"
1082
+ ]),
1083
+ key: Type.String(),
1084
+ mode: ClosedEnum(["shared", "exclusive"]),
1085
+ owner: Type.String(),
1086
+ fencingToken: Type.Optional(count$2())
1087
+ });
1088
+ const GIT_EVENTS = {
1089
+ "git.worktree.created": durable(Type.Object({
1090
+ slot: Type.String(),
1091
+ path: Type.String(),
1092
+ branch: Type.String(),
1093
+ baseSha: Type.String(),
1094
+ effectId: EffectId
1095
+ })),
1096
+ "git.worktree.provisioned": durable(Type.Object({
1097
+ slot: Type.String(),
1098
+ lockfileSha256: Sha256,
1099
+ network: Type.Boolean(),
1100
+ effectId: EffectId
1101
+ })),
1102
+ "git.worktree.quarantined": durable(Type.Object({
1103
+ slot: Type.String(),
1104
+ resetTo: Type.String(),
1105
+ patch: ArtifactRef,
1106
+ compensated: Type.Array(EffectId)
1107
+ })),
1108
+ "git.worktree.removed": durable(Type.Object({
1109
+ slot: Type.String(),
1110
+ path: Type.String()
1111
+ })),
1112
+ "git.commit.created": durable(Type.Object({
1113
+ slot: Type.String(),
1114
+ branch: Type.String(),
1115
+ sha: Type.String(),
1116
+ kind: ClosedEnum(["result", "checkpoint"]),
1117
+ treeDigest: Type.String(),
1118
+ paths: Type.Array(Type.String()),
1119
+ effectId: EffectId
1120
+ })),
1121
+ "git.merge.completed": durable(Type.Object({
1122
+ from: Type.String(),
1123
+ into: Type.String(),
1124
+ mergeSha: Type.String(),
1125
+ treeDigest: Type.String(),
1126
+ effectId: EffectId
1127
+ })),
1128
+ "git.merge.conflicted": durable(Type.Object({
1129
+ from: Type.String(),
1130
+ into: Type.String(),
1131
+ files: Type.Array(Type.String())
1132
+ })),
1133
+ "repo.change.detected": durable(Type.Object({
1134
+ slot: Type.String(),
1135
+ expected: Type.String(),
1136
+ actual: Type.String(),
1137
+ files: Type.Array(FileTouch)
1138
+ })),
1139
+ "lock.acquired": durable(Lock),
1140
+ "lock.released": durable(Lock),
1141
+ "lock.stolen": durable(Lock)
1142
+ };
1143
+ //#endregion
1144
+ //#region ../../packages/protocol/src/commands.ts
1145
+ /** `inspect { kind: 'artifact' }`: default 1 MiB, cap 3 MiB, so the document stays under a 4 MiB one-shot client. */
1146
+ const INSPECT_ARTIFACT_DEFAULT_BYTES = 1048576;
1147
+ const INSPECT_ARTIFACT_MAX_BYTES = 3145728;
1148
+ const count$1 = () => Type.Integer({ minimum: 0 });
1149
+ const COMMAND_AUTH_SCHEMES = ["hmac-sha256"];
1150
+ /**
1151
+ * Scheme-neutral, so an asymmetric signature (ADR-0022 "Revisit") is a MINOR. V3.0: value = hex
1152
+ * HMAC-SHA256(projectKey, canonicalCommandBody(envelope)). An unknown scheme VALIDATES under the open schema:
1153
+ * refusing it (`security/command-auth-invalid`) is the host's job, not the parser's.
1154
+ */
1155
+ const CommandAuth = Type.Object({
1156
+ scheme: OpenEnum(COMMAND_AUTH_SCHEMES),
1157
+ value: Type.String({ minLength: 1 })
1158
+ });
1159
+ const StartPayload = Type.Object({
1160
+ profile: PipelineProfile,
1161
+ spec: Type.Optional(Type.Union([Type.Object({ id: SpecId }), Type.Object({ path: Type.String() })])),
1162
+ reviewTarget: Type.Optional(Type.Union([
1163
+ Type.Object({ ref: Type.String() }),
1164
+ Type.Object({
1165
+ base: Type.String(),
1166
+ head: Type.String()
1167
+ }),
1168
+ Type.Object({ runId: RunId })
1169
+ ])),
1170
+ withFix: Type.Optional(Type.Boolean()),
1171
+ phases: Type.Optional(Type.Array(ActivePipelineState)),
1172
+ /** keyed by role */
1173
+ modelOverrides: Type.Optional(Type.Record(Type.String(), ModelRef)),
1174
+ runtime: Type.Optional(Type.String()),
1175
+ fakeScript: Type.Optional(Type.String()),
1176
+ unattended: Type.Boolean(),
1177
+ budgets: Type.Optional(BudgetCounters),
1178
+ sandboxRequire: Type.Optional(ClosedEnum(["native", "best-effort"])),
1179
+ /** 2.10.1: `--trust-project-config` travels in the SIGNED start command, so the host's re-check sees the consent the CLI saw */
1180
+ consent: Type.Optional(Type.Object({
1181
+ policySha256: Sha256,
1182
+ via: Type.Literal("cli-flag")
1183
+ }))
1184
+ });
1185
+ const InspectPayload = Type.Object({ target: Type.Union([
1186
+ Type.Object({
1187
+ kind: Type.Literal("agent"),
1188
+ agentId: AgentId
1189
+ }),
1190
+ Type.Object({
1191
+ kind: Type.Literal("context"),
1192
+ agentId: AgentId,
1193
+ incarnation: count$1()
1194
+ }),
1195
+ Type.Object({
1196
+ kind: Type.Literal("approval"),
1197
+ approvalId: ApprovalId
1198
+ }),
1199
+ Type.Object({
1200
+ kind: Type.Literal("effect"),
1201
+ effectId: EffectId
1202
+ }),
1203
+ Type.Object({ kind: Type.Literal("snapshot") }),
1204
+ Type.Object({ kind: Type.Literal("locks") }),
1205
+ Type.Object({
1206
+ kind: Type.Literal("diff"),
1207
+ surface: Type.Optional(SurfaceId)
1208
+ }),
1209
+ Type.Object({
1210
+ kind: Type.Literal("artifact"),
1211
+ artifactId: ArtifactId,
1212
+ maxBytes: Type.Optional(Type.Integer({
1213
+ minimum: 1,
1214
+ maximum: INSPECT_ARTIFACT_MAX_BYTES,
1215
+ default: INSPECT_ARTIFACT_DEFAULT_BYTES
1216
+ })),
1217
+ offset: Type.Optional(count$1())
1218
+ })
1219
+ ]) });
1220
+ const reader = (payload, route) => ({
1221
+ payload,
1222
+ route,
1223
+ authenticated: false,
1224
+ emitsResultEvent: false
1225
+ });
1226
+ const mutating = (payload, route) => ({
1227
+ payload,
1228
+ route: route ?? "inbox",
1229
+ authenticated: true,
1230
+ emitsResultEvent: true
1231
+ });
1232
+ const COMMANDS = {
1233
+ start: mutating(StartPayload, "start"),
1234
+ /** no runId => ProjectStatusDocument (R4 "current pipeline") */
1235
+ status: reader(Type.Object({ runId: Type.Optional(RunId) }), "direct-read"),
1236
+ inspect: reader(InspectPayload, "direct-read"),
1237
+ tail: reader(Type.Object({
1238
+ sinceSequence: Type.Optional(count$1()),
1239
+ replay: Type.Optional(count$1()),
1240
+ follow: Type.Boolean(),
1241
+ ephemeral: Type.Boolean()
1242
+ }), "direct-read"),
1243
+ pause: mutating(Type.Object({ reason: Type.Optional(Type.String()) })),
1244
+ resume: mutating(Type.Object({
1245
+ acknowledge: Type.Optional(Type.Literal("blocked-inspected")),
1246
+ raiseBudgets: Type.Optional(BudgetCounters),
1247
+ takeover: Type.Optional(Type.Boolean())
1248
+ })),
1249
+ cancel: mutating(Type.Object({
1250
+ reason: Type.Optional(Type.String()),
1251
+ keepWorktrees: Type.Boolean()
1252
+ })),
1253
+ approve: mutating(Type.Object({
1254
+ approvalId: ApprovalId,
1255
+ scope: ClosedEnum(["once", "run"]),
1256
+ /** required when the request carries `options`; must be one of them; echoed in the tool result */
1257
+ answer: Type.Optional(Type.String()),
1258
+ note: Type.Optional(Type.String())
1259
+ })),
1260
+ deny: mutating(Type.Object({
1261
+ approvalId: ApprovalId,
1262
+ note: Type.Optional(Type.String())
1263
+ })),
1264
+ retry: mutating(Type.Object({ target: Type.Union([Type.Object({
1265
+ kind: Type.Literal("phase"),
1266
+ state: Type.Optional(ActivePipelineState)
1267
+ }), Type.Object({
1268
+ kind: Type.Literal("agent"),
1269
+ agentId: AgentId
1270
+ })]) })),
1271
+ /** only if policy.skip lists that phase */
1272
+ skip: mutating(Type.Object({
1273
+ phase: ActivePipelineState,
1274
+ justification: Type.String({ minLength: 1 })
1275
+ })),
1276
+ /** admin; rejected unless policy.admin.runTool; still goes through the full gate chain */
1277
+ "run-tool": mutating(Type.Object({
1278
+ agentId: Type.Optional(AgentId),
1279
+ tool: Type.String({ minLength: 1 }),
1280
+ input: JsonValueSchema,
1281
+ justification: Type.String({ minLength: 1 })
1282
+ })),
1283
+ /** V3.0: 'plan' only */
1284
+ reconcile: reader(Type.Object({ mode: ClosedEnum(["plan", "apply"]) }), "cli-local"),
1285
+ shutdown: mutating(Type.Object({ graceMs: count$1() })),
1286
+ /** R11: optional, policy.steer.enabled, default false */
1287
+ "agent.send": mutating(Type.Object({
1288
+ agentId: AgentId,
1289
+ text: Type.String(),
1290
+ delivery: ClosedEnum(["steer", "follow-up"])
1291
+ }))
1292
+ };
1293
+ const COMMAND_TYPES = Object.keys(COMMANDS);
1294
+ Type.Object({
1295
+ protocolVersion: Type.Literal("1.0"),
1296
+ /** client-generated; THE idempotency key. Same id + same body = same outcome; same id + other body = conflict/command-id-reuse */
1297
+ commandId: CommandId,
1298
+ /** narrowed per command */
1299
+ type: Type.String({ minLength: 1 }),
1300
+ runId: Type.Optional(RunId),
1301
+ issuedAt: IsoInstant,
1302
+ actor: Actor,
1303
+ /** optimistic guard: reject if the run moved past this sequence */
1304
+ expectedSequence: Type.Optional(count$1()),
1305
+ /** narrowed per command */
1306
+ payload: Type.Unknown(),
1307
+ auth: Type.Optional(CommandAuth)
1308
+ });
1309
+ /**
1310
+ * The envelope MINUS `auth`, as canonical JSON: exactly what the authenticator covers, and the only thing `security`
1311
+ * ever sees of a command (it signs bytes, not envelopes). Key order never matters; every other field does.
1312
+ */
1313
+ function canonicalCommandBody(envelope) {
1314
+ const { auth: _auth, ...body } = envelope;
1315
+ return canonicalJson(body);
1316
+ }
1317
+ /** Controller exit codes. 4 is not an error: the inbox is durable, the command is accepted but still pending at `--wait` expiry. */
1318
+ const CONTROLLER_EXIT_CODES = {
1319
+ completed: 0,
1320
+ usage: 2,
1321
+ rejected: 3,
1322
+ pending: 4
1323
+ };
1324
+ //#endregion
1325
+ //#region ../../packages/protocol/src/events/governance.ts
1326
+ const APPROVAL_DECISIONS = [
1327
+ "allow-once",
1328
+ "allow-for-run",
1329
+ "deny",
1330
+ "expired",
1331
+ "superseded"
1332
+ ];
1333
+ const BUDGET_LEVELS = [
1334
+ "run",
1335
+ "phase",
1336
+ "agent",
1337
+ "provider",
1338
+ "tool"
1339
+ ];
1340
+ const BUDGET_THRESHOLDS = [
1341
+ 50,
1342
+ 80,
1343
+ 100
1344
+ ];
1345
+ const BUDGET_COUNTER_NAMES = [
1346
+ "tokens",
1347
+ "modelRequests",
1348
+ "toolCalls",
1349
+ "wallClockMs",
1350
+ "retries",
1351
+ "fixRounds",
1352
+ "contextTokens",
1353
+ "concurrentAgents",
1354
+ "estimatedQuotaPercent"
1355
+ ];
1356
+ const AUTH_REQUIRED_CAUSES = [
1357
+ "absent",
1358
+ "expired",
1359
+ "refresh-failed",
1360
+ "revoked",
1361
+ "entitlement",
1362
+ "mode-mismatch",
1363
+ "ambient-source"
1364
+ ];
1365
+ const RETRY_TARGET_KINDS = [
1366
+ "agent",
1367
+ "model-request",
1368
+ "tool",
1369
+ "phase"
1370
+ ];
1371
+ const BudgetScope = Type.Object({
1372
+ level: ClosedEnum(BUDGET_LEVELS),
1373
+ id: Type.String()
1374
+ });
1375
+ /** A MINOR may add commands (2.3.2), so the `type` a command event names is open on the wire. */
1376
+ const CommandTypeName = OpenEnum(COMMAND_TYPES);
1377
+ /** Exported because `inspect { kind: 'approval' }` returns this payload as the decision (R6). */
1378
+ const ApprovalResolvedPayload = Type.Object({
1379
+ approvalId: ApprovalId,
1380
+ decision: ClosedEnum(APPROVAL_DECISIONS),
1381
+ actor: Actor,
1382
+ commandId: Type.Optional(CommandId),
1383
+ /** the authenticator of the approve / deny command, copied so that the decision stays verifiable from the journal */
1384
+ commandAuth: Type.Optional(CommandAuth),
1385
+ grantId: Type.Optional(Type.String()),
1386
+ /** one of `ApprovalRequest.options` */
1387
+ answer: Type.Optional(Type.String()),
1388
+ note: Type.Optional(Type.String())
1389
+ });
1390
+ const GOVERNANCE_EVENTS = {
1391
+ /** R6 */
1392
+ "approval.requested": durable(ApprovalRequest),
1393
+ "approval.resolved": durable(ApprovalResolvedPayload),
1394
+ /** coalesced: thresholds + at most 1 per 5 s per scope */
1395
+ "budget.updated": durable(Type.Object({
1396
+ scope: BudgetScope,
1397
+ consumed: BudgetCounters,
1398
+ limit: BudgetCounters,
1399
+ threshold: Type.Optional(Type.Unsafe({
1400
+ type: "integer",
1401
+ enum: [...BUDGET_THRESHOLDS]
1402
+ }))
1403
+ })),
1404
+ "budget.exceeded": durable(Type.Object({
1405
+ scope: BudgetScope,
1406
+ counter: ClosedEnum(BUDGET_COUNTER_NAMES),
1407
+ limit: Type.Number({ minimum: 0 }),
1408
+ consumed: Type.Number({ minimum: 0 })
1409
+ })),
1410
+ /** on change only */
1411
+ "quota.updated": durable(Type.Object({
1412
+ provider: Type.String(),
1413
+ authMode: AuthMode,
1414
+ quota: QuotaInfo
1415
+ })),
1416
+ "auth.required": durable(Type.Object({
1417
+ provider: Type.String(),
1418
+ cause: ClosedEnum(AUTH_REQUIRED_CAUSES),
1419
+ cli: Type.String()
1420
+ })),
1421
+ "retry.scheduled": durable(Type.Object({
1422
+ target: Type.Object({
1423
+ kind: ClosedEnum(RETRY_TARGET_KINDS),
1424
+ id: Type.String()
1425
+ }),
1426
+ attempt: count$2(),
1427
+ maxAttempts: count$2(),
1428
+ delayMs: milliseconds(),
1429
+ cause: ErrorInfo
1430
+ })),
1431
+ /** `actor` as normalised by the host (2.6.7). An accepted command was authenticated: `authVerified` has one value. */
1432
+ "command.accepted": durable(Type.Object({
1433
+ commandId: CommandId,
1434
+ type: CommandTypeName,
1435
+ actor: Actor,
1436
+ authVerified: Type.Literal(true),
1437
+ scheme: OpenEnum(COMMAND_AUTH_SCHEMES)
1438
+ })),
1439
+ "command.completed": durable(Type.Object({
1440
+ commandId: CommandId,
1441
+ type: CommandTypeName,
1442
+ result: JsonValueSchema
1443
+ })),
1444
+ "command.rejected": durable(Type.Object({
1445
+ commandId: CommandId,
1446
+ type: CommandTypeName,
1447
+ error: ErrorInfo
1448
+ }))
1449
+ };
1450
+ const RUN_EVENTS = {
1451
+ "pipeline.started": durable(Type.Object({
1452
+ profile: PipelineProfile,
1453
+ tableVersion: count$2(),
1454
+ spec: Type.Object({
1455
+ id: SpecId,
1456
+ sha256: Sha256,
1457
+ kind: ClosedEnum([
1458
+ "feature",
1459
+ "patch",
1460
+ "review"
1461
+ ])
1462
+ }),
1463
+ snapshotDigest: Sha256,
1464
+ runtime: Type.Object({
1465
+ id: Type.String(),
1466
+ version: Type.String(),
1467
+ pinDigest: Type.String()
1468
+ }),
1469
+ plan: RunPlan,
1470
+ base: Type.Object({
1471
+ branch: Type.String(),
1472
+ sha: Type.String()
1473
+ }),
1474
+ integrationBranch: Type.String(),
1475
+ cohorteVersion: Type.String(),
1476
+ hostId: Type.String()
1477
+ })),
1478
+ "pipeline.completed": durable(Type.Object({
1479
+ stop: StopRecord,
1480
+ integration: Type.Object({
1481
+ branch: Type.String(),
1482
+ headSha: Type.String(),
1483
+ treeDigest: Type.String()
1484
+ }),
1485
+ totals: Type.Object({
1486
+ usage: BudgetCounters,
1487
+ tokens: TokenUsage,
1488
+ monetaryCost: MonetaryCost,
1489
+ fixRounds: count$2(),
1490
+ durationMs: milliseconds()
1491
+ })
1492
+ })),
1493
+ "pipeline.failed": durable(Type.Object({
1494
+ state: HaltedState,
1495
+ error: ErrorInfo,
1496
+ stop: StopRecord,
1497
+ checkpointSequence: count$2()
1498
+ })),
1499
+ "run.state.changed": durable(Type.Object({
1500
+ transitionId: Type.String(),
1501
+ defId: Type.String(),
1502
+ tableVersion: count$2(),
1503
+ from: PipelineState,
1504
+ to: PipelineState,
1505
+ reason: TransitionReason,
1506
+ actor: Actor,
1507
+ guards: Type.Array(GuardOutcome),
1508
+ idempotencyKey: Type.String(),
1509
+ resumeTo: Type.Optional(ActivePipelineState),
1510
+ stop: Type.Optional(StopRecord)
1511
+ })),
1512
+ "run.paused": durable(Type.Object({
1513
+ commandId: Type.Optional(CommandId),
1514
+ parkedAgents: Type.Array(AgentId),
1515
+ inFlightEffects: Type.Array(EffectId)
1516
+ })),
1517
+ "run.resumed": durable(Type.Object({
1518
+ commandId: Type.Optional(CommandId),
1519
+ mode: ClosedEnum([
1520
+ "unpause",
1521
+ "recovery",
1522
+ "retry"
1523
+ ]),
1524
+ report: ResumeReport
1525
+ })),
1526
+ "run.cancelled": durable(Type.Object({
1527
+ commandId: Type.Optional(CommandId),
1528
+ reason: Type.String(),
1529
+ cancelledAgents: Type.Array(AgentId),
1530
+ worktreesKept: Type.Boolean()
1531
+ })),
1532
+ "run.host.attached": durable(Type.Object({
1533
+ hostId: Type.String(),
1534
+ pid: count$2(),
1535
+ cohorteVersion: Type.String(),
1536
+ fencingToken: count$2(),
1537
+ takeover: Type.Boolean()
1538
+ })),
1539
+ "run.host.detached": durable(Type.Object({
1540
+ hostId: Type.String(),
1541
+ cause: ClosedEnum([
1542
+ "exit",
1543
+ "signal",
1544
+ "lease-lost",
1545
+ "shutdown-command",
1546
+ "fatal"
1547
+ ])
1548
+ })),
1549
+ "phase.started": durable(Type.Object({
1550
+ phase: PhaseRef,
1551
+ contractId: Type.String(),
1552
+ /** PhaseContract.version (DESIGN 2.5.2): a number */
1553
+ contractVersion: count$2(),
1554
+ planned: Type.Array(Type.Object({
1555
+ agentId: AgentId,
1556
+ role: Type.String(),
1557
+ surface: Type.Optional(SurfaceId)
1558
+ })),
1559
+ budget: BudgetCounters
1560
+ })),
1561
+ "phase.completed": durable(Type.Object({
1562
+ phase: PhaseRef,
1563
+ outcome: ClosedEnum([
1564
+ "passed",
1565
+ "failed",
1566
+ "needs-human",
1567
+ "skipped"
1568
+ ]),
1569
+ outputs: Type.Array(ArtifactRef),
1570
+ checks: Type.Array(CheckResult),
1571
+ durationMs: milliseconds()
1572
+ })),
1573
+ "check.started": durable(Type.Object({
1574
+ name: Type.String(),
1575
+ argv: Type.Array(Type.String()),
1576
+ slot: Type.String()
1577
+ })),
1578
+ "check.completed": durable(CheckResult),
1579
+ error: durable(Type.Object({
1580
+ error: ErrorInfo,
1581
+ fatal: Type.Boolean()
1582
+ })),
1583
+ "checkpoint.created": durable(Type.Object({
1584
+ atSequence: count$2(),
1585
+ snapshotSha256: Sha256,
1586
+ chainHash: Type.String(),
1587
+ chainMac: Type.String(),
1588
+ cause: ClosedEnum([
1589
+ "phase-boundary",
1590
+ "interval",
1591
+ "pause",
1592
+ "shutdown",
1593
+ "pre-effect",
1594
+ "fatal"
1595
+ ])
1596
+ }))
1597
+ };
1598
+ //#endregion
1599
+ //#region ../../packages/protocol/src/documents.ts
1600
+ const count = () => Type.Integer({ minimum: 0 });
1601
+ const documentVersion = () => Type.Literal(1);
1602
+ const protocolVersion = () => Type.Literal("1.0");
1603
+ const BILLING = ["plan-limits", "metered"];
1604
+ const ApprovalView = Type.Object({
1605
+ approvalId: ApprovalId,
1606
+ kind: Type.String(),
1607
+ agentId: Type.Optional(AgentId),
1608
+ /** sealed */
1609
+ what: Type.String({ maxLength: 512 }),
1610
+ since: IsoInstant,
1611
+ expiresAt: Type.Optional(IsoInstant),
1612
+ cli: Type.String()
1613
+ });
1614
+ const AgentNode = Type.Object({
1615
+ agentId: AgentId,
1616
+ role: Type.String(),
1617
+ surface: Type.Optional(SurfaceId),
1618
+ label: Type.String(),
1619
+ status: NodeStatus,
1620
+ lifecycle: AgentState,
1621
+ attempt: count(),
1622
+ incarnation: count(),
1623
+ model: Type.Object({
1624
+ requested: ModelRef,
1625
+ effective: Type.Optional(Type.Object({
1626
+ provider: Type.String(),
1627
+ model: Type.String()
1628
+ }))
1629
+ }),
1630
+ authMode: Type.Optional(AuthMode),
1631
+ worktree: Type.Optional(Type.String()),
1632
+ usage: BudgetCounters,
1633
+ summary: Type.Optional(Type.String()),
1634
+ lastError: Type.Optional(ErrorInfo),
1635
+ pendingApproval: Type.Optional(ApprovalId),
1636
+ /** R8: optional and opaque */
1637
+ runtimeRef: Type.Optional(RuntimeRef)
1638
+ });
1639
+ const PhaseNode = Type.Object({
1640
+ state: ActivePipelineState,
1641
+ label: Type.String(),
1642
+ status: NodeStatus,
1643
+ runs: Type.Array(Type.Object({
1644
+ phaseRunId: PhaseRunId,
1645
+ iteration: count(),
1646
+ status: NodeStatus,
1647
+ startedAt: Type.Optional(IsoInstant),
1648
+ endedAt: Type.Optional(IsoInstant),
1649
+ outcome: Type.Optional(Type.String()),
1650
+ agents: Type.Array(AgentNode),
1651
+ checks: Type.Array(CheckResult)
1652
+ }))
1653
+ });
1654
+ const RunNode = Type.Object({
1655
+ runId: RunId,
1656
+ profile: PipelineProfile,
1657
+ title: Type.String(),
1658
+ spec: Type.Object({
1659
+ id: SpecId,
1660
+ kind: Type.String(),
1661
+ sha256: Sha256
1662
+ }),
1663
+ state: PipelineState,
1664
+ status: NodeStatus,
1665
+ since: IsoInstant,
1666
+ resumeTo: Type.Optional(ActivePipelineState),
1667
+ stop: Type.Optional(StopRecord),
1668
+ lastError: Type.Optional(ErrorInfo),
1669
+ iteration: Type.Object({
1670
+ fixRounds: count(),
1671
+ maxFixRounds: count(),
1672
+ reviewRounds: count()
1673
+ }),
1674
+ host: Type.Object({
1675
+ hostId: Type.Optional(Type.String()),
1676
+ alive: Type.Boolean(),
1677
+ heartbeatAt: Type.Optional(IsoInstant),
1678
+ pid: Type.Optional(count())
1679
+ }),
1680
+ git: Type.Object({
1681
+ base: Type.Object({
1682
+ branch: Type.String(),
1683
+ sha: Type.String()
1684
+ }),
1685
+ integrationBranch: Type.String(),
1686
+ integrationHead: Type.Optional(Type.String()),
1687
+ approvedTreeDigest: Type.Optional(Type.String())
1688
+ }),
1689
+ plan: RunPlan,
1690
+ snapshotDigest: Sha256,
1691
+ startedAt: IsoInstant,
1692
+ endedAt: Type.Optional(IsoInstant)
1693
+ });
1694
+ /** `cohorte status <run> --json`, `inspect { kind: 'snapshot' }`, and the first line of every stream (R2). */
1695
+ const RunSnapshotDocument = Type.Object({
1696
+ documentVersion: documentVersion(),
1697
+ protocolVersion: protocolVersion(),
1698
+ cohorteVersion: Type.String(),
1699
+ generatedAt: IsoInstant,
1700
+ lastSequence: count(),
1701
+ run: RunNode,
1702
+ /** table order for the profile, not-yet-run phases as 'pending' */
1703
+ phases: Type.Array(PhaseNode),
1704
+ approvals: Type.Object({
1705
+ pending: Type.Array(ApprovalView),
1706
+ resolved: count()
1707
+ }),
1708
+ budgets: Type.Array(Type.Object({
1709
+ scope: Type.Object({
1710
+ level: Type.String(),
1711
+ id: Type.String()
1712
+ }),
1713
+ consumed: BudgetCounters,
1714
+ limit: BudgetCounters
1715
+ })),
1716
+ usage: Type.Object({
1717
+ tokens: TokenUsage,
1718
+ monetaryCost: MonetaryCost,
1719
+ byProvider: Type.Array(Type.Object({
1720
+ provider: Type.String(),
1721
+ authMode: AuthMode,
1722
+ billing: ClosedEnum(BILLING),
1723
+ tokens: TokenUsage,
1724
+ quota: QuotaInfo,
1725
+ accountLabel: Type.Optional(Type.String())
1726
+ }))
1727
+ }),
1728
+ locks: Type.Array(Type.Object({
1729
+ scope: Type.String(),
1730
+ key: Type.String(),
1731
+ mode: Type.String()
1732
+ })),
1733
+ inDoubtEffects: Type.Array(EffectId)
1734
+ });
1735
+ /**
1736
+ * One row of `ProjectStatusDocument.runs`: a PROJECTION of `RunSnapshotDocument.run`, never a second definition.
1737
+ *
1738
+ * KEEP THE EXPLICIT ANNOTATION. Biome 2.5.14 overflows its stack when it has to INFER the type of this pick, in every
1739
+ * file that names the const, and then exits 0 having linted nothing (docs/v3/requests/U0.02.md R1).
1740
+ */
1741
+ const ProjectRunSummary = Type.Unsafe(Type.Pick(RunNode, [
1742
+ "runId",
1743
+ "profile",
1744
+ "title",
1745
+ "state",
1746
+ "status",
1747
+ "since",
1748
+ "startedAt",
1749
+ "endedAt",
1750
+ "stop"
1751
+ ]));
1752
+ /** `cohorte status --json` without a run: the "current pipeline" of R4. */
1753
+ const ProjectStatusDocument = Type.Object({
1754
+ documentVersion: documentVersion(),
1755
+ protocolVersion: protocolVersion(),
1756
+ project: Type.Object({
1757
+ id: Type.String(),
1758
+ root: Type.String()
1759
+ }),
1760
+ runs: Type.Array(ProjectRunSummary),
1761
+ pendingApprovals: Type.Array(ApprovalView)
1762
+ });
1763
+ /** spec 17.1 "diffs"; `cohorte diff --json`. A patch is fetched with `inspect { kind: 'artifact' }`. */
1764
+ const RunDiffDocument = Type.Object({
1765
+ documentVersion: documentVersion(),
1766
+ runId: RunId,
1767
+ base: Type.Object({
1768
+ branch: Type.String(),
1769
+ sha: Type.String()
1770
+ }),
1771
+ head: Type.Object({
1772
+ branch: Type.String(),
1773
+ sha: Type.String(),
1774
+ treeDigest: Type.String()
1775
+ }),
1776
+ surfaces: Type.Array(Type.Object({
1777
+ surface: Type.Union([Type.Literal("shared"), SurfaceId]),
1778
+ files: Type.Array(FileTouch),
1779
+ stat: Type.Object({
1780
+ added: count(),
1781
+ removed: count()
1782
+ }),
1783
+ patch: ArtifactRef
1784
+ }))
1785
+ });
1786
+ /**
1787
+ * The artifact window is capped in BYTES by the command (`maxBytes` <= INSPECT_ARTIFACT_MAX_BYTES). `content` is
1788
+ * those bytes as utf8 (never more characters than bytes) or as base64 (4 characters per 3 bytes): the base64 length
1789
+ * of the byte cap bounds both.
1790
+ */
1791
+ const INSPECT_ARTIFACT_MAX_CONTENT_LENGTH = 4 * Math.ceil(INSPECT_ARTIFACT_MAX_BYTES / 3);
1792
+ const inspectHeader = () => ({
1793
+ documentVersion: documentVersion(),
1794
+ protocolVersion: protocolVersion(),
1795
+ runId: RunId,
1796
+ lastSequence: count()
1797
+ });
1798
+ /** Keyed by the published file name: `schemas/<name>.schema.json` (DESIGN 7.5 AC-07 lists them). */
1799
+ const DOCUMENTS = {
1800
+ "run-state": RunSnapshotDocument,
1801
+ "project-status": ProjectStatusDocument,
1802
+ inspect: Type.Union([
1803
+ Type.Object({
1804
+ ...inspectHeader(),
1805
+ kind: Type.Literal("agent"),
1806
+ agent: AgentNode,
1807
+ grantsDigest: Sha256,
1808
+ tools: Type.Array(Type.String()),
1809
+ incarnations: Type.Array(Type.Object({
1810
+ n: count(),
1811
+ state: Type.String(),
1812
+ startedAt: Type.Optional(IsoInstant),
1813
+ endedAt: Type.Optional(IsoInstant),
1814
+ stop: Type.Optional(Type.String()),
1815
+ reason: Type.Optional(Type.String())
1816
+ }))
1817
+ }),
1818
+ Type.Object({
1819
+ ...inspectHeader(),
1820
+ kind: Type.Literal("context"),
1821
+ agentId: AgentId,
1822
+ incarnation: count(),
1823
+ context: ContextBuiltPayload
1824
+ }),
1825
+ Type.Object({
1826
+ ...inspectHeader(),
1827
+ kind: Type.Literal("approval"),
1828
+ request: ApprovalRequest,
1829
+ status: Type.String(),
1830
+ decision: Type.Optional(ApprovalResolvedPayload)
1831
+ }),
1832
+ Type.Object({
1833
+ ...inspectHeader(),
1834
+ kind: Type.Literal("effect"),
1835
+ effect: Type.Object({
1836
+ effectId: EffectId,
1837
+ kind: Type.String(),
1838
+ replayClass: Type.String(),
1839
+ state: Type.String(),
1840
+ toolCallId: Type.Optional(ToolCallId),
1841
+ slot: Type.Optional(Type.String()),
1842
+ request: JsonValueSchema,
1843
+ result: Type.Optional(JsonValueSchema),
1844
+ error: Type.Optional(ErrorInfo)
1845
+ })
1846
+ }),
1847
+ Type.Object({
1848
+ ...inspectHeader(),
1849
+ kind: Type.Literal("snapshot"),
1850
+ document: RunSnapshotDocument
1851
+ }),
1852
+ Type.Object({
1853
+ ...inspectHeader(),
1854
+ kind: Type.Literal("locks"),
1855
+ locks: Type.Array(Type.Object({
1856
+ scope: Type.String(),
1857
+ key: Type.String(),
1858
+ mode: Type.String(),
1859
+ owner: Type.String(),
1860
+ leaseExpiresAt: IsoInstant
1861
+ }))
1862
+ }),
1863
+ Type.Object({
1864
+ ...inspectHeader(),
1865
+ kind: Type.Literal("diff"),
1866
+ diff: RunDiffDocument
1867
+ }),
1868
+ Type.Object({
1869
+ ...inspectHeader(),
1870
+ kind: Type.Literal("artifact"),
1871
+ artifact: ArtifactRef,
1872
+ offset: count(),
1873
+ bytes: Type.Integer({
1874
+ minimum: 0,
1875
+ maximum: INSPECT_ARTIFACT_MAX_BYTES
1876
+ }),
1877
+ truncated: Type.Boolean(),
1878
+ encoding: ClosedEnum(["utf8", "base64"]),
1879
+ /** sealed at write time */
1880
+ content: Type.String({ maxLength: INSPECT_ARTIFACT_MAX_CONTENT_LENGTH })
1881
+ })
1882
+ ]),
1883
+ "run-diff": RunDiffDocument,
1884
+ "command-result": Type.Object({
1885
+ documentVersion: documentVersion(),
1886
+ commandId: CommandId,
1887
+ /** open on the wire: a MINOR may add commands */
1888
+ type: OpenEnum(COMMAND_TYPES),
1889
+ status: ClosedEnum([
1890
+ "completed",
1891
+ "rejected",
1892
+ "pending"
1893
+ ]),
1894
+ result: Type.Optional(JsonValueSchema),
1895
+ error: Type.Optional(ErrorInfo),
1896
+ lastSequence: Type.Optional(count())
1897
+ }),
1898
+ "doctor-report": Type.Object({
1899
+ documentVersion: documentVersion(),
1900
+ cohorteVersion: Type.String(),
1901
+ generatedAt: IsoInstant,
1902
+ ok: Type.Boolean(),
1903
+ checks: Type.Array(Type.Object({
1904
+ id: Type.String(),
1905
+ status: OpenEnum([
1906
+ "ok",
1907
+ "warning",
1908
+ "error",
1909
+ "skipped"
1910
+ ]),
1911
+ summary: Type.String(),
1912
+ detail: Type.Optional(Type.String()),
1913
+ remediation: Type.Optional(Type.String())
1914
+ })),
1915
+ sandbox: JsonValueSchema,
1916
+ runtimeCapabilities: JsonValueSchema
1917
+ }),
1918
+ "auth-status": Type.Object({
1919
+ documentVersion: documentVersion(),
1920
+ generatedAt: IsoInstant,
1921
+ runtime: Type.Object({
1922
+ id: Type.String(),
1923
+ version: Type.String()
1924
+ }),
1925
+ providers: Type.Array(Type.Object({
1926
+ provider: Type.String(),
1927
+ state: Type.String(),
1928
+ subscription: Type.Boolean(),
1929
+ billing: ClosedEnum([...BILLING, "unknown"]),
1930
+ source: Type.Optional(Type.String()),
1931
+ accountLabel: Type.Optional(Type.String()),
1932
+ accountLabelNote: Type.Optional(Type.String()),
1933
+ caveat: Type.Optional(Type.String()),
1934
+ checkedAt: IsoInstant
1935
+ }))
1936
+ })
1937
+ };
1938
+ Object.keys(DOCUMENTS);
1939
+ //#endregion
1940
+ //#region ../../packages/protocol/src/events/stream.ts
1941
+ const STREAM_EVENTS = {
1942
+ /** synthetic first line of every stream: a late client gets this, then the durable events after `lastSequence` */
1943
+ snapshot: ephemeral(Type.Object({
1944
+ document: RunSnapshotDocument,
1945
+ lastSequence: count$2()
1946
+ })),
1947
+ /** every 15 s on `--follow` */
1948
+ heartbeat: ephemeral(Type.Object({
1949
+ hostAlive: Type.Boolean(),
1950
+ lastSequence: count$2()
1951
+ }))
1952
+ };
1953
+ //#endregion
1954
+ //#region ../../packages/protocol/src/events/tool.ts
1955
+ const TOOL_DENIAL_STAGES = [
1956
+ "liveness",
1957
+ "schema",
1958
+ "capability",
1959
+ "path",
1960
+ "command",
1961
+ "network",
1962
+ "budget",
1963
+ "approval"
1964
+ ];
1965
+ const TOOL_REJECTION_CAUSES = [
1966
+ "unknown-tool",
1967
+ "invalid-input",
1968
+ "output-truncated"
1969
+ ];
1970
+ const TOOL_DECISIONS = [
1971
+ "allow",
1972
+ "allow-once",
1973
+ "allow-for-run"
1974
+ ];
1975
+ const FINDING_DISPOSITIONS = [
1976
+ "kept",
1977
+ "refuted",
1978
+ "deferred",
1979
+ "needs-investigation",
1980
+ "duplicate"
1981
+ ];
1982
+ const FileAccess = Type.Object({
1983
+ toolCallId: ToolCallId,
1984
+ file: FileTouch,
1985
+ diffStat: Type.Optional(Type.Object({
1986
+ added: count$2(),
1987
+ removed: count$2()
1988
+ }))
1989
+ });
1990
+ const TOOL_EVENTS = {
1991
+ /** `args` is sealed */
1992
+ "tool.requested": durable(Type.Object({
1993
+ toolCallId: ToolCallId,
1994
+ tool: Type.String(),
1995
+ args: JsonValueSchema,
1996
+ argsSha256: Sha256
1997
+ })),
1998
+ "tool.denied": durable(Type.Object({
1999
+ toolCallId: ToolCallId,
2000
+ tool: Type.String(),
2001
+ stage: OpenEnum(TOOL_DENIAL_STAGES),
2002
+ ruleId: Type.String(),
2003
+ reason: Type.String(),
2004
+ overridable: Type.Boolean(),
2005
+ evaluatedRules: Type.Array(Type.String()),
2006
+ approvalId: Type.Optional(ApprovalId)
2007
+ })),
2008
+ /**
2009
+ * The ENGINE refused the call before the host saw it: no `toolCallId`, no gate, no rule ids — which is why it is
2010
+ * not a `tool.denied`. `message` is sealed.
2011
+ */
2012
+ "tool.rejected": durable(Type.Object({
2013
+ engineToolCallId: Type.Optional(Type.String()),
2014
+ tool: Type.String(),
2015
+ cause: OpenEnum(TOOL_REJECTION_CAUSES),
2016
+ message: Type.String()
2017
+ })),
2018
+ "tool.started": durable(Type.Object({
2019
+ toolCallId: ToolCallId,
2020
+ tool: Type.String(),
2021
+ effectId: EffectId,
2022
+ decision: ClosedEnum(TOOL_DECISIONS),
2023
+ ruleId: Type.String(),
2024
+ grantId: Type.Optional(Type.String()),
2025
+ normalizedArgs: JsonValueSchema,
2026
+ replayClass: ClosedEnum(REPLAY_CLASSES),
2027
+ sandbox: SandboxReport,
2028
+ /** marks a host-side replay of an approved call (4.5) */
2029
+ replayOfApproval: Type.Optional(ApprovalId)
2030
+ })),
2031
+ "tool.progress": ephemeral(Type.Object({
2032
+ toolCallId: ToolCallId,
2033
+ text: Type.Optional(Type.String()),
2034
+ bytes: Type.Optional(count$2())
2035
+ })),
2036
+ "tool.completed": durable(Type.Object({
2037
+ toolCallId: ToolCallId,
2038
+ tool: Type.String(),
2039
+ effectId: EffectId,
2040
+ isError: Type.Boolean(),
2041
+ exitCode: Type.Optional(Type.Integer()),
2042
+ signal: Type.Optional(Type.String()),
2043
+ timedOut: Type.Boolean(),
2044
+ durationMs: milliseconds(),
2045
+ /** time the runtime waited for the host, from the delivery of the call */
2046
+ waitedMs: milliseconds(),
2047
+ output: Type.Object({
2048
+ sha256: Sha256,
2049
+ bytes: count$2(),
2050
+ truncated: Type.Boolean(),
2051
+ preview: Type.String(),
2052
+ artifact: Type.Optional(ArtifactRef)
2053
+ }),
2054
+ filesTouched: Type.Array(FileTouch),
2055
+ /** hits dropped by output filtering (2.7) */
2056
+ filteredPaths: Type.Optional(count$2()),
2057
+ replayed: Type.Boolean()
2058
+ })),
2059
+ "file.read": durable(FileAccess),
2060
+ "file.written": durable(FileAccess),
2061
+ "file.changed": durable(Type.Object({
2062
+ slot: Type.String(),
2063
+ files: Type.Array(FileTouch),
2064
+ detectedBy: ClosedEnum(["post-command-scan", "ledger-audit"]),
2065
+ attributedTo: Type.Optional(ToolCallId)
2066
+ })),
2067
+ "review.started": durable(Type.Object({
2068
+ phase: PhaseRef,
2069
+ reviewRef: ReviewRef,
2070
+ surfaces: Type.Array(SurfaceId),
2071
+ reviewers: Type.Array(AgentId)
2072
+ })),
2073
+ "review.finding": durable(Type.Object({
2074
+ finding: Finding,
2075
+ reviewer: AgentRef,
2076
+ disposition: ClosedEnum(FINDING_DISPOSITIONS)
2077
+ })),
2078
+ "review.completed": durable(Type.Object({
2079
+ verdict: ReviewResult.properties.verdict,
2080
+ blocking: count$2(),
2081
+ blockingItems: Type.Array(Type.String()),
2082
+ fingerprint: ReviewResult.properties.fingerprint,
2083
+ unreviewed: Type.Array(SurfaceId),
2084
+ counts: ReviewResult.properties.counts,
2085
+ clean: Type.Boolean()
2086
+ })),
2087
+ "review.approved": durable(Type.Object({
2088
+ reviewRef: ReviewRef,
2089
+ waivers: Type.Array(Type.Object({
2090
+ findingId: FindingId,
2091
+ approvalId: ApprovalId
2092
+ }))
2093
+ }))
2094
+ };
2095
+ //#endregion
2096
+ //#region ../../packages/protocol/src/catalogue.ts
2097
+ const EVENTS = {
2098
+ ...RUN_EVENTS,
2099
+ ...AGENT_EVENTS,
2100
+ ...TOOL_EVENTS,
2101
+ ...GOVERNANCE_EVENTS,
2102
+ ...GIT_EVENTS,
2103
+ ...STREAM_EVENTS
2104
+ };
2105
+ Object.keys(EVENTS).filter((type) => EVENTS[type].durability === "durable");
2106
+ const isEventType = (type) => Object.hasOwn(EVENTS, type);
2107
+ const isDurableEventType = (type) => isEventType(type) && EVENTS[type].durability === "durable";
2108
+ /**
2109
+ * `compileStrict(type)`, `compileStrictEnvelope(type)` and `toOpenJsonSchema()` with the exact signatures of
2110
+ * DESIGN 2.3.2, bound to EVENTS. The functions of the same names in compile.ts are generic over a table.
2111
+ */
2112
+ const catalogue = bindCatalogue(EVENTS);
2113
+ //#endregion
2114
+ export { compileSchema as a, AgentOutput as c, EscalationPolicy as d, HALTED_STATES as f, ClosedEnum as g, TERMINAL_STATES as h, canonicalCommandBody as i, ACTIVE_PIPELINE_STATES as l, SUSPENDED_STATES as m, isDurableEventType as n, toStrictSchema as o, PipelineProfile as p, CONTROLLER_EXIT_CODES as r, compareOrder as s, catalogue as t, ActivePipelineState as u };
2115
+
2116
+ //# sourceMappingURL=src-s7YRvk0t.mjs.map