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

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 (39) hide show
  1. package/CORPUS-STAMP.json +39 -36
  2. package/api/seams-v2.yaml +1 -1
  3. package/api/v2/asyncapi.yaml +1 -1
  4. package/api/v2/openapi.yaml +17 -19
  5. package/package.json +18 -5
  6. package/schemas/capabilities.schema.json +40 -1
  7. package/schemas/certification-bundle-v2.schema.json +119 -27
  8. package/schemas/run-snapshot.schema.json +103 -33
  9. package/schemas/v2/agent-deployment-transition.schema.json +5 -6
  10. package/schemas/v2/agent-deployment.schema.json +8 -9
  11. package/schemas/v2/agent-eval-suite.schema.json +11 -12
  12. package/schemas/v2/artifact-type-pack-manifest.schema.json +22 -18
  13. package/schemas/v2/capabilities.schema.json +39 -0
  14. package/schemas/v2/certification-bundle.schema.json +1 -1
  15. package/schemas/v2/chat-card-pack-manifest.schema.json +19 -15
  16. package/schemas/v2/debug-bundle.schema.json +6 -6
  17. package/schemas/v2/error-envelope.schema.json +185 -138
  18. package/schemas/v2/eval-summary.schema.json +17 -10
  19. package/schemas/v2/goal.schema.json +5 -5
  20. package/schemas/v2/ids.schema.json +120 -22
  21. package/schemas/v2/node-pack-manifest.schema.json +27 -31
  22. package/schemas/v2/proposal.schema.json +7 -8
  23. package/schemas/v2/run-event-payloads.schema.json +258 -245
  24. package/schemas/v2/run-event.schema.json +2 -126
  25. package/schemas/v2/run-options.schema.json +1 -1
  26. package/schemas/v2/run-snapshot.schema.json +34 -13
  27. package/schemas/v2/webhook-delivery.schema.json +26 -0
  28. package/schemas/v2/workflow-chain-pack-manifest.schema.json +41 -45
  29. package/schemas/v2/workflow-definition.schema.json +31 -36
  30. package/spec/v1/core-standard-manifest.json +2 -2
  31. package/spec/v1/deprecations.json +79 -67
  32. package/spec/v1/deprecations.schema.json +23 -7
  33. package/spec/v1/extensions.json +3 -2
  34. package/spec/v2/declaration.json +34 -6
  35. package/spec/v2/errors.json +421 -360
  36. package/spec/v2/id-field-bindings.json +105 -0
  37. package/spec/v2/profiles.json +27 -6
  38. package/spec/v2/release.json +2 -2
  39. package/spec/v2/retention-floors.json +35 -0
@@ -105,14 +105,14 @@
105
105
  }
106
106
  },
107
107
  "configurableSchema": {
108
- "description": "Optional JSON Schema 2020-12 declaring which RunOptions.configurable keys this workflow accepts. When present, hosts MUST validate POST /v1/runs `configurable` payloads against this schema and reject mismatches with `validation_error`. Hosts MUST surface this schema on GET /v1/workflows/{workflowId} so clients can pre-flight-validate. See run-options.md §'Per-workflow configurableSchema'. Additive in v1.1.",
108
+ "description": "Optional JSON Schema 2020-12 declaring which RunOptions.configurable keys this workflow accepts. When present, hosts MUST validate POST /v1/runs `configurable` payloads against this schema and reject mismatches with `validation_error`. Hosts MUST surface this schema on GET /v1/workflows/{workflowId} so clients can pre-flight-validate. See run-options.md \u00a7'Per-workflow configurableSchema'. Additive in v1.1.",
109
109
  "type": "object",
110
110
  "additionalProperties": true
111
111
  },
112
112
  "defaults": {
113
113
  "type": "object",
114
114
  "additionalProperties": false,
115
- "description": "RFC 0029 §B. Workflow-author-controlled per-kind fallback values that apply at resolution chain layer 3 (`workflow-defaults`) per `spec/v1/prompts.md` §\"Resolution chain (normative)\". Applied when neither the node (layer 1) nor the node's bound agent (layer 2) specifies a value for the kind. Future RFCs MAY add sibling defaults (e.g., `defaults.temperature`, `defaults.modelClass`) without colliding.",
115
+ "description": "RFC 0029 \u00a7B. Workflow-author-controlled per-kind fallback values that apply at resolution chain layer 3 (`workflow-defaults`) per `spec/v1/prompts.md` \u00a7\"Resolution chain (normative)\". Applied when neither the node (layer 1) nor the node's bound agent (layer 2) specifies a value for the kind. Future RFCs MAY add sibling defaults (e.g., `defaults.temperature`, `defaults.modelClass`) without colliding.",
116
116
  "properties": {
117
117
  "promptRefs": {
118
118
  "type": "object",
@@ -174,13 +174,11 @@
174
174
  "id": {
175
175
  "type": "string",
176
176
  "minLength": 1,
177
- "description": "Node identifier, unique within the workflow. Intentionally has NO `maxLength` RFC 0013 chain expansion mints ids of the form `${chainIdSlug}_${expansionId}_${fragmentId}` where `chainIdSlug` is an unbounded reverse-DNS string, so an expanded node id can exceed any short cap. A host MUST NOT reject or truncate a node id by length (no host-imposed `maxLength` stricter than this schema)."
177
+ "description": "Node identifier, unique within the workflow. Intentionally has NO `maxLength` \u2014 RFC 0013 chain expansion mints ids of the form `${chainIdSlug}_${expansionId}_${fragmentId}` where `chainIdSlug` is an unbounded reverse-DNS string, so an expanded node id can exceed any short cap. A host MUST NOT reject or truncate a node id by length (no host-imposed `maxLength` stricter than this schema)."
178
178
  },
179
179
  "typeId": {
180
- "type": "string",
181
- "description": "Canonical node type ID (e.g., 'core.ai.callPrompt', 'core.chat.approvalGate'). Reserved prefixes: 'core.*' for spec-canonical, 'vendor.<org>.*' for third-party.",
182
- "minLength": 1,
183
- "pattern": "^[a-z][a-zA-Z0-9._-]*$"
180
+ "$ref": "ids.schema.json#/$defs/typeId",
181
+ "description": "Canonical node type ID (e.g., 'core.ai.callPrompt', 'core.chat.approvalGate'). Reserved prefixes: 'core.*' for spec-canonical, 'vendor.<org>.*' for third-party."
184
182
  },
185
183
  "name": {
186
184
  "type": "string",
@@ -204,7 +202,7 @@
204
202
  },
205
203
  "config": {
206
204
  "type": "object",
207
- "description": "Node configuration (pre-execution constants). The shape is per-typeId node-pack manifests declare each typeId's `configSchema` for install-time validation. By convention, the keys `systemPromptRef`, `userPromptRef`, and `additionalPromptRefs` MAY hold PromptRef values per `spec/v1/prompts.md` §\"PromptRef\" (RFC 0027). Hosts advertising `capabilities.prompts.supported: true` MUST resolve these keys; hosts without the capability MAY treat them as opaque strings. When both an inline body (e.g., `config.systemPrompt`) and a `*PromptRef` are present, the ref wins and the host MUST emit a `log.appended` warning with `code: \"prompt_ref_supersedes_inline\"` per RFC 0027 §C.",
205
+ "description": "Node configuration (pre-execution constants). The shape is per-typeId \u2014 node-pack manifests declare each typeId's `configSchema` for install-time validation. By convention, the keys `systemPromptRef`, `userPromptRef`, and `additionalPromptRefs` MAY hold PromptRef values per `spec/v1/prompts.md` \u00a7\"PromptRef\" (RFC 0027). Hosts advertising `capabilities.prompts.supported: true` MUST resolve these keys; hosts without the capability MAY treat them as opaque strings. When both an inline body (e.g., `config.systemPrompt`) and a `*PromptRef` are present, the ref wins and the host MUST emit a `log.appended` warning with `code: \"prompt_ref_supersedes_inline\"` per RFC 0027 \u00a7C.",
208
206
  "additionalProperties": true
209
207
  },
210
208
  "inputs": {
@@ -227,7 +225,7 @@
227
225
  "primary",
228
226
  "secondary"
229
227
  ],
230
- "description": "RFC 0065 author hint that this terminal node's output is the workflow's primary deliverable (`primary`) or an auxiliary output (`secondary`). Advisory: hosts MUST execute the workflow identically regardless of value. Tooling MAY use the hint to pick which of N terminal nodes' outputs to surface as the run's canonical artifact. Unknown values + absent values fall back to default behavior (show all terminal outputs)."
228
+ "description": "RFC 0065 \u2014 author hint that this terminal node's output is the workflow's primary deliverable (`primary`) or an auxiliary output (`secondary`). Advisory: hosts MUST execute the workflow identically regardless of value. Tooling MAY use the hint to pick which of N terminal nodes' outputs to surface as the run's canonical artifact. Unknown values + absent values fall back to default behavior (show all terminal outputs)."
231
229
  },
232
230
  "disabled": {
233
231
  "type": "boolean",
@@ -249,35 +247,34 @@
249
247
  },
250
248
  "artifactType": {
251
249
  "type": "string",
252
- "description": "Artifact type this node produces or reviews (first-class typed field replaces the deprecated config.outputArtifactType bag entry)."
250
+ "description": "Artifact type this node produces or reviews (first-class typed field \u2014 replaces the deprecated config.outputArtifactType bag entry)."
253
251
  },
254
252
  "cardType": {
255
253
  "type": "string",
256
- "description": "Explicit chat card type override (first-class typed field replaces the deprecated config.chatCard bag entry)."
254
+ "description": "Explicit chat card type override (first-class typed field \u2014 replaces the deprecated config.chatCard bag entry)."
257
255
  },
258
256
  "outputSensitivity": {
259
257
  "type": "object",
260
258
  "additionalProperties": {
261
259
  "type": "boolean"
262
260
  },
263
- "description": "Per-output-port sensitivity overrides. Map of port name boolean. When true, the engine masks the named output value in `node.completed` event payloads. Layered on top of pack-level `nodes[].outputs[port].sensitive` declarations: workflow-level true takes precedence over pack-level false (and vice versa last writer wins, but typically pack defaults are conservative and workflow overrides are explicit). See observability.md §Privacy classification (closes O5)."
261
+ "description": "Per-output-port sensitivity overrides. Map of port name \u2192 boolean. When true, the engine masks the named output value in `node.completed` event payloads. Layered on top of pack-level `nodes[].outputs[port].sensitive` declarations: workflow-level true takes precedence over pack-level false (and vice versa \u2014 last writer wins, but typically pack defaults are conservative and workflow overrides are explicit). See observability.md \u00a7Privacy classification (closes O5)."
264
262
  },
265
263
  "compensation": {
266
264
  "type": "object",
267
- "description": "RFC 0151 §B the inverse action for this node. OPTIONAL and closed. `nodeTypeId` MUST resolve at registration, so an unwind cannot fail on a typo discovered only during a failure. Inputs MUST derive from RECORDED FACTS: prompt or model regeneration MUST NOT construct a compensation input during replay, because a compensation built from a re-inferred value is not the inverse of what was actually done. A host MUST reject a compensation cycle.",
265
+ "description": "RFC 0151 \u00a7B \u2014 the inverse action for this node. OPTIONAL and closed. `nodeTypeId` MUST resolve at registration, so an unwind cannot fail on a typo discovered only during a failure. Inputs MUST derive from RECORDED FACTS: prompt or model regeneration MUST NOT construct a compensation input during replay, because a compensation built from a re-inferred value is not the inverse of what was actually done. A host MUST reject a compensation cycle.",
268
266
  "additionalProperties": false,
269
267
  "required": [
270
268
  "nodeTypeId"
271
269
  ],
272
270
  "properties": {
273
271
  "nodeTypeId": {
274
- "type": "string",
275
- "minLength": 1,
272
+ "$ref": "ids.schema.json#/$defs/typeId",
276
273
  "description": "Node type implementing the inverse action. MUST resolve at registration time."
277
274
  },
278
275
  "inputMapping": {
279
276
  "type": "object",
280
- "description": "Derived from recorded facts only node outputs and run inputs already in the event log.",
277
+ "description": "Derived from recorded facts only \u2014 node outputs and run inputs already in the event log.",
281
278
  "additionalProperties": true
282
279
  },
283
280
  "retry": {
@@ -296,17 +293,17 @@
296
293
  },
297
294
  "requiresApproval": {
298
295
  "type": "boolean",
299
- "description": "RFC 0151 §C an inverse action can itself be harmful (RFC 0147 R9), so it may be gated behind the same approval surface as a forward effect."
296
+ "description": "RFC 0151 \u00a7C \u2014 an inverse action can itself be harmful (RFC 0147 R9), so it may be gated behind the same approval surface as a forward effect."
300
297
  },
301
298
  "waiveRequiresApproval": {
302
299
  "type": "boolean",
303
- "description": "RFC 0151 §B/§E (S36, 2026-08-17) OPTIONAL. When true, ABANDONING this inverse action (§E `skip with justification` or `terminate as uncompensated`) requires an RFC 0051 approval to have resolved `approved` first if a human must authorize RUNNING an inverse, a human must authorize deciding it will NEVER run. DEFAULT = the obligation's EFFECTIVE `requiresApproval` (after the policy's `approvalScope` escalation, §B) NOT false so the field is purely additive: no existing document changes meaning. Stamped onto the obligation at MINT time like `requiresApproval` (a mid-flight redefinition cannot change who had to authorize). Does NOT apply to `substitute` (still an attempt to undo; a substitution is a new planVersion whose own `requiresApproval` governs it). No policy-level counterpart: because the default inherits the effective value, an `approvalScope` escalation escalates waives with it."
300
+ "description": "RFC 0151 \u00a7B/\u00a7E (S36, 2026-08-17) \u2014 OPTIONAL. When true, ABANDONING this inverse action (\u00a7E `skip with justification` or `terminate as uncompensated`) requires an RFC 0051 approval to have resolved `approved` first \u2014 if a human must authorize RUNNING an inverse, a human must authorize deciding it will NEVER run. DEFAULT = the obligation's EFFECTIVE `requiresApproval` (after the policy's `approvalScope` escalation, \u00a7B) \u2014 NOT false \u2014 so the field is purely additive: no existing document changes meaning. Stamped onto the obligation at MINT time like `requiresApproval` (a mid-flight redefinition cannot change who had to authorize). Does NOT apply to `substitute` (still an attempt to undo; a substitution is a new planVersion whose own `requiresApproval` governs it). No policy-level counterpart: because the default inherits the effective value, an `approvalScope` escalation escalates waives with it."
304
301
  }
305
302
  }
306
303
  },
307
304
  "irreversibleEffect": {
308
305
  "type": "boolean",
309
- "description": "RFC 0151 §B (UQ4, resolved 2026-08-16) the author states that this node's committed effect HAS NO INVERSE. OPTIONAL; absent or false means nothing (an undeclared compensator is still not implied). Mutually exclusive with `compensation`: a node declaring both is contradictory and a host MUST reject it at registration (`validation_error`). When true and the node's effect committed before an unwind starts, the plan records the node as `irreversible` (never completed) so the §D rollup caps at `partial` a reader can no longer infer a full undo from a `completed` that quietly skipped it."
306
+ "description": "RFC 0151 \u00a7B (UQ4, resolved 2026-08-16) \u2014 the author states that this node's committed effect HAS NO INVERSE. OPTIONAL; absent or false means nothing (an undeclared compensator is still not implied). Mutually exclusive with `compensation`: a node declaring both is contradictory and a host MUST reject it at registration (`validation_error`). When true and the node's effect committed before an unwind starts, the plan records the node as `irreversible` (never completed) so the \u00a7D rollup caps at `partial` \u2014 a reader can no longer infer a full undo from a `completed` that quietly skipped it."
310
307
  }
311
308
  },
312
309
  "additionalProperties": false,
@@ -341,16 +338,14 @@
341
338
  "minLength": 1
342
339
  },
343
340
  "sourceNodeId": {
344
- "type": "string",
345
- "minLength": 1
341
+ "$ref": "ids.schema.json#/$defs/nodeId"
346
342
  },
347
343
  "sourceOutput": {
348
344
  "type": "string",
349
345
  "description": "Source output port key. Default 'output'."
350
346
  },
351
347
  "targetNodeId": {
352
- "type": "string",
353
- "minLength": 1
348
+ "$ref": "ids.schema.json#/$defs/nodeId"
354
349
  },
355
350
  "targetInput": {
356
351
  "type": "string",
@@ -390,14 +385,14 @@
390
385
  "truthy",
391
386
  "falsy"
392
387
  ],
393
- "description": "Operator. `equals`/`notEquals`/`contains` compare `left` to `right`; `regex` matches `left` against `right`; `expression` evaluates `expression`. RFC 0134: `truthy`/`falsy` test the resolved value at `left` for JS-style truthiness and take NO `right` operand (the edge contributes iff `left` is truthy resp. falsy/absent). `left` is required for all operators except `expression`."
388
+ "description": "Operator. `equals`/`notEquals`/`contains` compare `left` to `right`; `regex` matches `left` against `right`; `expression` evaluates `expression`. RFC 0134: `truthy`/`falsy` test the resolved value at `left` for JS-style truthiness and take NO `right` operand (the edge contributes iff `left` is truthy \u2014 resp. falsy/absent). `left` is required for all operators except `expression`."
394
389
  },
395
390
  "left": {
396
391
  "type": "string",
397
392
  "description": "Left operand path (e.g., 'status', 'output.approved'). Required for every operator except `expression`."
398
393
  },
399
394
  "right": {
400
- "description": "Right operand value (any JSON value). Meaningless for `truthy`/`falsy` (RFC 0134) a host MUST ignore it there, not error."
395
+ "description": "Right operand value (any JSON value). Meaningless for `truthy`/`falsy` (RFC 0134) \u2014 a host MUST ignore it there, not error."
401
396
  },
402
397
  "expression": {
403
398
  "type": "string",
@@ -512,7 +507,7 @@
512
507
  "chat-message",
513
508
  "channel-write"
514
509
  ],
515
- "description": "Trigger discriminator. The `channel-write` variant fires a node when a named channel receives a write (closes C2 reactive cross-engine pattern). Its `config` shape: `{channel: string, onlyFrom?: 'child'|'parent'|'any', debounceMs?: integer}`. See channels-and-reducers.md §Distributed reducers."
510
+ "description": "Trigger discriminator. The `channel-write` variant fires a node when a named channel receives a write (closes C2 \u2014 reactive cross-engine pattern). Its `config` shape: `{channel: string, onlyFrom?: 'child'|'parent'|'any', debounceMs?: integer}`. See channels-and-reducers.md \u00a7Distributed reducers."
516
511
  },
517
512
  "name": {
518
513
  "type": "string"
@@ -569,12 +564,12 @@
569
564
  "sensitive": {
570
565
  "type": "boolean",
571
566
  "default": false,
572
- "description": "When true, the engine masks this variable's value in persisted `variable.changed` events, `state.snapshot` projections, and `RunSnapshot.variables`. Reads inside NodeModule executors work normally; only persistence + external surfaces mask. See observability.md §Privacy classification (closes O5)."
567
+ "description": "When true, the engine masks this variable's value in persisted `variable.changed` events, `state.snapshot` projections, and `RunSnapshot.variables`. Reads inside NodeModule executors work normally; only persistence + external surfaces mask. See observability.md \u00a7Privacy classification (closes O5)."
573
568
  },
574
569
  "format": {
575
570
  "type": "string",
576
571
  "minLength": 1,
577
- "description": "RFC 0136 (`Active`). ADVISORY presentational hint for a `type: \"string\"` variable, drawn from the JSON-Schema format vocabulary (`email`, `uri`, `date`, `date-time`, `time`, `duration` are the v1 recognised set). Hosts SHOULD use it to choose an input affordance (e.g. an email keyboard). It is NOT a validation contract: a host MUST NOT reject a run, refuse a variable write, or fail validation because a value does not match, and MUST NOT assume a value matches when reading it. DELIBERATELY NOT AN ENUM an unrecognised value MUST round-trip and degrade to plain text rather than error (RFC 0136 requirement 2), which an enum would turn into a hard validation failure on a client-submitted (closed) shape. Ignored when `type` is not `\"string\"`. Orthogonal to `sensitive`: masking hides the VALUE on server-emitted surfaces, `format` describes the FIELD in the definition, so the two compose with no interaction."
572
+ "description": "RFC 0136 (`Active`). ADVISORY presentational hint for a `type: \"string\"` variable, drawn from the JSON-Schema format vocabulary (`email`, `uri`, `date`, `date-time`, `time`, `duration` are the v1 recognised set). Hosts SHOULD use it to choose an input affordance (e.g. an email keyboard). It is NOT a validation contract: a host MUST NOT reject a run, refuse a variable write, or fail validation because a value does not match, and MUST NOT assume a value matches when reading it. DELIBERATELY NOT AN ENUM \u2014 an unrecognised value MUST round-trip and degrade to plain text rather than error (RFC 0136 requirement 2), which an enum would turn into a hard validation failure on a client-submitted (closed) shape. Ignored when `type` is not `\"string\"`. Orthogonal to `sensitive`: masking hides the VALUE on server-emitted surfaces, `format` describes the FIELD in the definition, so the two compose with no interaction."
578
573
  }
579
574
  },
580
575
  "additionalProperties": false
@@ -607,7 +602,7 @@
607
602
  "nodeIds": {
608
603
  "type": "array",
609
604
  "items": {
610
- "type": "string"
605
+ "$ref": "ids.schema.json#/$defs/nodeId"
611
606
  }
612
607
  },
613
608
  "position": {
@@ -653,7 +648,7 @@
653
648
  "properties": {
654
649
  "reducer": {
655
650
  "type": "string",
656
- "description": "Canonical names: 'replace', 'append', 'merge', 'counter', 'votes', 'feedback', 'message' (Multi-Agent Shift Phase 1 append-only + idempotent on `messageId`). Custom reducers MUST use 'vendor.<org>.<name>'.",
651
+ "description": "Canonical names: 'replace', 'append', 'merge', 'counter', 'votes', 'feedback', 'message' (Multi-Agent Shift Phase 1 \u2014 append-only + idempotent on `messageId`). Custom reducers MUST use 'vendor.<org>.<name>'.",
657
652
  "pattern": "^(replace|append|merge|counter|votes|feedback|message|vendor\\.[a-z][a-z0-9_-]*\\.[a-z][a-z0-9_-]*)$"
658
653
  },
659
654
  "schema": {
@@ -669,7 +664,7 @@
669
664
  "type": "integer",
670
665
  "minimum": 1,
671
666
  "maximum": 31536000000,
672
- "description": "Optional entry-age TTL in milliseconds (closes C3). Applies to `append` / `votes` / `feedback` reducers; ignored on others. Engine drops entries older than this age (lazy: on read or next write). Range: 1..1 year. Replay-safe uses original event timestamps for comparison. See channels-and-reducers.md §Channel TTL."
667
+ "description": "Optional entry-age TTL in milliseconds (closes C3). Applies to `append` / `votes` / `feedback` reducers; ignored on others. Engine drops entries older than this age (lazy: on read or next write). Range: 1..1 year. Replay-safe \u2014 uses original event timestamps for comparison. See channels-and-reducers.md \u00a7Channel TTL."
673
668
  },
674
669
  "options": {
675
670
  "type": "object",
@@ -691,18 +686,18 @@
691
686
  "minimum": 1
692
687
  },
693
688
  "uniqueItems": true,
694
- "description": "Older schema versions whose persisted writes are forward-readable under the CURRENT schema. The engine validates each old write against the current schema during fold; pass = include, fail = hard error `channel_schema_breaking_change`. Empty/omitted = no backward compat (any older write trips the breaking-change error). For breaking edits, authors create a new channel name + a copy node see channels-and-reducers.md §Channel schema migration."
689
+ "description": "Older schema versions whose persisted writes are forward-readable under the CURRENT schema. The engine validates each old write against the current schema during fold; pass = include, fail = hard error `channel_schema_breaking_change`. Empty/omitted = no backward compat (any older write trips the breaking-change error). For breaking edits, authors create a new channel name + a copy node \u2014 see channels-and-reducers.md \u00a7Channel schema migration."
695
690
  },
696
691
  "sensitive": {
697
692
  "type": "boolean",
698
693
  "default": false,
699
- "description": "When true, the engine masks `channel.written` event payloads' `value` field. The reduced channel state in `RunSnapshot.channels` is also masked when read via the REST surface. See observability.md §Privacy classification (closes O5)."
694
+ "description": "When true, the engine masks `channel.written` event payloads' `value` field. The reduced channel state in `RunSnapshot.channels` is also masked when read via the REST surface. See observability.md \u00a7Privacy classification (closes O5)."
700
695
  }
701
696
  },
702
697
  "additionalProperties": false
703
698
  },
704
699
  "ChannelAccess": {
705
- "description": "Per-channel access control. See channels-and-reducers.md §Channel access control (closes C1). Three forms: 'public' (no restriction; same as omitting), 'private' (lockdown shorthand equivalent to {readers: [], writers: []}), or an explicit {readers?, writers?} object where each side is independently scoped (omitted = open, present = strict allowlist).",
700
+ "description": "Per-channel access control. See channels-and-reducers.md \u00a7Channel access control (closes C1). Three forms: 'public' (no restriction; same as omitting), 'private' (lockdown shorthand \u2014 equivalent to {readers: [], writers: []}), or an explicit {readers?, writers?} object where each side is independently scoped (omitted = open, present = strict allowlist).",
706
701
  "oneOf": [
707
702
  {
708
703
  "const": "public"
@@ -804,7 +799,7 @@
804
799
  "regulated"
805
800
  ],
806
801
  "default": "public",
807
- "description": "Top-level workflow sensitivity tier. Sets the `openwop.compliance_class` span attribute on every span the run produces. Drives default retention / masking / export-gating policy at observability collectors. See observability.md §Privacy classification (closes O5)."
802
+ "description": "Top-level workflow sensitivity tier. Sets the `openwop.compliance_class` span attribute on every span the run produces. Drives default retention / masking / export-gating policy at observability collectors. See observability.md \u00a7Privacy classification (closes O5)."
808
803
  },
809
804
  "complianceConfig": {
810
805
  "type": "object",
@@ -854,7 +849,7 @@
854
849
  },
855
850
  "compensation": {
856
851
  "$ref": "compensation-policy.schema.json",
857
- "description": "RFC 0151 §B the workflow-level compensation policy (WHEN an unwind starts and HOW it runs). OPTIONAL and capability-gated: a host that advertises `capabilities.compensation` MUST validate it at registration; a host that does not MUST refuse the workflow with `capability_required` rather than accept a policy it will never honour. Node-level `nodes[].compensation` declarations remain valid without it they describe the inverse action; this key requests the unwind."
852
+ "description": "RFC 0151 \u00a7B \u2014 the workflow-level compensation policy (WHEN an unwind starts and HOW it runs). OPTIONAL and capability-gated: a host that advertises `capabilities.compensation` MUST validate it at registration; a host that does not MUST refuse the workflow with `capability_required` rather than accept a policy it will never honour. Node-level `nodes[].compensation` declarations remain valid without it \u2014 they describe the inverse action; this key requests the unwind."
858
853
  }
859
854
  },
860
855
  "additionalProperties": false
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.0.0-rc.6"
7
+ "version": "2.0.0-rc.60"
8
8
  },
9
9
  "note": "Derived from the corpus at generation time. Regenerate with --write; verify with --check."
10
10
  },
@@ -419,5 +419,5 @@
419
419
  "$id": "https://openwop.dev/spec/v1/workspace-file.schema.json"
420
420
  }
421
421
  ],
422
- "digest": "68425d02115f2ac15d7145694b8bea019ba7c8757a299e4ab0378330ea6322de"
422
+ "digest": "7a832066cef86b863d1996f0a351356897d99dcebddd6e6efc33db37305a2acd"
423
423
  }