@openwop/spec-artifacts 2.0.0-rc.37 → 2.0.0-rc.6

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 (34) hide show
  1. package/CORPUS-STAMP.json +32 -34
  2. package/api/seams-v2.yaml +1 -1
  3. package/api/v2/asyncapi.yaml +1 -1
  4. package/api/v2/openapi.yaml +10 -9
  5. package/package.json +5 -18
  6. package/schemas/capabilities.schema.json +1 -40
  7. package/schemas/certification-bundle-v2.schema.json +27 -119
  8. package/schemas/run-snapshot.schema.json +33 -103
  9. package/schemas/v2/agent-deployment-transition.schema.json +6 -5
  10. package/schemas/v2/agent-deployment.schema.json +9 -8
  11. package/schemas/v2/agent-eval-suite.schema.json +12 -11
  12. package/schemas/v2/artifact-type-pack-manifest.schema.json +18 -22
  13. package/schemas/v2/capabilities.schema.json +0 -39
  14. package/schemas/v2/certification-bundle.schema.json +1 -1
  15. package/schemas/v2/chat-card-pack-manifest.schema.json +15 -19
  16. package/schemas/v2/debug-bundle.schema.json +6 -6
  17. package/schemas/v2/eval-summary.schema.json +10 -17
  18. package/schemas/v2/goal.schema.json +5 -5
  19. package/schemas/v2/ids.schema.json +22 -120
  20. package/schemas/v2/node-pack-manifest.schema.json +31 -27
  21. package/schemas/v2/proposal.schema.json +8 -7
  22. package/schemas/v2/run-event-payloads.schema.json +242 -246
  23. package/schemas/v2/run-event.schema.json +126 -2
  24. package/schemas/v2/run-snapshot.schema.json +13 -34
  25. package/schemas/v2/workflow-chain-pack-manifest.schema.json +45 -41
  26. package/schemas/v2/workflow-definition.schema.json +36 -31
  27. package/spec/v1/core-standard-manifest.json +2 -2
  28. package/spec/v1/deprecations.json +67 -79
  29. package/spec/v1/deprecations.schema.json +7 -23
  30. package/spec/v1/extensions.json +2 -3
  31. package/spec/v2/declaration.json +0 -7
  32. package/spec/v2/release.json +2 -2
  33. package/schemas/v2/webhook-delivery.schema.json +0 -26
  34. package/spec/v2/id-field-bindings.json +0 -104
@@ -195,7 +195,131 @@
195
195
  "description": "Optional ID of the event that caused this one (e.g., node.completed caused by approval.received). Lets projections build causal chains without inferring from timing."
196
196
  }
197
197
  },
198
- "$comment": "RFC 0171 §A / `events.md` §\"The envelope\": in v2 RunEventDoc is CLOSED (`additionalProperties: false`). This reverses the v1 rule, which left the envelope open so v1.x hosts could add optional fields additively. The v2 envelope carries host-specific data in the registered vendor branch, not at the root. Do not restore the v1 sentence: a host that follows it emits root-level extension fields and fails `v2-event-type-closed`, and the schema keyword is the contract while a comment is only a claim about it.",
198
+ "$comment": "RFC 0094 §G + COMPATIBILITY.md §\"Schema closure\": RunEventDoc is a SERVER-EMITTED shape, so it is open (`additionalProperties: true`) v1.x hosts may add optional fields additively without breaking schema-validating clients. Client-submitted shapes stay closed at their outermost composition.",
199
199
  "additionalProperties": false,
200
- "$defs": {}
200
+ "$defs": {
201
+ "RunEventType": {
202
+ "type": "string",
203
+ "description": "Discriminator for event payload shape. Dotted naming convention. New variants extend the union — readers MUST NOT throw on unknown types (forward-compat: fold best-effort, ignore unknowns). RFC 0151 §D adds the six content-free `compensation.*` events. They are added to this CLOSED enum because without them a conforming host cannot emit them at all: the RFC named the events, the enum did not contain them, and any host following §D would have produced run events that fail schema validation. Payloads carry opaque node/effect IDs, attempt, ordering model, and closed reason codes — never provider bodies or credentials (§D/§G).",
204
+ "enum": [
205
+ "run.started",
206
+ "run.completed",
207
+ "run.failed",
208
+ "run.cancelled",
209
+ "run.resuming",
210
+ "run.paused",
211
+ "run.resumed",
212
+ "run.restored-from-snapshot",
213
+ "run.dead_lettered",
214
+ "node.started",
215
+ "node.completed",
216
+ "node.failed",
217
+ "node.suspended",
218
+ "node.suspend-failed",
219
+ "node.resumed",
220
+ "node.retried",
221
+ "node.skipped",
222
+ "node.cancelled",
223
+ "approval.requested",
224
+ "approval.received",
225
+ "approval.granted",
226
+ "approval.rejected",
227
+ "approval.overridden",
228
+ "clarification.requested",
229
+ "clarification.resolved",
230
+ "interrupt.requested",
231
+ "interrupt.resolved",
232
+ "channel.written",
233
+ "channel.presence",
234
+ "context.summarized",
235
+ "artifact.created",
236
+ "output.chunk",
237
+ "variable.changed",
238
+ "log.appended",
239
+ "version.pinned",
240
+ "workflow.restored",
241
+ "workflow.loopback-limit",
242
+ "workflow.stalled",
243
+ "cap.breached",
244
+ "lease.acquired",
245
+ "lease.renewed",
246
+ "lease.lost",
247
+ "lease.handed-off",
248
+ "replay.diverged",
249
+ "replay.divergedAtRefusal",
250
+ "agent.reasoned",
251
+ "agent.reasoning.delta",
252
+ "provider.usage",
253
+ "prompt.composed",
254
+ "agent.promptResolved",
255
+ "model.capability.substituted",
256
+ "model.capability.insufficient",
257
+ "envelope.retry.attempted",
258
+ "envelope.retry.exhausted",
259
+ "envelope.refusal",
260
+ "envelope.truncated",
261
+ "envelope.nlToFormat.engaged",
262
+ "envelope.recovery.applied",
263
+ "agent.toolCalled",
264
+ "agent.toolReturned",
265
+ "agent.handoff",
266
+ "agent.decided",
267
+ "agent.verified",
268
+ "agent.invocation.started",
269
+ "agent.invocation.completed",
270
+ "eval.started",
271
+ "eval.scored",
272
+ "eval.completed",
273
+ "deployment.promoted",
274
+ "deployment.rolled-back",
275
+ "deployment.canary.adjusted",
276
+ "deployment.state.changed",
277
+ "roster.run.initiated",
278
+ "tool.session.opened",
279
+ "tool.session.closed",
280
+ "egress.decided",
281
+ "trigger.subscription.state.changed",
282
+ "trigger.delivery.attempted",
283
+ "budget.reserved",
284
+ "budget.consumed",
285
+ "budget.threshold.crossed",
286
+ "budget.exhausted",
287
+ "runOrchestrator.decided",
288
+ "node.dispatched",
289
+ "core.dispatch.fanOut",
290
+ "core.dispatch.join",
291
+ "conversation.opened",
292
+ "conversation.exchanged",
293
+ "conversation.closed",
294
+ "memory.compacted",
295
+ "memory.written",
296
+ "agent.memory.consolidated",
297
+ "commitment.fired",
298
+ "workspace.updated",
299
+ "core.workflowChain.event",
300
+ "core.workflowChain.confidence-escalated",
301
+ "connector.authorized",
302
+ "connector.auth_expired",
303
+ "authorization.decided",
304
+ "proposal.created",
305
+ "proposal.activated",
306
+ "goal.evaluated",
307
+ "goal.closed",
308
+ "import.applied",
309
+ "voice.speech_start",
310
+ "voice.transcript",
311
+ "voice.endpoint_candidate",
312
+ "voice.turn_commit",
313
+ "voice.synthesis_chunk",
314
+ "voice.barge_in",
315
+ "voice.cancelled",
316
+ "compensation.requested",
317
+ "compensation.started",
318
+ "compensation.completed",
319
+ "compensation.failed",
320
+ "compensation.paused",
321
+ "compensation.manual_intervention_required"
322
+ ]
323
+ }
324
+ }
201
325
  }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://openwop.dev/spec/v2/run-snapshot.schema.json",
4
4
  "title": "RunSnapshot",
5
- "description": "Projected run state returned by `GET /runs/{runId}`. Source is the run\u2019s append-only event log (run-event.schema.json) folded through the `RunProjection`. CLOSED in v2 (`additionalProperties: false`): a reader MUST NOT expect to ignore unknown root fields, because there are none to ignore \u2014 host-specific state goes in `extensions`. The v1 schema was open and therefore never had to declare what hosts actually served; closing the object is what made that visible.",
5
+ "description": "Projected run state returned by `GET /v1/runs/{runId}`. Source is the run's append-only event log (run-event.schema.json) folded through the `RunProjection`. Forward-compat tolerant: readers MUST ignore unknown fields rather than reject.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "eventLogSchemaVersion",
@@ -34,7 +34,7 @@
34
34
  "cancelling",
35
35
  "cancelled"
36
36
  ],
37
- "description": "Current run state. `waiting-external` MUST be used when the suspended interrupt's `kind` is `external-event` per `interrupt-profiles.md \u00a7openwop-interrupt-external-event` \u2014 distinguishes external-event waits from HITL waits at the wire level. `cancelling` (RFC 0094 \u00a7B) is the transitional state between a cancel request being accepted and the terminal `cancelled` \u2014 `rest-endpoints.md` and the OpenAPI cancel responses already document the transition; a snapshot read during the cancel cascade carries it. Forward-compat: future statuses MAY be added; readers SHOULD treat unknown values as terminal-unknown rather than throw."
37
+ "description": "Current run state. `waiting-external` MUST be used when the suspended interrupt's `kind` is `external-event` per `interrupt-profiles.md §openwop-interrupt-external-event` distinguishes external-event waits from HITL waits at the wire level. `cancelling` (RFC 0094 §B) is the transitional state between a cancel request being accepted and the terminal `cancelled` `rest-endpoints.md` and the OpenAPI cancel responses already document the transition; a snapshot read during the cancel cascade carries it. Forward-compat: future statuses MAY be added; readers SHOULD treat unknown values as terminal-unknown rather than throw."
38
38
  },
39
39
  "compensationStatus": {
40
40
  "type": "string",
@@ -47,7 +47,7 @@
47
47
  "failed",
48
48
  "manual"
49
49
  ],
50
- "description": "RFC 0151 \u00a7D \u2014 the run's compensation (unwind) rollup, kept separate from `status` on purpose: `status` is the FORWARD execution state and a closed union exported by the SDK, so RFC 0151 forbids reinterpreting it (there is deliberately no `compensating` run status). OPTIONAL and capability-gated \u2014 a host that does not advertise `capabilities.compensation` MUST omit this field; a host that advertises it MUST include it on every snapshot, `none` when no compensation was ever requested for the run. Presence is therefore a wire witness of the advert, and a `none` cannot be read as \"unwind is monitored here\" from a host that would never unwind. Values are the deterministic fold of the six `compensation.*` events over the persisted plan, defined normatively in `spec/v1/compensation.md \u00a7\"Run rollup: compensationStatus\"`: `none` (no `compensation.requested`), `pending` (requested, no `started`), `running` (started, plan active \u2014 a \u00a7E approval pause does NOT change it; the run's own `status: waiting-approval` carries the wait), `completed` (every inverse action completed), `partial` (plan inactive; some completed and some did not \u2014 reported, never rounded), `failed` (plan inactive; none completed), `manual` (`manual_intervention_required` recorded and unresolved; takes precedence over `partial`/`failed` while unresolved). Content-free by construction. Resolves RFC 0151 UQ3: `RunSnapshot` (`GET /v1/runs/{runId}`) is the sole owner; debug bundles and the AsyncAPI `run.snapshot` reuse it by `$ref`."
50
+ "description": "RFC 0151 §D the run's compensation (unwind) rollup, kept separate from `status` on purpose: `status` is the FORWARD execution state and a closed union exported by the SDK, so RFC 0151 forbids reinterpreting it (there is deliberately no `compensating` run status). OPTIONAL and capability-gated a host that does not advertise `capabilities.compensation` MUST omit this field; a host that advertises it MUST include it on every snapshot, `none` when no compensation was ever requested for the run. Presence is therefore a wire witness of the advert, and a `none` cannot be read as \"unwind is monitored here\" from a host that would never unwind. Values are the deterministic fold of the six `compensation.*` events over the persisted plan, defined normatively in `spec/v1/compensation.md §\"Run rollup: compensationStatus\"`: `none` (no `compensation.requested`), `pending` (requested, no `started`), `running` (started, plan active a §E approval pause does NOT change it; the run's own `status: waiting-approval` carries the wait), `completed` (every inverse action completed), `partial` (plan inactive; some completed and some did not reported, never rounded), `failed` (plan inactive; none completed), `manual` (`manual_intervention_required` recorded and unresolved; takes precedence over `partial`/`failed` while unresolved). Content-free by construction. Resolves RFC 0151 UQ3: `RunSnapshot` (`GET /v1/runs/{runId}`) is the sole owner; debug bundles and the AsyncAPI `run.snapshot` reuse it by `$ref`."
51
51
  },
52
52
  "owner": {
53
53
  "type": "object",
@@ -67,11 +67,11 @@
67
67
  "$ref": "subject.schema.json"
68
68
  }
69
69
  },
70
- "description": "RFC 0170 \u00a7A.1 \u2014 the Subject is the owner; principal/principalKind removed. Copied verbatim onto a fork (\u00a7A.4)."
70
+ "description": "RFC 0170 §A.1 the Subject is the owner; principal/principalKind removed. Copied verbatim onto a fork (§A.4)."
71
71
  },
72
72
  "currentNodeId": {
73
- "$ref": "ids.schema.json#/$defs/nodeId",
74
- "description": "Set when the run is suspended at a specific node (`waiting-approval` / `waiting-input` / `waiting-external`) \u2014 identifies which node holds the interrupt."
73
+ "type": "string",
74
+ "description": "Set when the run is suspended at a specific node (`waiting-approval` / `waiting-input` / `waiting-external`) identifies which node holds the interrupt."
75
75
  },
76
76
  "startedAt": {
77
77
  "type": "string",
@@ -83,15 +83,15 @@
83
83
  },
84
84
  "agent": {
85
85
  "$ref": "agent-ref.schema.json",
86
- "description": "Optional run-level agent identity (Multi-Agent Shift Phase 1). When the run is driven by a single agent, this field carries that agent's `AgentRef`. In supervisor-orchestrated runs (Phase 5), this field rotates as workers hand off \u2014 it always carries the active worker for the current node. See `runOrchestrator` for the run-lifetime supervisor identity. Absent for runs with no agent provenance (legacy single-actor host)."
86
+ "description": "Optional run-level agent identity (Multi-Agent Shift Phase 1). When the run is driven by a single agent, this field carries that agent's `AgentRef`. In supervisor-orchestrated runs (Phase 5), this field rotates as workers hand off it always carries the active worker for the current node. See `runOrchestrator` for the run-lifetime supervisor identity. Absent for runs with no agent provenance (legacy single-actor host)."
87
87
  },
88
88
  "runOrchestrator": {
89
89
  "$ref": "agent-ref.schema.json",
90
- "description": "Optional orchestrator-supervisor identity (Multi-Agent Shift Phase 5). When set, this agent owns dispatch decisions across the run's lifetime; `runOrchestrator.decided` events emitted during the run carry this agent's `agentId`. Distinct from `agent` \u2014 `agent` rotates with each worker; `runOrchestrator` is set at run start (or first `core.orchestrator.supervisor` node) and MUST NOT change for the run's lifetime. In single-agent runs (no supervisor), this field is absent; in supervisor runs both fields MAY co-exist."
90
+ "description": "Optional orchestrator-supervisor identity (Multi-Agent Shift Phase 5). When set, this agent owns dispatch decisions across the run's lifetime; `runOrchestrator.decided` events emitted during the run carry this agent's `agentId`. Distinct from `agent` `agent` rotates with each worker; `runOrchestrator` is set at run start (or first `core.orchestrator.supervisor` node) and MUST NOT change for the run's lifetime. In single-agent runs (no supervisor), this field is absent; in supervisor runs both fields MAY co-exist."
91
91
  },
92
92
  "nodeStates": {
93
93
  "type": "object",
94
- "description": "Per-node state map. Keys are nodeIds; values are implementation-shaped state objects. Spec doesn't constrain the inner shape \u2014 see version-negotiation.md \u00a7node-states.",
94
+ "description": "Per-node state map. Keys are nodeIds; values are implementation-shaped state objects. Spec doesn't constrain the inner shape see version-negotiation.md §node-states.",
95
95
  "additionalProperties": true
96
96
  },
97
97
  "variables": {
@@ -129,13 +129,13 @@
129
129
  },
130
130
  "engineVersion": {
131
131
  "type": "integer",
132
- "description": "Engine version the run was started under. Used by the projection for forward-compat folds. v2: integer everywhere (RFC 0172 \u00a7B axis 3).",
132
+ "description": "Engine version the run was started under. Used by the projection for forward-compat folds. v2: integer everywhere (RFC 0172 §B axis 3).",
133
133
  "minimum": 0
134
134
  },
135
135
  "eventLogSchemaVersion": {
136
136
  "type": "integer",
137
137
  "minimum": 2,
138
- "description": "RFC 0176 \u00a7A.2 \u2014 the era key; a v2 host writes 3; a v1-era run reads 2."
138
+ "description": "RFC 0176 §A.2 the era key; a v2 host writes 3; a v1-era run reads 2."
139
139
  },
140
140
  "tags": {
141
141
  "type": "array",
@@ -158,11 +158,11 @@
158
158
  },
159
159
  "metrics": {
160
160
  "type": "object",
161
- "description": "Aggregate run-level metrics. Forward-compat: readers MUST tolerate missing/unknown fields. Fields are populated lazily as the engine emits them \u2014 absence does NOT mean zero. Implementation-specific fields (e.g., legacy `cost: number` estimates) MAY appear alongside the spec-canonical fields below.",
161
+ "description": "Aggregate run-level metrics. Forward-compat: readers MUST tolerate missing/unknown fields. Fields are populated lazily as the engine emits them absence does NOT mean zero. Implementation-specific fields (e.g., legacy `cost: number` estimates) MAY appear alongside the spec-canonical fields below.",
162
162
  "properties": {
163
163
  "openwopCost": {
164
164
  "type": "object",
165
- "description": "Spec-canonical cost rollup aggregated from per-node `recordCost()` calls. Keys mirror the `openwop.cost.*` OTel attribute allowlist (see `observability.md` \u00a7Cost attribution). Named `openwopCost` rather than `cost` because some implementations carry a legacy `metrics.cost: number` estimate that predates the typed rollup; using a distinct name avoids collision. Multi-provider runs report `provider`/`model` of the LAST contributing call; SDKs that need per-call detail SHOULD subscribe to OTel spans instead of reading this rollup.",
165
+ "description": "Spec-canonical cost rollup aggregated from per-node `recordCost()` calls. Keys mirror the `openwop.cost.*` OTel attribute allowlist (see `observability.md` §Cost attribution). Named `openwopCost` rather than `cost` because some implementations carry a legacy `metrics.cost: number` estimate that predates the typed rollup; using a distinct name avoids collision. Multi-provider runs report `provider`/`model` of the LAST contributing call; SDKs that need per-call detail SHOULD subscribe to OTel spans instead of reading this rollup.",
166
166
  "properties": {
167
167
  "usd": {
168
168
  "type": "number",
@@ -201,27 +201,6 @@
201
201
  }
202
202
  },
203
203
  "additionalProperties": false
204
- },
205
- "parentRunId": {
206
- "$ref": "ids.schema.json#/$defs/runId",
207
- "description": "RFC 0022 / `runs.md` \u00a7forkRun \u2014 the run this one was forked from, absent on a root run. Declared because the object is closed: a fork\u2019s lineage is real protocol state, and an undeclared field on a closed object is deleted rather than ignored."
208
- },
209
- "inputs": {
210
- "type": "object",
211
- "description": "RFC 0022 \u00a7A \u2014 the inputs the run was created with. Declared for the same reason as parentRunId: the v1 wire carried it under an open schema, and closing the object without a seat would force every host to drop it.",
212
- "additionalProperties": true
213
- },
214
- "extensions": {
215
- "type": "object",
216
- "additionalProperties": false,
217
- "patternProperties": {
218
- "^[a-z][a-z0-9]*(-[a-z0-9]+)*\\.[a-z][a-z0-9]*(-[a-z0-9]+)*$": {
219
- "type": "object",
220
- "additionalProperties": true,
221
- "description": "A vendor/host extension record; its shape is the org\u2019s, declared open on purpose."
222
- }
223
- },
224
- "description": "RFC 0169 \u00a7A.4 \u2014 the seat for host-specific snapshot state, keyed `<org>.<name>`. Closing an object without an extension seat does not make hosts stop having extra state; it makes them delete it or serve an invalid document. Every other closed v2 surface has this seat and the snapshot was the omission."
225
204
  }
226
205
  },
227
206
  "additionalProperties": false