@openwop/spec-artifacts 2.0.8 → 2.0.10
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 +57 -57
- package/api/seams-v2.yaml +1 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +1 -1
- package/package.json +1 -1
- package/schemas/v2/a2ui-surface-delta-frame.schema.json +1 -1
- package/schemas/v2/agent-deployment-transition.schema.json +1 -1
- package/schemas/v2/agent-deployment.schema.json +1 -1
- package/schemas/v2/agent-eval-suite.schema.json +1 -1
- package/schemas/v2/agent-inventory-response.schema.json +3 -3
- package/schemas/v2/agent-manifest.schema.json +1 -1
- package/schemas/v2/agent-org-chart.schema.json +1 -1
- package/schemas/v2/agent-roster-entry.schema.json +2 -2
- package/schemas/v2/agent-roster-response.schema.json +1 -1
- package/schemas/v2/annotation-create.schema.json +1 -1
- package/schemas/v2/annotation.schema.json +1 -1
- package/schemas/v2/audit-verify-result.schema.json +1 -1
- package/schemas/v2/capabilities.schema.json +19 -19
- package/schemas/v2/compact-tool-descriptor.schema.json +1 -1
- package/schemas/v2/eval-summary.schema.json +2 -2
- package/schemas/v2/localized-content-page-response.schema.json +1 -1
- package/schemas/v2/localized-content-page.schema.json +1 -1
- package/schemas/v2/org-chart-responsibility-view.schema.json +1 -1
- package/schemas/v2/prompt-pack-manifest.schema.json +2 -2
- package/schemas/v2/residency.schema.json +1 -1
- package/schemas/v2/run-ancestry-response.schema.json +1 -1
- package/schemas/v2/run-diff-response.schema.json +1 -1
- package/schemas/v2/run-event-payloads.schema.json +4 -4
- package/schemas/v2/run-options.schema.json +1 -1
- package/schemas/v2/run-snapshot.schema.json +1 -1
- package/schemas/v2/tool-descriptor.schema.json +1 -1
- package/schemas/v2/trigger-subscription-registration.schema.json +1 -1
- package/schemas/v2/workflow-definition.schema.json +1 -1
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v2/README.md +6 -2
- package/spec/v2/core/capabilities.md +5 -1
- package/spec/v2/core/conformance.md +1 -1
- package/spec/v2/core/connection-packs.md +1 -1
- package/spec/v2/core/errors.md +1 -1
- package/spec/v2/core/events.md +1 -1
- package/spec/v2/core/form-content-packs.md +1 -1
- package/spec/v2/core/headers.md +1 -1
- package/spec/v2/core/idempotency.md +1 -1
- package/spec/v2/core/identity.md +6 -2
- package/spec/v2/core/interop.md +1 -1
- package/spec/v2/core/interrupt.md +1 -1
- package/spec/v2/core/overview.md +1 -1
- package/spec/v2/core/packs.md +1 -1
- package/spec/v2/core/persistence.md +1 -1
- package/spec/v2/core/replay.md +1 -1
- package/spec/v2/core/runs.md +1 -1
- package/spec/v2/core/security-defaults.md +1 -1
- package/spec/v2/core/versioning.md +25 -5
- package/spec/v2/core/webhooks.md +1 -1
- package/spec/v2/core/workflow-chain-packs.md +1 -1
- package/spec/v2/release.json +2 -2
package/spec/v2/core/replay.md
CHANGED
package/spec/v2/core/runs.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Versioning and Release
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable · v2.0.10 (2026-09-10) · RFC 0172, 0179, 0176.**
|
|
4
4
|
|
|
5
5
|
## Why this exists
|
|
6
6
|
|
|
@@ -18,9 +18,11 @@ A v2 host MUST advertise `protocolVersions[]` (grammar `^(0|[1-9][0-9]*)\.(0|[1-
|
|
|
18
18
|
|
|
19
19
|
v1 operations keep their `/v1/…` path keys unchanged through the overlap. v2 operations are unversioned path keys on a bare origin (`servers[].url = https://{host}`): `/runs`, `/runs/{runId}`, `/.well-known/openwop`. There is no `/v2/` path space. An unversioned path is the v2 surface; the v1 MUST that servers answer `400` for unversioned roots is retracted for v2.
|
|
20
20
|
|
|
21
|
-
A host that advertises a major in `protocolVersions[]` MUST reach, under that major, every operation it serves under the other. Advertising a major is a claim about the **path space**, not about `/.well-known/openwop` alone — that resource's representation is *selected* by the request header (§1.3), so it answers correctly for a host that has mounted nothing else, and every discovery-level probe of the advertisement passes with it. Concretely: if `/v1/<op>` answers and the unversioned `/<op>` returns `404` under the advertised major, the advertisement overstates what the host serves and the host MUST NOT advertise that major until the surface is reachable. The pairing is normative because a lone `404` cannot distinguish *"this host does not serve that operation"* from *"this host serves it and did not mount it under this major"*, and only the second is a defect.
|
|
21
|
+
A host that advertises a major in `protocolVersions[]` MUST reach, under that major, every operation **named in `spec/v2/path-manifest.json`** that it serves under the other. Advertising a major is a claim about the **path space**, not about `/.well-known/openwop` alone — that resource's representation is *selected* by the request header (§1.3), so it answers correctly for a host that has mounted nothing else, and every discovery-level probe of the advertisement passes with it. Concretely: if `/v1/<op>` answers and the unversioned `/<op>` returns `404` under the advertised major, the advertisement overstates what the host serves and the host MUST NOT advertise that major until the surface is reachable. The pairing is normative because a lone `404` cannot distinguish *"this host does not serve that operation"* from *"this host serves it and did not mount it under this major"*, and only the second is a defect.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**The manifest is the scope, and that qualifier is load-bearing.** An earlier wording quantified over *every operation it serves*, which is not jointly satisfiable with `conformance.md` §"Test seams": the seams profile mounts the real path space `/conformance/seams/…`, and that same document requires `spec/v2/path-manifest.json` and `api/v2/openapi.yaml` to contain **no** seam operation. Under the unqualified reading a host serving seams under one major owed them under the other, while the manifest against which the claim is measured was forbidden to name them. Surfaces a host serves that the manifest does not name — seam paths, and any path the protocol does not define — are **not** bound by this paragraph; §5 records what the protocol does and does not say about the second class. The narrowing does not weaken the case the rule exists for: the defect that motivated it was `POST /webhooks` answering `404` under major 2 while `POST /v1/webhooks` answered `201`, and `webhooks` is a manifest operation.
|
|
24
|
+
|
|
25
|
+
`spec/v2/path-manifest.json` (generated) carries operations (`method`, `path`, `operationId`) and channels (`name`, `address`) on a bare origin, and **every path in it is unversioned** — there are no `/v1` rows. The `/v1` twin of a manifest row is derived by prefixing, which is what the pairing above compares. OpenAPI (`api/v2/openapi.yaml`), AsyncAPI (`api/v2/asyncapi.yaml`), and any kept proto MUST resolve to identical absolute paths for the shared event stream (`scripts/check-path-parity.mjs`); the canonical OpenAPI MUST contain no seam or test-mode operation (those live in the seams profile, see `conformance.md`).
|
|
24
26
|
|
|
25
27
|
### 1.3 The request header
|
|
26
28
|
|
|
@@ -37,7 +39,19 @@ A request on a `/v1/…` path key MUST NOT carry `OpenWOP-Version` with a value
|
|
|
37
39
|
|
|
38
40
|
### 1.4 The response header
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
Every protocol response MUST carry `OpenWOP-Version: <major>.<minor>` naming the contract that produced it. Reporting a version other than the one used is a silent downgrade and non-conformant; the `dual-stack-negotiation` scenario falsifies it. Emitting the header on `/v1/` responses is additive in v1.x and REQUIRED in v2.
|
|
43
|
+
|
|
44
|
+
A *protocol response* is one produced by an operation named in `spec/v2/path-manifest.json` (or its `/v1/` twin through the overlap); a shell, a hosting fallback or a proprietary route on the same origin has no version to name. Errata 2026-09-10: this read "any path" — §1.2's quantifier defect again.
|
|
45
|
+
|
|
46
|
+
**A non-protocol response MUST NOT carry `OpenWOP-Version` and MUST NOT be `application/json`**; a reader, a cache or the suite MUST NOT count a response without the header, or with a `text/html` body, as reaching the operation (`reachedUnderMajor2`).
|
|
47
|
+
|
|
48
|
+
**Content negotiation on a shared name is permitted, with conditions.** A host MAY serve a protocol operation and a page under one unversioned name, selecting on `Accept`, iff:
|
|
49
|
+
|
|
50
|
+
1. A request identifying as a protocol client — `OpenWOP-Version` present, **or** an `Accept` admitting `application/json` without preferring `text/html` (absent and `*/*` included) — MUST get the protocol response for the applicable major (§1.3) with `OpenWOP-Version`; only an explicit `text/html` preference selects the page.
|
|
51
|
+
2. The page obeys the paragraph above.
|
|
52
|
+
3. The response carries `Vary: Accept, OpenWOP-Version`.
|
|
53
|
+
|
|
54
|
+
Otherwise the page MUST move off the shared name.
|
|
41
55
|
|
|
42
56
|
### 1.5 Client precedence and `minClientVersion`
|
|
43
57
|
|
|
@@ -94,12 +108,18 @@ A consumer that vendors any file from `schemas/`, `api/`, or `spec/` MUST pin to
|
|
|
94
108
|
|
|
95
109
|
Through the overlap a host MUST advertise both majors (§1.1), MUST emit `OpenWOP-Version` on every response (§1.4), and MUST serve `/.well-known/openwop` as one resource whose representation the request header selects (`capabilities.md`). The dual-stack scenario creates one run through `/v1/runs` with no header and reads it through `/runs` with `OpenWOP-Version: 2`; the response headers name the contract used.
|
|
96
110
|
|
|
97
|
-
**A run minted under major 1 and read under major 2 MUST be named by its tenant-bound projection** `<tenantId>/<the v1 id>` (`identity.md` §5). A host MUST NOT return the bare v1 id in a major-2 response body.
|
|
111
|
+
**A run minted under major 1 and read under major 2 MUST be named by its tenant-bound projection** `<tenantId>/<the v1 id>` (`identity.md` §5). A host MUST NOT return the bare v1 id in a major-2 response body. Normative since 2026-09-04, when a conformance check asserting byte-equality with the v1 id and a host implementing `identity.md` §5 could not both hold — §5 had no reading.
|
|
98
112
|
|
|
99
113
|
The projection is mandatory rather than optional for a reason that is not stylistic. A tenant-bound id carries the tenant segment that §5's `403 id_tenant_mismatch` check reads. **A bare, unprefixed id has no tenant segment, so the mandatory cross-tenant refusal cannot run on it at all.** Admitting a legacy unprefixed form under major 2 would therefore create a class of identifiers — exactly the long-lived ones, carried over from v1 — on which major 2's tenant-isolation check is structurally inapplicable. The grammar in `ids.schema.json` has no legacy branch, and it MUST NOT acquire one.
|
|
100
114
|
|
|
101
115
|
The overlap ends at v1 end-of-support (`overview.md`), when `protocolVersions[]` drops the `1.<n>` member and every alias carrying the `v1-end-of-support` trigger is removed.
|
|
102
116
|
|
|
117
|
+
**Retirement is atomic, and that is a consequence of §1.1 rather than a separate rule.** Through the overlap `preferredVersion` MUST name a `1.x` member; a host that drops v1 from `protocolVersions[]` advertises a `2.x` `preferredVersion`. There is no legal intermediate state in which both majors are advertised and `2.x` is preferred, so flipping `preferredVersion` ahead of the drop is not a smaller first step — it is the same step. Dropping v1 therefore retires the whole `/v1` path space at once, not incrementally.
|
|
118
|
+
|
|
119
|
+
**Retirement flips every header-less request's contract.** Through the overlap a header-less request on an unversioned name is served major 1 (§1.3); where the v1 surface lives under `/v1/` that name is not a v1 key and falls through to whatever else is served there — typically a page. At end-of-support the same request is served major 2 and the page starts answering the operation. A `/v1/`-counting inventory cannot see this. Test: `manifest top-level segments ∩ anything else served unversioned` (`{agents, prompts, runs}` on the host that found it). A non-empty intersection MUST be resolved before end-of-support: move the page, or serve it under §1.4's conditions.
|
|
120
|
+
|
|
121
|
+
**Open gap — host-proprietary paths have no defined successor.** A host may serve `/v1` roots the manifest does not name. §1.2 does not bind them, and at end-of-support the `/v1` prefix that addressed them is gone, so the protocol says nothing about where they go. This is **undecided, not permissive**: the corpus reserves a vendor namespace for capability records (`capabilities.md` §"extensions"), error codes (`errors.md`), event types (`events.md`), and pack-document properties (`packs.md`), each keyed to an org registered in `spec/v2/declaration.json` — and has no equivalent for paths. RFC 0172 rejected a `/v2/` path space and did not reach this question. The one worked example of a legitimate path space outside the manifest is the seams profile (`conformance.md` §"Test seams"), which stays honest by advertising `openwop-conformance-seams-v2` in `profiles[]` rather than by any path-level rule. A host in this position SHOULD record the affected roots before end-of-support so the set is known when the question is decided.
|
|
122
|
+
|
|
103
123
|
## 6. Migration rows (RFC 0172)
|
|
104
124
|
|
|
105
125
|
| Row | v1 | v2 |
|
package/spec/v2/core/webhooks.md
CHANGED
package/spec/v2/release.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "RFC 0172 \u00a7D.1 \u2014 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.0.
|
|
4
|
-
"corpusTag": "v2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
|
+
"corpusTag": "v2.0.10",
|
|
5
5
|
"updated": "2026-09-05"
|
|
6
6
|
}
|