@openwop/spec-artifacts 2.42.5 → 2.42.7
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 +64 -63
- package/api/seams-v2.yaml +238 -316
- package/api/v2/asyncapi.yaml +83 -113
- package/api/v2/openapi.yaml +339 -724
- package/package.json +1 -1
- package/schemas/audit-verify-result.schema.json +2 -2
- package/schemas/v2/audit-verify-result.schema.json +2 -2
- package/schemas/v2/capabilities.schema.json +2 -5
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/gaps.json +171 -1
- package/spec/v2/README.md +34 -36
- package/spec/v2/core/capabilities.md +186 -119
- package/spec/v2/core/conformance.md +78 -27
- package/spec/v2/core/connection-packs.md +8 -3
- package/spec/v2/core/conversation.md +10 -4
- package/spec/v2/core/errors.md +30 -9
- package/spec/v2/core/events.md +116 -80
- package/spec/v2/core/form-content-packs.md +11 -13
- package/spec/v2/core/headers.md +22 -14
- package/spec/v2/core/host-services.md +22 -5
- package/spec/v2/core/idempotency.md +48 -36
- package/spec/v2/core/identity.md +110 -42
- package/spec/v2/core/interop.md +82 -21
- package/spec/v2/core/interrupt.md +79 -40
- package/spec/v2/core/node-pack-runtimes.md +18 -4
- package/spec/v2/core/oauth.md +40 -6
- package/spec/v2/core/overview.md +61 -33
- package/spec/v2/core/packs.md +53 -28
- package/spec/v2/core/persistence.md +61 -80
- package/spec/v2/core/replay.md +56 -42
- package/spec/v2/core/runs.md +198 -60
- package/spec/v2/core/security-defaults.md +57 -33
- package/spec/v2/core/tool-catalog.md +29 -6
- package/spec/v2/core/versioning.md +95 -49
- package/spec/v2/core/webhooks.md +59 -20
- package/spec/v2/core/workflow-chain-packs.md +16 -14
- package/spec/v2/corrections.json +17 -1
- package/spec/v2/corrections.schema.json +1 -1
- package/spec/v2/declaration.json +24 -7
- package/spec/v2/declaration.schema.json +10 -0
- package/spec/v2/errors.json +109 -2
- package/spec/v2/errors.schema.json +38 -0
- package/spec/v2/ext/README.md +36 -23
- package/spec/v2/ext/a2uiSurface/README.md +75 -89
- package/spec/v2/ext/brand/README.md +15 -15
- package/spec/v2/ext/canvas/README.md +15 -15
- package/spec/v2/ext/chat/README.md +15 -15
- package/spec/v2/ext/coordination/README.md +15 -15
- package/spec/v2/ext/dataIntegration/README.md +17 -20
- package/spec/v2/ext/entities/README.md +15 -15
- package/spec/v2/ext/grpc-transport/README.md +6 -8
- package/spec/v2/ext/kanban/README.md +15 -15
- package/spec/v2/ext/knowledge/README.md +15 -15
- package/spec/v2/ext/launchStudio/README.md +16 -16
- package/spec/v2/ext/messaging/README.md +15 -15
- package/spec/v2/ext/portability/README.md +3 -17
- package/spec/v2/ext/provider-idempotency/README.md +7 -10
- package/spec/v2/ext/restTransport/README.md +30 -19
- package/spec/v2/ext/sandbox-runtime-notes/README.md +7 -9
- package/spec/v2/ext/webResearch/README.md +16 -16
- package/spec/v2/profiles.json +6 -2
- package/spec/v2/release.json +2 -2
- package/spec/v2/surface-baseline.json +542 -2
package/spec/v2/core/webhooks.md
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
# Webhooks
|
|
2
2
|
|
|
3
|
-
> **Status: Stable
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
> **Normative home:** `webhooks`.
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
8
|
-
A client registers a URL and an event filter once; the host POSTs matching events, signed, as they happen.
|
|
8
|
+
A client registers a URL and an event filter once; the host POSTs matching events, signed, as they happen. Durable delivery binds with the surface — a signed event that may be dropped is not a delivery contract.
|
|
9
9
|
|
|
10
10
|
## Surfaces
|
|
11
11
|
|
|
12
|
-
A host that advertises `webhooks` (capabilities.md) serves `registerWebhook` (`POST /webhooks`) and `unregisterWebhook` (`DELETE /webhooks/{webhookId}`) from `api/v2/openapi.yaml`. The facet (`spec/v2/facets/webhooks.schema.json`) is `{ signatureAlgorithms[] }`, which MUST list `"v1"
|
|
12
|
+
A host that advertises `webhooks` ([capabilities.md](capabilities.md)) serves `registerWebhook` (`POST /webhooks`) and `unregisterWebhook` (`DELETE /webhooks/{webhookId}`) from `api/v2/openapi.yaml`. The facet (`spec/v2/facets/webhooks.schema.json`) is `{ signatureAlgorithms[] }`, which MUST list `"v1"`.
|
|
13
13
|
|
|
14
14
|
| Operation | Request | Response |
|
|
15
15
|
| --- | --- | --- |
|
|
16
|
-
| `registerWebhook` | `{ url, events[], secret?, tags?, signatureAlgorithms? }
|
|
16
|
+
| `registerWebhook` | `{ url, events[], secret?, tags?, signatureAlgorithms? }` | `201 { webhookId }` |
|
|
17
17
|
| `unregisterWebhook` | path `webhookId` | `204`; `404` when unknown; `403` when the caller is outside the subscription's tenant |
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
On `registerWebhook`, `url` MUST be `https://` and `events[]` MUST be non-empty v2 event type names ([events.md](events.md)).
|
|
20
|
+
|
|
21
|
+
A `204` from `unregisterWebhook` ends the subscription's deliveries, including retries already scheduled (§Durability).
|
|
20
22
|
|
|
21
23
|
A subscription MUST receive only events from runs within its tenant scope; cross-tenant delivery is a protocol violation whatever the filter says (invariant `webhook-cross-tenant-isolation`). `tags` narrows delivery to runs whose options carry an overlapping tag.
|
|
22
24
|
|
|
23
25
|
## Delivery
|
|
24
26
|
|
|
25
|
-
The delivery envelope is generated from the event's payload definition (events.md §Payloads). The body is `{ runId, workspaceId?, event }
|
|
27
|
+
The delivery envelope is generated from the event's payload definition (events.md §Payloads). The body is `{ runId, workspaceId?, event }`, where `event` is the verbatim run event.
|
|
26
28
|
|
|
27
|
-
The
|
|
28
|
-
`identity.md
|
|
29
|
-
|
|
30
|
-
exists at delivery time.
|
|
29
|
+
- The body MUST validate against `schemas/v2/webhook-delivery.schema.json`.
|
|
30
|
+
- `workspaceId` is present exactly when `RunSnapshot.owner.workspace` is ([identity.md §1](identity.md)); a host MUST NOT substitute its tenant id for an absent workspace.
|
|
31
|
+
- The envelope's `runId` MUST use the tenant-bound form of [identity.md §5](identity.md), matching the nested event and every response representation, even though no versioned request exists at delivery time.
|
|
31
32
|
|
|
32
33
|
### Headers
|
|
33
34
|
|
|
@@ -43,15 +44,21 @@ A host MUST send all five on every delivery. The signed bytes are `{timestamp}.{
|
|
|
43
44
|
|
|
44
45
|
### Verification
|
|
45
46
|
|
|
46
|
-
A subscriber MUST verify before acting:
|
|
47
|
+
A subscriber MUST verify before acting:
|
|
48
|
+
|
|
49
|
+
1. Reject a timestamp more than ±5 minutes from its clock.
|
|
50
|
+
2. Compute `HMAC-SHA256({timestamp}.{rawBody}, secret)`.
|
|
51
|
+
3. Compare in constant time.
|
|
52
|
+
|
|
53
|
+
A subscriber MUST reject an unrecognized `OpenWOP-Signature-Algorithm` value, and SHOULD track `(OpenWOP-Webhook-Id, runId, sequence)` for at-least-once deduplication. A host MUST NOT log the secret.
|
|
47
54
|
|
|
48
55
|
### Standard Webhooks
|
|
49
56
|
|
|
50
|
-
`standard-webhooks-1` names the symmetric scheme of Standard Webhooks 1.0.0
|
|
57
|
+
`standard-webhooks-1` names the symmetric scheme of Standard Webhooks 1.0.0. Its in-header `v1,` token is that standard's, not the OpenWOP scheme id `v1`; neither is read as the other, and `OpenWOP-Signature-Algorithm` stays `v1`.
|
|
51
58
|
|
|
52
59
|
**Opt-in.** A subscription carries the scheme only when `registerWebhook` sends `signatureAlgorithms` listing it and `v1`, with a `secret` of the form `whsec_<base64 of 24–64 bytes>`; otherwise, or when the host does not advertise the id, `400 validation_error`. The `201` echoes the applied list. Every other subscription is unchanged.
|
|
53
60
|
|
|
54
|
-
**Endpoint verification.** Before answering `201`,
|
|
61
|
+
**Endpoint verification.** Before answering `201`, a host MUST send the request of `schemas/v2/webhook-verification.schema.json` to `url` under §Egress, signed as below. Unless a `2xx` arrives within 10 s whose JSON `challenge` equals the one sent, it MUST refuse `400 webhook_endpoint_unverified`, persisting nothing. A host MUST NOT verify a subscription that did not opt in.
|
|
55
62
|
|
|
56
63
|
**Delivery.** Each delivery to an opted-in subscription adds `webhook-id`, `webhook-timestamp` (equal to `OpenWOP-Timestamp`) and `webhook-signature`: space-separated `v1,<base64 HMAC-SHA256>` entries over `{webhook-id}.{webhook-timestamp}.{rawBody}`, keyed by the decoded secret. `webhook-id` matches `^[A-Za-z0-9_-]{16,128}$`, MUST be identical on every attempt of one `(webhookId, runId, sequence)` and MUST differ across them.
|
|
57
64
|
|
|
@@ -59,28 +66,60 @@ A subscriber MUST verify before acting: reject a timestamp more than ±5 minutes
|
|
|
59
66
|
|
|
60
67
|
### Dual emission through the overlap
|
|
61
68
|
|
|
62
|
-
A host advertising both majors MUST send, on every delivery, the `X-openwop-*` family alongside the `OpenWOP-*` family with identical values
|
|
69
|
+
- A host advertising both majors MUST send, on every delivery, the `X-openwop-*` family alongside the `OpenWOP-*` family with identical values. This adds no signature scheme.
|
|
70
|
+
- A v2 receiver MUST accept a delivery carrying only the `X-openwop-*` family under scheme `v1`, verifying the same bytes.
|
|
71
|
+
- Per-subscription secrets are unchanged across the cut. Deliveries queued before the cut drain under their own retry policy with the payload they were serialized with ([persistence.md](persistence.md)).
|
|
72
|
+
- The `X-openwop-*` family is removed on its register date.
|
|
63
73
|
|
|
64
74
|
## Durability
|
|
65
75
|
|
|
66
|
-
Durable delivery is an obligation of the `webhooks` surface (
|
|
76
|
+
Durable delivery is an obligation of the `webhooks` surface ([security-defaults.md](security-defaults.md)). A host MUST:
|
|
67
77
|
|
|
68
78
|
- retry a failed attempt per its advertised `retryPolicy` (`maxAttempts`, `backoff ∈ none | fixed | exponential`) with backoff between attempts;
|
|
69
|
-
- route a delivery whose retries are exhausted to the dead-letter sink
|
|
79
|
+
- route a delivery whose retries are exhausted to the dead-letter sink (§Dead letters), rather than drop it;
|
|
70
80
|
- deliver each matching event at least once; a receiver MAY observe the same event more than once;
|
|
71
|
-
- not make the start of an attempt to one subscription wait for an attempt to a *different* subscription to finish (answered, failed, or timed out)
|
|
72
|
-
- sustain that while at least **8** subscriptions have attempts outstanding that their receivers have not answered
|
|
73
|
-
- after `unregisterWebhook` answers `204`, not start any further attempt for that subscription, including attempts already scheduled for retry (invariant `webhook-unregister-stops-delivery
|
|
81
|
+
- not make the start of an attempt to one subscription wait for an attempt to a *different* subscription to finish (answered, failed, or timed out) (§Delivery isolation);
|
|
82
|
+
- sustain that while at least **8** subscriptions have attempts outstanding that their receivers have not answered;
|
|
83
|
+
- after `unregisterWebhook` answers `204`, not start any further attempt for that subscription, including attempts already scheduled for retry (invariant `webhook-unregister-stops-delivery`);
|
|
74
84
|
- dead-letter a `payload_unprojectable` delivery (events.md §Era-2) on the first attempt, never retry it.
|
|
75
85
|
|
|
76
86
|
Best-effort delivery is not a conforming mode. A `3xx` response is a delivery failure, retried under the same policy. `webhook-durable-delivery` witnesses it.
|
|
77
87
|
|
|
88
|
+
### Delivery isolation
|
|
89
|
+
|
|
90
|
+
One subscription's slow or dead receiver MUST NOT delay another subscription's deliveries (invariant `webhook-delivery-isolation`). The rule is about when an attempt starts, not how soon after an event it must start, and it names no mechanism: a lane per subscription, a concurrent pool or asynchronous I/O all meet it; a sequential loop over a batch does not.
|
|
91
|
+
|
|
92
|
+
A host MAY bound concurrent attempts beyond the floor of 8, and SHOULD NOT let one tenant's unanswered attempts occupy capacity another tenant's deliveries need.
|
|
93
|
+
|
|
94
|
+
### Unregister
|
|
95
|
+
|
|
96
|
+
An attempt whose request the host had begun sending before `unregisterWebhook` answered `204` MAY complete. The unregister does not oblige the host to route that subscription's undelivered events to the dead-letter sink: the exhaustion rule governs deliveries of a live subscription.
|
|
97
|
+
|
|
98
|
+
### Dead letters
|
|
99
|
+
|
|
100
|
+
This sink is the delivery sink; the `deadLetter` family is the run sink and is a different thing.
|
|
101
|
+
|
|
102
|
+
- A host advertising `webhooks.deadLetter` MUST serve `GET /webhooks/{webhookId}/dead-letters`.
|
|
103
|
+
- A record MUST NOT carry the delivered body, the delivery headers, or the subscription secret — a dead-letter read names a delivery, it does not replay one.
|
|
104
|
+
- The read belongs to a live subscription: after `unregisterWebhook` answers `204`, `GET /webhooks/{webhookId}/dead-letters` for that id MUST answer `404 not_found`, exactly as for a same-tenant id the host never minted. The host MAY discard that subscription's records at the unregister.
|
|
105
|
+
- `expiresAt` bounds a record's retention only while its subscription exists.
|
|
106
|
+
|
|
78
107
|
## Replay
|
|
79
108
|
|
|
80
109
|
A host MUST NOT deliver events a `replay` fork re-emits as fixed history; replay-ness is read from the run, never from the event type (replay.md). A `branch` fork's events are new facts and are delivered.
|
|
81
110
|
|
|
82
111
|
## Egress
|
|
83
112
|
|
|
84
|
-
At registration a host MUST reject (`400 webhook_url_rejected`) non-`https://` URLs, RFC 1918 and loopback and link-local ranges, IPv6 ULA, cloud metadata hosts, and `localhost`.
|
|
113
|
+
At registration a host MUST reject (`400 webhook_url_rejected`) non-`https://` URLs, RFC 1918 and loopback and link-local ranges, IPv6 ULA, cloud metadata hosts, and `localhost`.
|
|
114
|
+
|
|
115
|
+
Address classification:
|
|
116
|
+
|
|
117
|
+
- An IPv4-mapped IPv6 address (`::ffff:0:0/96`) MUST be judged by the IPv4 address it embeds, whatever its spelling.
|
|
118
|
+
- An address embedding IPv4 in another standard translation form (IPv4-compatible `::/96`, NAT64 `64:ff9b::/96`, 6to4 `2002::/16`) SHOULD be judged the same way, and those prefixes SHOULD NOT be denied wholesale.
|
|
119
|
+
- A host SHOULD refuse every destination the IANA special-purpose address registries mark not globally reachable.
|
|
120
|
+
|
|
121
|
+
At delivery time a host MUST re-resolve the hostname, validate every resolved address against the same denied ranges plus its own denylist, connect to the validated address without re-resolving, and refuse to follow redirects (invariant `webhook-delivery-egress-revalidation`, reference-impl tier). These delivery-time rules bind an A2A push identically (interop.md §"A2A push delivery").
|
|
85
122
|
|
|
86
123
|
See also: events.md, replay.md, persistence.md, security-defaults.md.
|
|
124
|
+
|
|
125
|
+
*Sources: RFC 0053, RFC 0165, RFC 0171, RFC 0173, RFC 0176, RFC 0188, RFC 0196, RFC 0201, RFC 0215, RFC 0217.*
|
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
# Workflow Chain Packs
|
|
2
2
|
|
|
3
|
-
> **Status: Stable
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
> **Normative home:** `workflowChainPacks`.
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
8
|
-
A workflow-chain pack ships a reusable fragment a host expands into a concrete definition, and may compose other chains as co-registered children. The manifest is `schemas/v2/workflow-chain-pack-manifest.schema.json`; installation and signing follow packs.md.
|
|
8
|
+
A workflow-chain pack ships a reusable fragment a host expands into a concrete definition, and may compose other chains as co-registered children. The manifest is `schemas/v2/workflow-chain-pack-manifest.schema.json`; installation and signing follow [packs.md](packs.md).
|
|
9
9
|
|
|
10
10
|
## Exact pins
|
|
11
11
|
|
|
12
|
-
Every reference a chain makes to a node type or an external chain MUST pin an exact version per referenced `typeId` (`core.ai.callPrompt@1.0.0`). A host MUST refuse to register a chain whose reference carries a range or no version.
|
|
12
|
+
Every reference a chain makes to a node type or an external chain MUST pin an exact version per referenced `typeId` (`core.ai.callPrompt@1.0.0`). A host MUST refuse to register a chain whose reference carries a range or no version.
|
|
13
13
|
|
|
14
14
|
## Co-registered children
|
|
15
15
|
|
|
16
|
-
When a parent chain expands a `subChainRef`, the child is registered as its own workflow
|
|
16
|
+
When a parent chain expands a `subChainRef`, the child is registered as its own workflow. A host MUST:
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
| Deletion | delete the child only when its last parent is deleted |
|
|
23
|
-
| Ownership record | persist the resolved child version in the parent's ownership record, so a re-instantiation or `:fork` reproduces the same child |
|
|
18
|
+
- **Identity** — register the child under a deterministic id, so two parents composing the same child share one registration.
|
|
19
|
+
- **Reference count** — count each parent that references the child; deleting a parent decrements the count.
|
|
20
|
+
- **Deletion** — delete the child only when its last parent is deleted.
|
|
21
|
+
- **Ownership record** — persist the resolved child version in the parent's ownership record, so a re-instantiation or `:fork` reproduces the same child.
|
|
24
22
|
|
|
25
|
-
The ownership record is a persistence.md store.
|
|
23
|
+
The ownership record is a [persistence.md](persistence.md) store.
|
|
26
24
|
|
|
27
25
|
## Parameter substitution
|
|
28
26
|
|
|
29
|
-
`{{params.<name>}}` tokens are substituted at expansion time, when the author drops the tile. A persisted definition MUST NOT contain a `{{params.*}}` token, and a host MUST NOT defer substitution to dispatch time.
|
|
27
|
+
`{{params.<name>}}` tokens are substituted at expansion time, when the author drops the tile. A persisted definition MUST NOT contain a `{{params.*}}` token, and a host MUST NOT defer substitution to dispatch time.
|
|
30
28
|
|
|
31
29
|
## Composition depth
|
|
32
30
|
|
|
33
|
-
A host MUST bound sub-chain nesting by `workflowChainPacks.subChains.maxDepth` (capabilities.md), default 8. A composition that exceeds the depth, or that transitively composes itself, MUST fail closed with `sub_chain_cycle`; the depth check and the cycle check compose as one guard.
|
|
31
|
+
A host MUST bound sub-chain nesting by `workflowChainPacks.subChains.maxDepth` ([capabilities.md](capabilities.md)), default 8. A composition that exceeds the depth, or that transitively composes itself, MUST fail closed with `sub_chain_cycle`; the depth check and the cycle check compose as one guard.
|
|
34
32
|
|
|
35
33
|
## Edge conditions
|
|
36
34
|
|
|
37
|
-
Fragment edges carry the same `condition` and `triggerRule` shapes as a top-level definition (`schemas/v2/workflow-definition.schema.json`). `EdgeCondition.type` is one of `expression`, `equals`, `notEquals`, `contains`, `regex`, `truthy`, `falsy`; `truthy` and `falsy` take `left` and no `right`.
|
|
35
|
+
Fragment edges carry the same `condition` and `triggerRule` shapes as a top-level definition (`schemas/v2/workflow-definition.schema.json`). `EdgeCondition.type` is one of `expression`, `equals`, `notEquals`, `contains`, `regex`, `truthy`, `falsy`; `truthy` and `falsy` take `left` and no `right`.
|
|
36
|
+
|
|
37
|
+
A host MUST carry both fields through expansion verbatim and MUST honor them on expanded edges as on authored ones. [form-content-packs.md](form-content-packs.md) reuses this operator set for field visibility.
|
|
38
|
+
|
|
39
|
+
*Sources: RFC 0133, RFC 0177.*
|
package/spec/v2/corrections.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "./corrections.schema.json",
|
|
3
3
|
"$comment": "RFC 0197 §A.4 — v2 Class-3 corrections. Seeded with P3 only. The 2.8.2 removal of `workflowChainPacks.deferredParameters` and `.hostExpansionSeam` (P1) is deliberately NOT seeded: a committed bundle carried `deferredParameters` and then failed `capabilities-root-closed`, so the row would fail R3 — which is the point. P1 is recorded as the motivating defect in COMPATIBILITY.md §3a, not laundered into this register.",
|
|
4
4
|
"version": 1,
|
|
5
|
-
"updated": "2026-09-
|
|
5
|
+
"updated": "2026-09-27",
|
|
6
6
|
"rows": [
|
|
7
7
|
{
|
|
8
8
|
"id": "openwop.correction.v2.1",
|
|
@@ -27,6 +27,22 @@
|
|
|
27
27
|
"manifestsScanned": 190,
|
|
28
28
|
"note": "The prior shape is a manifest shape, not a discovery shape, so no bundle could carry it and the bundle leg is 0 by construction. The registry leg was measured at the correction: 0 of 190 published v2 pack.json documents validated against the schemas BEFORE the change and 185 of 190 after, so no published document carried the `{ publicKeyRef, signatureRef, method }` block the schemas described. `spec/v2/core/packs.md` §Signing, RFC 0177 §C.3 and migration row openwop.migration.C10.1 had already replaced it with `{ keyId, scheme }`; the schemas were the outlier against the prose, the Accepted RFC and the registry at once. `signing` stays OPTIONAL on a bare manifest, so no previously-valid unsigned document is invalidated. FragmentNode.config was closed by the v1→v2 seed against its own description, failing 73 of 81 published chain packs; reopening it narrows nothing."
|
|
29
29
|
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "openwop.correction.v2.2",
|
|
33
|
+
"date": "2026-09-27",
|
|
34
|
+
"class": "w3c-class-3",
|
|
35
|
+
"rfc": "0172",
|
|
36
|
+
"pointers": [
|
|
37
|
+
"schemas/v2/capabilities.schema.json#/minClientVersion"
|
|
38
|
+
],
|
|
39
|
+
"compatibilityEntry": "the v2 `minClientVersion` grammar",
|
|
40
|
+
"priorShapeCensus": {
|
|
41
|
+
"bundles": 0,
|
|
42
|
+
"manifests": 0,
|
|
43
|
+
"manifestsScanned": 156,
|
|
44
|
+
"note": "The prior shape is any string; the corrected shape is the axis-1 `<major>.<minor>` grammar that spec/v2/core/versioning.md §1.5 and the v2-min-client-version scenario already required of an advertised value. Bundle leg: all 8 committed evidence/v2-host-bundles/*.json advertise minClientVersion, and every value conforms (seven \"1.0\", MyndHyve \"0.1\"), so 0 carry a value the pattern rejects. The one \"0.1.0\" in the corpus is a major-1 witness under evidence/rfc-witnesses/, not a v2 bundle. Registry leg: minClientVersion is a discovery field, not a manifest field; 0 of 156 pack.json documents on openwop-registry origin/main (c15d3d6) carry it. The schema added a pattern only, so no property, type or required entry moved and check-v2-surface-monotone sees no change."
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
]
|
|
32
48
|
}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"description": "Every schema pointer the correction moved, as `<repo-relative file>#<INSTANCE pointer>` \u2014 the document-shaped path scripts/generate-v2-surface-baseline.mjs prints (`#/signing`, `#/chains/[]/dag/nodes/[]/config`), never the schema-shaped one (`#/properties/signing`), because a `$defs` name is not a surface. scripts/check-v2-surface-monotone.mjs matches a baseline removal against this list, so a pointer left out is a removal the monotone gate refuses.",
|
|
31
31
|
"items": { "type": "string", "pattern": "^[A-Za-z0-9_./-]+#(/[^#|]*)?$" }
|
|
32
32
|
},
|
|
33
|
-
"compatibilityEntry": { "type": "string", "minLength": 1, "description": "A literal substring of the COMPATIBILITY.md §3 \"correction on record\" entry. The gate fails when it drifts — a register row whose prose entry has been reworded away is an unrecorded shape change." },
|
|
33
|
+
"compatibilityEntry": { "type": "string", "minLength": 1, "description": "A literal substring of the COMPATIBILITY.md §3 \"correction on record\" entry, which is kept in docs/COMPATIBILITY-CORRECTIONS-LOG.md. The gate fails when it drifts — a register row whose prose entry has been reworded away is an unrecorded shape change." },
|
|
34
34
|
"priorShapeCensus": {
|
|
35
35
|
"type": "object",
|
|
36
36
|
"additionalProperties": false,
|
package/spec/v2/declaration.json
CHANGED
|
@@ -1734,10 +1734,11 @@
|
|
|
1734
1734
|
"anchor": "ext",
|
|
1735
1735
|
"section": "ext/restTransport/",
|
|
1736
1736
|
"peerDependencyId": "restTransport",
|
|
1737
|
-
"
|
|
1737
|
+
"extensionName": "rest-transport",
|
|
1738
|
+
"witness": "witnessable-gated",
|
|
1738
1739
|
"maturity": {
|
|
1739
1740
|
"technical": "experimental",
|
|
1740
|
-
"adoption": "
|
|
1741
|
+
"adoption": "single-witness"
|
|
1741
1742
|
},
|
|
1742
1743
|
"facets": [
|
|
1743
1744
|
"conditionalRunGet",
|
|
@@ -1746,7 +1747,7 @@
|
|
|
1746
1747
|
"floorScenarios": [],
|
|
1747
1748
|
"requirementIds": [],
|
|
1748
1749
|
"owningRfc": "0115",
|
|
1749
|
-
"reason": "RFC 0169 \u00a7C.5
|
|
1750
|
+
"reason": "RFC 0169 \u00a7C.5 moved it to ext/ as claims-check; RFC 0220 \u00a7C lands the behavioral witness (v2-ext-rest-transport), so the witness is witnessable-gated on the extensions.<org>.rest-transport claim. It stays ext/: becoming core takes its own RFC (ext/README.md)."
|
|
1750
1751
|
},
|
|
1751
1752
|
{
|
|
1752
1753
|
"key": "a2uiSurface",
|
|
@@ -1754,7 +1755,8 @@
|
|
|
1754
1755
|
"anchor": "ext",
|
|
1755
1756
|
"section": "ext/a2uiSurface/",
|
|
1756
1757
|
"peerDependencyId": "a2uiSurface",
|
|
1757
|
-
"
|
|
1758
|
+
"extensionName": "a2ui-surface",
|
|
1759
|
+
"witness": "seam-gated",
|
|
1758
1760
|
"maturity": {
|
|
1759
1761
|
"technical": "experimental",
|
|
1760
1762
|
"adoption": "none"
|
|
@@ -1765,7 +1767,7 @@
|
|
|
1765
1767
|
"floorScenarios": [],
|
|
1766
1768
|
"requirementIds": [],
|
|
1767
1769
|
"owningRfc": "0209",
|
|
1768
|
-
"reason": "RFC 0169 \u00a7C.5 (
|
|
1770
|
+
"reason": "RFC 0169 \u00a7C.5 (ext/); RFC 0220 \u00a7C: the witness is seam-gated (v2-a2ui-v09-surface drives the emit-surface seam; the family row is its family-witness leg); RFC 0209: the ext README is the v2 contract for `ui.a2ui-surface` schema version 2; facet `deltaTransport` deprecated for v2 (RFC 0197 retirement path)"
|
|
1769
1771
|
},
|
|
1770
1772
|
{
|
|
1771
1773
|
"key": "brand",
|
|
@@ -1773,6 +1775,7 @@
|
|
|
1773
1775
|
"anchor": "ext",
|
|
1774
1776
|
"section": "ext/brand/",
|
|
1775
1777
|
"peerDependencyId": "brand",
|
|
1778
|
+
"extensionName": "brand",
|
|
1776
1779
|
"witness": "claims-check",
|
|
1777
1780
|
"maturity": {
|
|
1778
1781
|
"technical": "experimental",
|
|
@@ -1790,6 +1793,7 @@
|
|
|
1790
1793
|
"anchor": "ext",
|
|
1791
1794
|
"section": "ext/canvas/",
|
|
1792
1795
|
"peerDependencyId": "canvas",
|
|
1796
|
+
"extensionName": "canvas",
|
|
1793
1797
|
"witness": "claims-check",
|
|
1794
1798
|
"maturity": {
|
|
1795
1799
|
"technical": "experimental",
|
|
@@ -1807,6 +1811,7 @@
|
|
|
1807
1811
|
"anchor": "ext",
|
|
1808
1812
|
"section": "ext/chat/",
|
|
1809
1813
|
"peerDependencyId": "chat",
|
|
1814
|
+
"extensionName": "chat",
|
|
1810
1815
|
"witness": "claims-check",
|
|
1811
1816
|
"maturity": {
|
|
1812
1817
|
"technical": "experimental",
|
|
@@ -1824,6 +1829,7 @@
|
|
|
1824
1829
|
"anchor": "ext",
|
|
1825
1830
|
"section": "ext/coordination/",
|
|
1826
1831
|
"peerDependencyId": "coordination",
|
|
1832
|
+
"extensionName": "coordination",
|
|
1827
1833
|
"witness": "claims-check",
|
|
1828
1834
|
"maturity": {
|
|
1829
1835
|
"technical": "experimental",
|
|
@@ -1841,6 +1847,7 @@
|
|
|
1841
1847
|
"anchor": "ext",
|
|
1842
1848
|
"section": "ext/dataIntegration/",
|
|
1843
1849
|
"peerDependencyId": "dataIntegration",
|
|
1850
|
+
"extensionName": "data-integration",
|
|
1844
1851
|
"witness": "claims-check",
|
|
1845
1852
|
"maturity": {
|
|
1846
1853
|
"technical": "experimental",
|
|
@@ -1858,6 +1865,7 @@
|
|
|
1858
1865
|
"anchor": "ext",
|
|
1859
1866
|
"section": "ext/entities/",
|
|
1860
1867
|
"peerDependencyId": "entities",
|
|
1868
|
+
"extensionName": "entities",
|
|
1861
1869
|
"witness": "claims-check",
|
|
1862
1870
|
"maturity": {
|
|
1863
1871
|
"technical": "experimental",
|
|
@@ -1875,6 +1883,7 @@
|
|
|
1875
1883
|
"anchor": "ext",
|
|
1876
1884
|
"section": "ext/kanban/",
|
|
1877
1885
|
"peerDependencyId": "kanban",
|
|
1886
|
+
"extensionName": "kanban",
|
|
1878
1887
|
"witness": "claims-check",
|
|
1879
1888
|
"maturity": {
|
|
1880
1889
|
"technical": "experimental",
|
|
@@ -1892,6 +1901,7 @@
|
|
|
1892
1901
|
"anchor": "ext",
|
|
1893
1902
|
"section": "ext/knowledge/",
|
|
1894
1903
|
"peerDependencyId": "knowledge",
|
|
1904
|
+
"extensionName": "knowledge",
|
|
1895
1905
|
"witness": "claims-check",
|
|
1896
1906
|
"maturity": {
|
|
1897
1907
|
"technical": "experimental",
|
|
@@ -1909,6 +1919,7 @@
|
|
|
1909
1919
|
"anchor": "ext",
|
|
1910
1920
|
"section": "ext/launchStudio/",
|
|
1911
1921
|
"peerDependencyId": "launchStudio",
|
|
1922
|
+
"extensionName": "launch-studio",
|
|
1912
1923
|
"witness": "claims-check",
|
|
1913
1924
|
"maturity": {
|
|
1914
1925
|
"technical": "experimental",
|
|
@@ -1926,6 +1937,7 @@
|
|
|
1926
1937
|
"anchor": "ext",
|
|
1927
1938
|
"section": "ext/messaging/",
|
|
1928
1939
|
"peerDependencyId": "messaging",
|
|
1940
|
+
"extensionName": "messaging",
|
|
1929
1941
|
"witness": "claims-check",
|
|
1930
1942
|
"maturity": {
|
|
1931
1943
|
"technical": "experimental",
|
|
@@ -1943,6 +1955,7 @@
|
|
|
1943
1955
|
"anchor": "ext",
|
|
1944
1956
|
"section": "ext/webResearch/",
|
|
1945
1957
|
"peerDependencyId": "webResearch",
|
|
1958
|
+
"extensionName": "web-research",
|
|
1946
1959
|
"witness": "claims-check",
|
|
1947
1960
|
"maturity": {
|
|
1948
1961
|
"technical": "experimental",
|
|
@@ -1958,6 +1971,7 @@
|
|
|
1958
1971
|
"profiles": [
|
|
1959
1972
|
{
|
|
1960
1973
|
"id": "openwop-discovery-core",
|
|
1974
|
+
"summary": "The host publishes a valid v2 discovery document and negotiates the protocol version; it makes no claim about running workflows.",
|
|
1961
1975
|
"predicate": {
|
|
1962
1976
|
"families": [],
|
|
1963
1977
|
"metadata": [
|
|
@@ -1974,6 +1988,7 @@
|
|
|
1974
1988
|
},
|
|
1975
1989
|
{
|
|
1976
1990
|
"id": "openwop-core-standard",
|
|
1991
|
+
"summary": "The host runs workflows to the executable floor: interrupts, replay, webhooks, idempotency and the event log. This is what an unqualified \"OpenWOP conformant\" claim means.",
|
|
1977
1992
|
"predicate": {
|
|
1978
1993
|
"families": [
|
|
1979
1994
|
"interrupt",
|
|
@@ -1996,13 +2011,15 @@
|
|
|
1996
2011
|
"v2-run-bulk-cancel",
|
|
1997
2012
|
"v2-run-pause-resume",
|
|
1998
2013
|
"v2-run-options-limits",
|
|
1999
|
-
"v2-sse-last-event-id"
|
|
2014
|
+
"v2-sse-last-event-id",
|
|
2015
|
+
"v2-sse-last-event-id-cursor"
|
|
2000
2016
|
],
|
|
2001
2017
|
"requirementIds": [],
|
|
2002
|
-
"note": "rc.59: five unaided run-surface witnesses joined the floor \u2014 v2-run-cancel (runs.md \u00a7Cancel: 409 run_terminal on a terminal run), v2-run-bulk-cancel (\u00a7Cancel: per-entry envelopes, id_tenant_mismatch / not_found, details.maxRunIds), v2-run-pause-resume (\u00a7Pause and resume: 409 run_terminal / run_state_conflict, the literal drainPolicy echo, the immediate cut), v2-run-options-limits (capabilities.md limits metadata honoured on create), v2-sse-last-event-id (events.md \u00a7SSE frames: Last-Event-ID resumes at the next sequence, never re-emits the resumption point). cancelRun, bulkCancelRuns and pauseRun are core operations by the runs.md surface table (only ancestry, annotations and eval-summary are 404-when-unadvertised), so a host that omits one is blocked, not inapplicable, and the floor refuses it \u2014 the prose's outcome. Their optional legs (values mode, the conformance-delay / conformance-cancellable fixtures) record inapplicable with the reason and the file row stays a witnessed pass. Measured before the change: the reference host passes all five (rc.58, 179 / 0 / 0 / 42); neither production host satisfies this predicate, so no existing claim moves. seeded from spec/v1/core-standard-manifest.json at P3-B; floor minted rc.45, one or more unaided witnesses per predicate family: interrupt (token scheme), replay (the effect-seam manifest \u2014 its seam-driven no-re-fire leg lives in v2-effect-seam-no-refire on the seams floor), webhooks (durable delivery), idempotency (Layer-1 key grammar), eventLog (era key, era stamp, closed event type, poll cursor). Deliberately absent: v2-pinned-run-disposition (seam-gated and opt-in), v2-v1-signed-webhook-accepted (a coexistence scenario, driven through the seam; the cut gate is its home), v2-effect-identity-business-key (retry leg seam-driven), v2-approver-enforced (conditional on the refKinds facet)."
|
|
2018
|
+
"note": "2.42.7: v2-sse-last-event-id-cursor joined the floor (events.md \u00a7SSE frames, RFC 0213 \u00a7A: Last-Event-ID is an exclusive cursor, a well-formed id past the log is not refused, and the header is read only after authorization). It was held off the floor until the three bundle hosts were measured. Measured on committed bundles, it is executed-pass on the v2 reference host (2.42.2), MyndHyve (2.42.0) and openwop-app (2.42.2 side revision); the first two carry partial-witness only for the SHOULD leg (a malformed id accepted, recorded not failed), so no existing claim moves. rc.59: five unaided run-surface witnesses joined the floor \u2014 v2-run-cancel (runs.md \u00a7Cancel: 409 run_terminal on a terminal run), v2-run-bulk-cancel (\u00a7Cancel: per-entry envelopes, id_tenant_mismatch / not_found, details.maxRunIds), v2-run-pause-resume (\u00a7Pause and resume: 409 run_terminal / run_state_conflict, the literal drainPolicy echo, the immediate cut), v2-run-options-limits (capabilities.md limits metadata honoured on create), v2-sse-last-event-id (events.md \u00a7SSE frames: Last-Event-ID resumes at the next sequence, never re-emits the resumption point). cancelRun, bulkCancelRuns and pauseRun are core operations by the runs.md surface table (only ancestry, annotations and eval-summary are 404-when-unadvertised), so a host that omits one is blocked, not inapplicable, and the floor refuses it \u2014 the prose's outcome. Their optional legs (values mode, the conformance-delay / conformance-cancellable fixtures) record inapplicable with the reason and the file row stays a witnessed pass. Measured before the change: the reference host passes all five (rc.58, 179 / 0 / 0 / 42); neither production host satisfies this predicate, so no existing claim moves. seeded from spec/v1/core-standard-manifest.json at P3-B; floor minted rc.45, one or more unaided witnesses per predicate family: interrupt (token scheme), replay (the effect-seam manifest \u2014 its seam-driven no-re-fire leg lives in v2-effect-seam-no-refire on the seams floor), webhooks (durable delivery), idempotency (Layer-1 key grammar), eventLog (era key, era stamp, closed event type, poll cursor). Deliberately absent: v2-pinned-run-disposition (seam-gated and opt-in), v2-v1-signed-webhook-accepted (a coexistence scenario, driven through the seam; the cut gate is its home), v2-effect-identity-business-key (retry leg seam-driven), v2-approver-enforced (conditional on the refKinds facet)."
|
|
2003
2019
|
},
|
|
2004
2020
|
{
|
|
2005
2021
|
"id": "openwop-conformance-seams-v2",
|
|
2022
|
+
"summary": "The host mounts the conformance test seams under /conformance/seams/ so the suite can drive seam-based scenarios; it is a testing surface, not a production feature.",
|
|
2006
2023
|
"predicate": {
|
|
2007
2024
|
"families": [],
|
|
2008
2025
|
"metadata": [
|
|
@@ -179,6 +179,11 @@
|
|
|
179
179
|
"peerDependencyId": {
|
|
180
180
|
"type": "string"
|
|
181
181
|
},
|
|
182
|
+
"extensionName": {
|
|
183
|
+
"type": "string",
|
|
184
|
+
"pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
|
|
185
|
+
"description": "RFC 0220 \u00a7A \u2014 ext families only (scripts/check-declaration.mjs requires it on every anchor: ext row and forbids it on core rows). The <name> half of the extensions key the family is advertised under, extensions[\"<org>.<extensionName>\"] (core/capabilities.md \u00a73.2). It is the kebab-case form of `key`: the family key is camelCase and cannot match extensionsKeyPattern, so a README that said `extensions.<org>.<key>` named a key no host could emit."
|
|
186
|
+
},
|
|
182
187
|
"witness": {
|
|
183
188
|
"enum": [
|
|
184
189
|
"witnessable-unaided",
|
|
@@ -283,6 +288,11 @@
|
|
|
283
288
|
"id": {
|
|
284
289
|
"type": "string"
|
|
285
290
|
},
|
|
291
|
+
"summary": {
|
|
292
|
+
"type": "string",
|
|
293
|
+
"minLength": 1,
|
|
294
|
+
"description": "One plain-English line: what claiming this profile means to an adopter. Carried into spec/v2/profiles.json."
|
|
295
|
+
},
|
|
286
296
|
"predicate": {
|
|
287
297
|
"type": "object",
|
|
288
298
|
"additionalProperties": false,
|