@openwop/spec-artifacts 2.33.2 → 2.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CORPUS-STAMP.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "_comment": "Provenance of @openwop/spec-artifacts (RFC 0168 §D.2). files: SHA-256 per file; the conformance suite compares the installed peer against dist/spec-artifacts.lock.json at start.",
3
3
  "package": "@openwop/spec-artifacts",
4
- "version": "2.33.2",
5
- "corpusTag": "v2.33.0",
4
+ "version": "2.34.1",
5
+ "corpusTag": "v2.34.0",
6
6
  "files": {
7
7
  "api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
8
8
  "api/asyncapi.yaml": "d5ecb9ee6114582be3b1f662c84bfac9ae96dae7bacb853e461168f70a8e1c7d",
9
9
  "api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
10
10
  "api/openapi.yaml": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
11
11
  "api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
12
- "api/seams-v2.yaml": "975b6cd87fa679857df9fcdc60b6a2bed98510b831e82a5eff5a114e3b263f6e",
13
- "api/v2/asyncapi.yaml": "96ba13176119bbf54a94bd41d789ebaa919f67c81d529bdc3c66ffb3f419ee36",
14
- "api/v2/openapi.yaml": "428ab881d0a8d08d388dd89d4b4457f3454cd0433b665674180d3e85821b978d",
12
+ "api/seams-v2.yaml": "d26d906b044e53fbb6ba742be90c853b9dcf14af4005bb6376e354d618fbdd5a",
13
+ "api/v2/asyncapi.yaml": "eda3679b6902a3ab931e2dab55a04f6b6bb2b9b664748de38d8a104e53e93c76",
14
+ "api/v2/openapi.yaml": "313fc72043a3730fbb98fdf47f4539773564bf9c5bed54f1f180efb50cf57410",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
@@ -116,7 +116,7 @@
116
116
  "schemas/v2/audit-verify-result.schema.json": "a748dfadb5155adfde8a91045e76b0db6695005fe559035d71670fdd55edb3ba",
117
117
  "schemas/v2/budget-policy.schema.json": "c7449daeb6e1d95e7a047b8c2814d3d54748697c27046972834874867d9b5f4c",
118
118
  "schemas/v2/capabilities.schema.json": "e62d44f23c21c8f64b273fcdb083636e801c0de976cbd1f93333f99928dd1025",
119
- "schemas/v2/certification-bundle.schema.json": "ab9204e37f9e0bba79857275cd38be2da98e54d26b4ecb97469829efe6ebea28",
119
+ "schemas/v2/certification-bundle.schema.json": "46a5a07670f2457bf1b7af8f6df1f4f76edb3ff7e64d1b6ed85738270c95668e",
120
120
  "schemas/v2/channel-presence-payload.schema.json": "1c20ad810cb311d47aa0b95d928490826b2468fd161f884cd29e867053e6782f",
121
121
  "schemas/v2/channel-written-payload.schema.json": "ccecff3c71a3275ad8db035ac0e04db25e6f8d23cf091ddbcd5a60d1be1cbb6b",
122
122
  "schemas/v2/chat-card-pack-manifest.schema.json": "f7cf09b30d3e1d2251620d84ea9f65541438d015ab44aec10d1dcfe68d8bd496",
@@ -201,7 +201,7 @@
201
201
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
202
202
  "spec/v1/alias-detectors.json": "40069d5976eeb6ba1384a648e57e5cfd673db3fce36175115fb8293bee9664d4",
203
203
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
204
- "spec/v1/core-standard-manifest.json": "65a8576c2e5ea9deb9d463be5b02a8bfb0e125a8dcbe3fe2cf286a4fd6d5d53e",
204
+ "spec/v1/core-standard-manifest.json": "0c1aaddf25eefbbe473d543067838a4a8eed8d3e5c00b55ce0ca98eabbc1ce66",
205
205
  "spec/v1/deprecations.json": "307083ce29c23fd406015951f99a30d78d6187ff061d38dc9732f62191b40f3f",
206
206
  "spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
207
207
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
@@ -215,7 +215,7 @@
215
215
  "spec/v1/spec-gaps.json": "eb3bfcb9c7d05c9a6845d4a40ec9493cfaa5a671932daf1af561310136fdabe8",
216
216
  "spec/v2/README.md": "8dbfc17b10f373dba95bdd2e8fec0580f35b380a834d304be3e24e7498170185",
217
217
  "spec/v2/core/capabilities.md": "4c4e5577caf4ae20c84fe59d580de4c6599e76783471d3b59f9730fc3807de71",
218
- "spec/v2/core/conformance.md": "a451c0a2ba79d93c55e540ccef480eba7de9602d59bbb03eead05daafde0beac",
218
+ "spec/v2/core/conformance.md": "e5cb403f6ea6633eebc8ee4fa7bde5bf023bf4aee7c959b849e7105d37ab1f8b",
219
219
  "spec/v2/core/connection-packs.md": "466bdb9dde79d85615ad8281dacfb7bf923ca22d7fb3ed219749e59574c753ed",
220
220
  "spec/v2/core/conversation.md": "e425887c4ba199b8cdc5c99e792689f7bd7d46de492f28670de2e402fa6d9506",
221
221
  "spec/v2/core/errors.md": "0dff4a0ae102a86f6a17a9a3b16a203292588a0f422ed19d1c0d9213995aa01d",
@@ -229,7 +229,7 @@
229
229
  "spec/v2/core/interrupt.md": "3a926d84b942d4ee7daccc4443c93dc29f6a69f2936ba813182f2c1336db2cbb",
230
230
  "spec/v2/core/overview.md": "7dc00ace32d4e4ce929a383651f0029fc4b7091ec87487b1bf26ead1be209e0e",
231
231
  "spec/v2/core/packs.md": "1c0919059760f9a3940a93264a76b7e30f9a0f6f27ff19753cc88f15753d8088",
232
- "spec/v2/core/persistence.md": "9e241f84259e38848f4a2ad1c21debb0dffd5f8aafbad26408aa6cc8969bf93b",
232
+ "spec/v2/core/persistence.md": "9785e536362ec2000dab7fee9847543240d40a907745efc70cf2c8b4c1b8344e",
233
233
  "spec/v2/core/replay.md": "b980a66e2543107240e3dc4f58131b9f4ff52478737e79ade6d5777b26ad1119",
234
234
  "spec/v2/core/runs.md": "136319842bacbbb300178980e4b83444917d5b193cc5fdd92e39a4902ba8d3c0",
235
235
  "spec/v2/core/security-defaults.md": "2a54ceaa4cef02c26ee0fbcf44f822ceeea79537c7d5a51ed300f21aa4fea576",
@@ -279,8 +279,8 @@
279
279
  "spec/v2/path-manifest.json": "c123c9fd77dc1b3f9c2e9346ace80cdae007e6511138894956abda01e61ec1c6",
280
280
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
281
281
  "spec/v2/profiles.json": "0636f19fceae625390003a347e70ef4797d84766b5c24ce8a02cea52aadebca4",
282
- "spec/v2/release.json": "94a3ea302324d9f7df87ce62a186b0b98936de6ce5ac5ec01a3fb3208c38efc3",
282
+ "spec/v2/release.json": "eaf652e3a01f02a1d9c4eee7d7ea2c2a0396fe5694b5dce4cb01ca2af2891cc5",
283
283
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
284
284
  },
285
- "corpusCommit": "65e40d60fbf43b1a0cd95a58e63d7464ed944ddb"
285
+ "corpusCommit": "ffc0f6bf6bfe378c1e69f94386373687b15cfdb6"
286
286
  }
package/api/seams-v2.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP conformance seams profile (openwop-conformance-seams-v2)
4
- version: 2.33.0
4
+ version: 2.34.0
5
5
  description: 'GENERATED by scripts/derive-v2-api.py. RFC 0168 §C: the seams are a versioned conformance profile with their
6
6
  own document and path space (/conformance/seams/…), validated against the canonical v2 schemas with no tolerance path,
7
7
  forbidden from the capability namespace (a host advertises the profile, never a testSeams flag). This document carries
@@ -1,7 +1,7 @@
1
1
  asyncapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 event streams
4
- version: 2.33.0
4
+ version: 2.34.0
5
5
  description: GENERATED by scripts/derive-v2-api.py (RFC 0171 §E.1, RFC 0172 §C.2). One run-events channel whose address
6
6
  is the OpenAPI path key; the server pathname is empty (bare origin). streamMode is a pattern over the closed set and its
7
7
  comma-separated combinations (`values` never combines). hostEvents has a real address (RFC 0171 §E.1) — the documented
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 API
4
- version: 2.33.0
4
+ version: 2.34.0
5
5
  summary: REST surface for declaring, executing, suspending, resuming, and observing multi-step workflows.
6
6
  description: GENERATED by scripts/derive-v2-api.py from api/openapi.yaml and the RFC 0167 children (v2 charter Phase 3,
7
7
  P3-C). Bare origin, unversioned path keys, negotiation by `OpenWOP-Version` + `protocolVersions[]` (RFC 0172 §A). No seam
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/spec-artifacts",
3
- "version": "2.33.2",
3
+ "version": "2.34.1",
4
4
  "description": "The OpenWOP machine-readable contract: api/ (OpenAPI, AsyncAPI, the seams profile), schemas/ (v1 and v2 JSON Schemas), the spec/v1 and spec/v2 registries (errors, event codemap, declaration, deprecations, migrations, gaps) and CORPUS-STAMP.json — published from the openwop/openwop corpus tag; the peer dependency @openwop/openwop-conformance digest-checks at start (RFC 0168 §D.2).",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -281,6 +281,88 @@
281
281
  },
282
282
  "detail": {
283
283
  "type": "string"
284
+ },
285
+ "evidence": {
286
+ "type": "object",
287
+ "additionalProperties": false,
288
+ "minProperties": 1,
289
+ "description": "RFC 0158 §E — structured evidence for this row. OPTIONAL, and carried on the ROW rather than at the bundle root because the attestation covers witnessSha256 and witnessSha256 digests the rows: a root-level block would be unsigned. It enters the witness digest only when present, so every bundle without it digests exactly as before. Closed: one optional member per kind of evidence. Recorded for an `executed-pass` row only.",
290
+ "properties": {
291
+ "recovery": {
292
+ "type": "object",
293
+ "additionalProperties": false,
294
+ "required": [
295
+ "class",
296
+ "boundMs",
297
+ "observedMs"
298
+ ],
299
+ "description": "On a kill row (`0158.kill-after-accept`, `0158.kill-during-execution`): the recovery CLASS the exercise exercised, the bound it was judged against, and the kill → RESUMPTION interval observed (never kill → terminal, RFC 0158 §B.4). `class` MUST name an entry of `recoveryBounds[]` and `boundMs` MUST equal that entry's `bound`: That refuses an undeclared class, a bound label that disagrees with its class, and a resumption outside the bound. It does NOT refuse a host that names the wrong DECLARED class while resuming inside that class's longer bound — a seam that kills before the host holds its execution claim exercises an easier class than the one it labels, and no arithmetic separates that from a fast recovery. Recording the interval makes the mislabel visible to a reader; killing only once the claim is held remains the host's obligation (RFC 0158 §E).",
300
+ "properties": {
301
+ "class": {
302
+ "type": "string",
303
+ "pattern": "^[a-z][A-Za-z0-9._-]{0,63}$",
304
+ "description": "Opaque and host-chosen — NOT an enum. \"leased\" / \"unleased\" name one host's mechanisms and boot re-entry another's; a closed vocabulary would select for an architecture."
305
+ },
306
+ "boundMs": {
307
+ "type": "integer",
308
+ "minimum": 0
309
+ },
310
+ "observedMs": {
311
+ "type": "integer",
312
+ "minimum": 0
313
+ }
314
+ }
315
+ },
316
+ "recoveryBounds": {
317
+ "type": "array",
318
+ "minItems": 1,
319
+ "maxItems": 16,
320
+ "description": "On `0158.bound-is-derived`: the declared recovery bound PER WORK CLASS, each with the terms that produce it, so a reader can recompute it (RFC 0158 §B.5, §E). There is deliberately NO scalar overall bound: Unresolved Question 1 resolved per class, and a convenience total is the lie by aggregation that resolution rejects. This proves ARITHMETIC — that each bound follows from its stated mechanism — and MUST NOT be cited as evidence that the mechanism runs; only a kill row's `observedMs` witnesses that.",
321
+ "items": {
322
+ "type": "object",
323
+ "additionalProperties": false,
324
+ "required": [
325
+ "class",
326
+ "bound",
327
+ "terms"
328
+ ],
329
+ "properties": {
330
+ "class": {
331
+ "type": "string",
332
+ "pattern": "^[a-z][A-Za-z0-9._-]{0,63}$"
333
+ },
334
+ "bound": {
335
+ "type": "integer",
336
+ "minimum": 0,
337
+ "description": "Milliseconds. MUST equal the sum of `terms[].ms`."
338
+ },
339
+ "terms": {
340
+ "type": "array",
341
+ "minItems": 1,
342
+ "maxItems": 16,
343
+ "items": {
344
+ "type": "object",
345
+ "additionalProperties": false,
346
+ "required": [
347
+ "name",
348
+ "ms"
349
+ ],
350
+ "properties": {
351
+ "name": {
352
+ "type": "string",
353
+ "pattern": "^[a-z][A-Za-z0-9._-]{0,63}$"
354
+ },
355
+ "ms": {
356
+ "type": "integer",
357
+ "minimum": 0
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ }
365
+ }
284
366
  }
285
367
  }
286
368
  },
@@ -330,6 +412,23 @@
330
412
  },
331
413
  "description": "Required when any result is not executed-pass (allOf below). A DERIVED projection of `results.requirements[]` for readability — never an independent source of counts."
332
414
  },
415
+ "durability": {
416
+ "type": "object",
417
+ "additionalProperties": false,
418
+ "required": [
419
+ "rung"
420
+ ],
421
+ "description": "RFC 0158 §D — the qualification rung this host CLAIMS. OPTIONAL; absent means no rung is claimed, which is every host's status by default (§E.10 mints no discovery capability, so this is the only place a rung is stated). It is a CLAIM and is outside the attestation: a verifier MUST re-derive it from the signed rows — every row of the rung `executed-pass`, each kill row's `evidence.recovery.class` naming a `recoveryBounds[]` entry whose `bound` equals its `boundMs` and is not exceeded by its `observedMs`, and each entry's terms summing to its bound — and MUST reject a bundle whose claim it cannot derive (`rung-not-derivable`). Only `durable-single-instance` is derivable in this revision: `peer-resume` is bundle-witnessed by evidence not yet carried, so a higher claim is refused, not assumed.",
422
+ "properties": {
423
+ "rung": {
424
+ "enum": [
425
+ "durable-single-instance",
426
+ "durable-multi-instance",
427
+ "multi-region-qualified"
428
+ ]
429
+ }
430
+ }
431
+ },
333
432
  "signature": {
334
433
  "type": "object",
335
434
  "additionalProperties": false,
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.33.2"
7
+ "version": "2.34.1"
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": "e712cbc2b485a47c8b09b7a9f12caa6836bf6dbff25632bb74115d114143a5e7"
422
+ "digest": "cfc738eec46aca8721ebe1208a3613c3e9847a69203e017cb1e142bad676a915"
423
423
  }
@@ -67,12 +67,25 @@ A certification bundle validates against `schemas/v2/certification-bundle.schema
67
67
  | `witnessSha256` | REQUIRED; covers the reporter record |
68
68
  | `assertionCount` | REQUIRED, ≥ 1 |
69
69
  | `detail.nonPass[]` | REQUIRED when any total other than `executedPass` is non-zero |
70
+ | `results.requirements[].evidence` | OPTIONAL, closed; structured evidence on an `executed-pass` row (below) |
71
+ | `durability.rung` | OPTIONAL; a claim the verifier re-derives (below) |
70
72
  | `signature` | REQUIRED |
71
73
 
72
74
  `signature` is an Ed25519 attestation over the canonical JSON of `{ witnessSha256, host.build, suite.version, discovery.sha256 }`; `over` MUST list exactly those four members. A host that signs bundles MUST publish the corresponding public keys as `signingKeys[]` in its discovery document, and `signature.keyId` MUST name one of them. A verifier MUST resolve `keyId` there — in the discovery document of the host the bundle is *about* — and MUST verify the attestation under the published key.
73
75
 
74
76
  A signature that cannot be resolved to a published key attests **integrity only**: it proves the bundle was not altered after signing, and proves nothing about who signed it, because a signer can mint a keypair and a key id at will. Such a bundle MUST NOT be read as attributable evidence, and a gate MUST distinguish three outcomes that a presence check collapses into one — *no discovery document was read*, *read and the key is not published*, and *the attestation does not verify*. A retired key MUST stay listed, because removing it silently invalidates every bundle it already signed. `evidenceTier: independent` MUST carry a `verifierKeyId` distinct from the host's signing key; the verifier MUST refuse, not warn, on a missing or self-signed independent claim. A bundle with `totals.blocked > 0` does not certify. A profile that carries an operator relaxation (`host.relaxations[]`) cannot certify. v1 and v2 bundles are never upgraded to v3; a bundle is evidence at its own version.
75
77
 
78
+ ### Recovery evidence
79
+
80
+ RFC 0158 §E publishes a rung and its recovery bounds here instead of in discovery. The attestation covers `witnessSha256`, and `witnessSha256` digests the rows, so the evidence rides on rows: a row's `evidence` enters the digest only when present, and a bundle without it digests as it always did.
81
+
82
+ | Row | `evidence` member |
83
+ | --- | --- |
84
+ | `0158.bound-is-derived` | `recoveryBounds[]` of `{ class, bound, terms[] }`, each term `{ name, ms }`; `bound` MUST equal the sum of its terms. One entry per recovery class; there is no aggregate bound. |
85
+ | `0158.kill-after-accept`, `0158.kill-during-execution` | `recovery: { class, boundMs, observedMs }` — the class exercised, the bound it was judged against, and the observed kill-to-resumption interval. |
86
+
87
+ `class` and `name` are opaque host-chosen identifiers, never a closed vocabulary. `durability.rung` is outside the attestation, so a verifier MUST re-derive it and MUST reject (`rung-not-derivable`) a claim it cannot derive: every row of the rung `executed-pass`, each kill row's `class` naming a declared entry whose `bound` equals its `boundMs` and is not exceeded by its `observedMs`. Only `durable-single-instance` is derivable in this revision; a higher claim is refused. This proves arithmetic and that recovery ran once inside the bound. It does not prove the kill landed in the class it names; killing only once the execution claim is held is the host's obligation.
88
+
76
89
  ## Corpus-gate evidence
77
90
 
78
91
  An RFC whose acceptance criteria are corpus gates rather than host scenarios records the evidence label **corpus gate — no host tier** in its `Updated` line; the accepted-predicate check reads `(corpus)` rows from `evidence/corpus-ledger.json` for such an RFC and MUST NOT require a host bundle for it.
@@ -1,6 +1,6 @@
1
1
  # Persistence and Coexistence
2
2
 
3
- > **Status: Stable · RFC 0176 (§A–§B, §D–§E), 0171 §A, 0170 §A.3.**
3
+ > **Status: Stable · RFC 0176 (§A–§B, §D–§E), 0171 §A, 0170 §A.3, 0158 §A–§D.**
4
4
  > **Normative home:** `eventLog`.
5
5
 
6
6
  ## Why this exists
@@ -179,6 +179,20 @@ Template — one row per store:
179
179
 
180
180
  The reference hosts' dispositions are recorded in RFC 0176; a host MUST NOT decide a store's disposition during the migration.
181
181
 
182
+ ## Durable acceptance and recovery
183
+
184
+ RFC 0158 §A–§D, restated because its v1 homes (`idempotency.md`, `storage-adapters.md`) retire with v1. Nothing here is new.
185
+
186
+ | Clause | Requirement |
187
+ | --- | --- |
188
+ | Acceptance (§A) | A host that returns success for work it accepted MUST have made the intent to perform it durable in the same transaction as the work record; a wakeup, hint, or in-process dispatch MUST NOT be the only record. It MUST resume accepted-but-unstarted work after the accepting process dies, without client action. |
189
+ | Liveness (§B.3) | A host MUST distinguish how long a unit of work may legitimately run from the interval in which a live worker demonstrates liveness, and MUST NOT use the duration bound as the sole liveness signal. |
190
+ | Recovery bound (§B.4–6) | A host MUST declare the longest interval between an instance ceasing to make progress and another becoming eligible to resume its work, and MUST derive it from the mechanism that enforces it — one bound per enforcing mechanism, never a single aggregate. Any length is conformant; an undeclared or unenforced bound is not. |
191
+ | Duplicates (§C.7) | Duplicate delivery of accepted work MUST NOT produce duplicate external effects; the host MUST dedupe on an identity that survives redelivery (idempotency.md). |
192
+ | Poison work (§C.8) | Work that fails deterministically MUST reach a terminal, operator-visible state within a bounded number of attempts. |
193
+
194
+ A host MAY claim a qualification rung (`durable-single-instance`, `durable-multi-instance`, `multi-region-qualified`; cumulative) only with the evidence named for it, and MUST NOT claim one from tests in which no process was terminated (§D.9). A rung is evidence, not a capability: discovery carries none, and the rung and its bounds are published in the certification bundle (conformance.md §Bundle v3).
195
+
182
196
  ## The corpus-tag pin
183
197
 
184
198
  A consumer that vendors any file from `schemas/`, `api/`, or `spec/` MUST pin to a published `openwop-conformance/vX.Y.Z` tag, MUST record the tag, and MUST refuse a sync from any other ref. A v1.x consumer MUST NOT vendor `schemas/v2/` (RFC 0176 §E.1). The `corpus-tag-pinned` check verifies that each consumer's recorded tag resolves (conformance.md).
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$comment": "RFC 0172 §D.1 — the one release identity the v2 artifacts derive from. `version` is the next corpus tag `v<version>` (the publish workflow's coordinated-release tag pattern `v*`; RFC 0172's `openwop/v2.<minor>.<patch>` spelling is amended to this at its flip). api/v2/*.yaml info.version, the suite's 2.x version and @openwop/spec-artifacts read it. Bumped by the release PR that cuts the tag, never by hand elsewhere.",
3
- "version": "2.33.0",
4
- "corpusTag": "v2.33.0",
3
+ "version": "2.34.0",
4
+ "corpusTag": "v2.34.0",
5
5
  "updated": "2026-09-21"
6
6
  }