@openwop/spec-artifacts 2.45.22 → 2.45.23
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 +29 -27
- package/api/seams-v2.yaml +66 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +124 -1
- package/package.json +1 -1
- package/schemas/v2/capabilities.schema.json +17 -3
- package/schemas/v2/certification-bundle.schema.json +1 -1
- package/schemas/v2/error-envelope.schema.json +68 -3
- package/schemas/v2/ui-plugin-message.schema.json +5 -4
- package/spec/v1/alias-detectors.json +12 -0
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/deprecations.json +122 -96
- package/spec/v1/gaps.json +136 -0
- package/spec/v2/core/capabilities.md +1 -1
- package/spec/v2/core/conversation.md +5 -5
- package/spec/v2/core/errors.md +2 -2
- package/spec/v2/core/events.md +1 -1
- package/spec/v2/core/headers.md +5 -4
- package/spec/v2/core/packs.md +7 -5
- package/spec/v2/core/replay.md +1 -1
- package/spec/v2/declaration.json +9 -5
- package/spec/v2/errors.json +35 -1
- package/spec/v2/facets/nondeterminismPolicy.schema.json +22 -0
- package/spec/v2/facets/uiPlugins.schema.json +62 -0
- package/spec/v2/generated/error-codes.md +3 -1
- package/spec/v2/path-manifest.json +23 -1
- package/spec/v2/release.json +2 -2
- package/spec/v2/surface-baseline.json +16 -2
package/spec/v1/gaps.json
CHANGED
|
@@ -14292,6 +14292,142 @@
|
|
|
14292
14292
|
}
|
|
14293
14293
|
]
|
|
14294
14294
|
},
|
|
14295
|
+
{
|
|
14296
|
+
"id": "openwop.gap.0237.1",
|
|
14297
|
+
"rfc": "0237",
|
|
14298
|
+
"local": "G1",
|
|
14299
|
+
"section": "§D",
|
|
14300
|
+
"surface": "No host installs `conformance-nondeterminism` or lists `nondeterminismPolicy.sources`.",
|
|
14301
|
+
"witness": "unclassified",
|
|
14302
|
+
"requirementId": null,
|
|
14303
|
+
"disposition": "externally-gated",
|
|
14304
|
+
"target": "v2-reference-nondeterminism-fixture",
|
|
14305
|
+
"sources": [
|
|
14306
|
+
{
|
|
14307
|
+
"file": "RFCS/registers/0237-nondeterminism-sources.gaps.md",
|
|
14308
|
+
"token": "G1"
|
|
14309
|
+
}
|
|
14310
|
+
]
|
|
14311
|
+
},
|
|
14312
|
+
{
|
|
14313
|
+
"id": "openwop.gap.0237.2",
|
|
14314
|
+
"rfc": "0237",
|
|
14315
|
+
"local": "G2",
|
|
14316
|
+
"section": "§Conformance",
|
|
14317
|
+
"surface": "No host bundle records the two `openwop.requirement.0237.*` ids yet; the legs shipped in suite 2.45.23.",
|
|
14318
|
+
"witness": "unclassified",
|
|
14319
|
+
"requirementId": null,
|
|
14320
|
+
"disposition": "carried",
|
|
14321
|
+
"target": "openwop.gap.0237.2",
|
|
14322
|
+
"sources": [
|
|
14323
|
+
{
|
|
14324
|
+
"file": "RFCS/registers/0237-nondeterminism-sources.gaps.md",
|
|
14325
|
+
"token": "G2"
|
|
14326
|
+
}
|
|
14327
|
+
]
|
|
14328
|
+
},
|
|
14329
|
+
{
|
|
14330
|
+
"id": "openwop.gap.0237.3",
|
|
14331
|
+
"rfc": "0237",
|
|
14332
|
+
"local": "G3",
|
|
14333
|
+
"section": "§C",
|
|
14334
|
+
"surface": "The two required booleans stay in v2 (`overview.md` §0a predicate 4).",
|
|
14335
|
+
"witness": "unclassified",
|
|
14336
|
+
"requirementId": null,
|
|
14337
|
+
"disposition": "externally-gated",
|
|
14338
|
+
"target": "next-major",
|
|
14339
|
+
"sources": [
|
|
14340
|
+
{
|
|
14341
|
+
"file": "RFCS/registers/0237-nondeterminism-sources.gaps.md",
|
|
14342
|
+
"token": "G3"
|
|
14343
|
+
}
|
|
14344
|
+
]
|
|
14345
|
+
},
|
|
14346
|
+
{
|
|
14347
|
+
"id": "openwop.gap.0238.1",
|
|
14348
|
+
"rfc": "0238",
|
|
14349
|
+
"local": "G1",
|
|
14350
|
+
"section": "§B, §C",
|
|
14351
|
+
"surface": "No host serves the frame document or the dispatch operation at the normative paths, so none of the §F rows has a witness. openwop-app dispatches at a vendor path and mounts frames by `srcdoc`.",
|
|
14352
|
+
"witness": "unclassified",
|
|
14353
|
+
"requirementId": null,
|
|
14354
|
+
"disposition": "externally-gated",
|
|
14355
|
+
"target": "openwop-app-ui-plugin-served",
|
|
14356
|
+
"sources": [
|
|
14357
|
+
{
|
|
14358
|
+
"file": "RFCS/registers/0238-ui-plugin-observation-path.gaps.md",
|
|
14359
|
+
"token": "G1"
|
|
14360
|
+
}
|
|
14361
|
+
]
|
|
14362
|
+
},
|
|
14363
|
+
{
|
|
14364
|
+
"id": "openwop.gap.0238.2",
|
|
14365
|
+
"rfc": "0238",
|
|
14366
|
+
"local": "G2",
|
|
14367
|
+
"section": "Decisions 3",
|
|
14368
|
+
"surface": "A non-iframe isolation mechanism has no HTTP-visible boundary, so `frontend-plugin-isolation` keeps a seam witness for such a host.",
|
|
14369
|
+
"witness": "unclassified",
|
|
14370
|
+
"requirementId": null,
|
|
14371
|
+
"disposition": "externally-gated",
|
|
14372
|
+
"target": "non-iframe-ui-plugin-host",
|
|
14373
|
+
"sources": [
|
|
14374
|
+
{
|
|
14375
|
+
"file": "RFCS/registers/0238-ui-plugin-observation-path.gaps.md",
|
|
14376
|
+
"token": "G2"
|
|
14377
|
+
}
|
|
14378
|
+
]
|
|
14379
|
+
},
|
|
14380
|
+
{
|
|
14381
|
+
"id": "openwop.gap.0238.3",
|
|
14382
|
+
"rfc": "0238",
|
|
14383
|
+
"local": "G3",
|
|
14384
|
+
"section": "Decisions 5",
|
|
14385
|
+
"surface": "The always-on schema legs of `frontend-plugin-packs.test.ts` read only the corpus but run in a major-1 host bundle.",
|
|
14386
|
+
"witness": "unclassified",
|
|
14387
|
+
"requirementId": null,
|
|
14388
|
+
"disposition": "transferred",
|
|
14389
|
+
"target": "TODO.md",
|
|
14390
|
+
"sources": [
|
|
14391
|
+
{
|
|
14392
|
+
"file": "RFCS/registers/0238-ui-plugin-observation-path.gaps.md",
|
|
14393
|
+
"token": "G3"
|
|
14394
|
+
}
|
|
14395
|
+
]
|
|
14396
|
+
},
|
|
14397
|
+
{
|
|
14398
|
+
"id": "openwop.gap.0239.1",
|
|
14399
|
+
"rfc": "0239",
|
|
14400
|
+
"local": "G1",
|
|
14401
|
+
"section": "§F",
|
|
14402
|
+
"surface": "No host advertises `multiPartyConversation` together with the §E fixture, so none of the §F rows has a witness.",
|
|
14403
|
+
"witness": "unclassified",
|
|
14404
|
+
"requirementId": null,
|
|
14405
|
+
"disposition": "externally-gated",
|
|
14406
|
+
"target": "multi-party-council-host",
|
|
14407
|
+
"sources": [
|
|
14408
|
+
{
|
|
14409
|
+
"file": "RFCS/registers/0239-council-roster-input.gaps.md",
|
|
14410
|
+
"token": "G1"
|
|
14411
|
+
}
|
|
14412
|
+
]
|
|
14413
|
+
},
|
|
14414
|
+
{
|
|
14415
|
+
"id": "openwop.gap.0239.2",
|
|
14416
|
+
"rfc": "0239",
|
|
14417
|
+
"local": "G2",
|
|
14418
|
+
"section": "§C, Decisions 4",
|
|
14419
|
+
"surface": "A host whose `maxParticipants` is 64 or more cannot be shown an oversized roster: there is no schema ceiling and no v2 workflow registration.",
|
|
14420
|
+
"witness": "unclassified",
|
|
14421
|
+
"requirementId": null,
|
|
14422
|
+
"disposition": "externally-gated",
|
|
14423
|
+
"target": "v2-workflow-registration",
|
|
14424
|
+
"sources": [
|
|
14425
|
+
{
|
|
14426
|
+
"file": "RFCS/registers/0239-council-roster-input.gaps.md",
|
|
14427
|
+
"token": "G2"
|
|
14428
|
+
}
|
|
14429
|
+
]
|
|
14430
|
+
},
|
|
14295
14431
|
{
|
|
14296
14432
|
"id": "openwop.gap.spec.a2a-integration.g1",
|
|
14297
14433
|
"rfc": "0152",
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
8
|
-
No client route opens a conversation.
|
|
8
|
+
No client route opens a conversation. These are the obligations of a host advertising these families.
|
|
9
9
|
|
|
10
10
|
## `multiPartyConversation`
|
|
11
11
|
|
|
12
12
|
A host advertising `multiPartyConversation`:
|
|
13
13
|
|
|
14
|
-
- MUST accept
|
|
15
|
-
- MUST refuse a turn
|
|
16
|
-
- MUST refuse
|
|
14
|
+
- MUST accept optional `participants` (agent references) in `core.conversationGate` config and carry them on `conversation.opened`;
|
|
15
|
+
- MUST refuse a resumed turn whose `speakerId` is off that roster with `conversation_speaker_not_participant`, leaving the interrupt open;
|
|
16
|
+
- MUST refuse at run creation, never truncate, a roster over `multiPartyConversation.maxParticipants`, with `conversation_roster_exceeded`.
|
|
17
17
|
|
|
18
18
|
## `channelPresence`
|
|
19
19
|
|
|
@@ -25,4 +25,4 @@ A host MUST list it under `hostEvents` as ephemeral ([events.md](events.md) §Ho
|
|
|
25
25
|
|
|
26
26
|
A host that stamps model provenance on an agent turn MUST advertise `conversationTurnModelProvenance`. The stamp is non-secret and non-PII (provider and model identifiers only), and a host MUST NOT place prompt or completion content in it.
|
|
27
27
|
|
|
28
|
-
*Sources: RFCs 0101, 0109, 0110, 0236.*
|
|
28
|
+
*Sources: RFCs 0101, 0109, 0110, 0236, 0239.*
|
package/spec/v2/core/errors.md
CHANGED
|
@@ -8,7 +8,7 @@ Every error a v2 host returns is a row in one registry. A client routes on `erro
|
|
|
8
8
|
|
|
9
9
|
## The registry
|
|
10
10
|
|
|
11
|
-
`spec/v2/errors.json` holds one row per code, defined by `spec/v2/errors.schema.json`. It registers **
|
|
11
|
+
`spec/v2/errors.json` holds one row per code, defined by `spec/v2/errors.schema.json`. It registers **122** codes. `schemas/v2/error-envelope.schema.json` is GENERATED from it and MUST NOT be edited by hand.
|
|
12
12
|
|
|
13
13
|
- A host MUST emit a registered code, or a vendor code, wherever it emits an error code: the `error` of every error response, and `error.code` on `run.failed`, `node.failed` and the snapshot's `error` (overview.md §0). A recorded event re-emitted by replay or `:fork` is carried as recorded ([replay.md](replay.md)).
|
|
14
14
|
- A vendor code MUST match `^(?!openwop\.)[a-z][a-z0-9]*(-[a-z0-9]+)*\.[a-z][a-z0-9_]*$`, with its first segment an org registered in `spec/v2/declaration.json`. `openwop.` is reserved.
|
|
@@ -59,6 +59,6 @@ An operation gated on a family or facet the host does not advertise MUST answer
|
|
|
59
59
|
|
|
60
60
|
## Codes by HTTP status
|
|
61
61
|
|
|
62
|
-
Every registered code, by HTTP status, is listed in [error-codes.md](../generated/error-codes.md), generated from `spec/v2/errors.json` (
|
|
62
|
+
Every registered code, by HTTP status, is listed in [error-codes.md](../generated/error-codes.md), generated from `spec/v2/errors.json` (122 codes).
|
|
63
63
|
|
|
64
64
|
*Sources: RFCs 0171, 0213, 0227, 0228.*
|
package/spec/v2/core/events.md
CHANGED
|
@@ -201,7 +201,7 @@ An absent `kinds` is not an empty catalog and is not an unrestricted one: a host
|
|
|
201
201
|
|
|
202
202
|
## Envelope contracts
|
|
203
203
|
|
|
204
|
-
`envelopeContracts` advertises that a host enforces per-node envelope permission sets. A host advertising
|
|
204
|
+
`envelopeContracts` advertises that a host enforces per-node envelope permission sets; `advertised: false` is not a v2 state. A host advertising it MUST refuse a node whose emitted envelope `type` is neither universal nor listed in that node's accepted set. It MUST refuse it distinctly from the capability-gated `typeId` refusal: the two stack rather than substitute.
|
|
205
205
|
|
|
206
206
|
## Envelope, feedback and usage facets
|
|
207
207
|
|
package/spec/v2/core/headers.md
CHANGED
|
@@ -16,10 +16,10 @@ Standard headers keep their standard names: `Idempotency-Key`, `ETag`, `If-None-
|
|
|
16
16
|
| `Idempotency-Key` | 15 | Per-mutation idempotency token (`idempotency.md` Layer 1). The server caches `(tenantId, endpoint, key)` → response for ≥24h. A duplicate request returns the cached response with `OpenWOP-Idempotent-Replay: true`. |
|
|
17
17
|
| `If-None-Match` | 2 | Conditional request on the discovery document (capabilities.md §1) and the run snapshot (runs.md §Snapshot). A value that matches the current `ETag` (runs.md §Caching and encoding) MUST yield `304 Not Modified` with no body. The 304 carries `OpenWOP-Version` like every response (versioning.md §1.4). |
|
|
18
18
|
| `Last-Event-ID` | 1 | Resume from sequence after this ID. |
|
|
19
|
-
| `OpenWOP-Client-Version` |
|
|
19
|
+
| `OpenWOP-Client-Version` | 60 | The protocol version the client implements (versioning.md §1.5). Compared with `minClientVersion` on major.minor. A malformed value is treated as absent and MUST NOT produce a 400. Never selects a contract. |
|
|
20
20
|
| `OpenWOP-Dedup` | 1 | When set, the host's cross-host claim system rejects a duplicate `(tenantId, scopeId)` pair with `409 Conflict`. |
|
|
21
21
|
| `OpenWOP-Force-Engine-Version` | 1 | Test keys only. The server emits this run's events as if it ran the given engine version, which must be within `Capabilities.testing.forceEngineVersionRange`. Servers MUST reject it on production API keys with `403 force_engine_version_forbidden`. |
|
|
22
|
-
| `OpenWOP-Version` |
|
|
22
|
+
| `OpenWOP-Version` | 60 | Selects one of the host's listed major.minor versions. Absent, `/.well-known/openwop` uses `preferredVersion` and every other unversioned path is v2; an unlisted value is 406 protocol_version_unsupported. |
|
|
23
23
|
|
|
24
24
|
## Cross-origin preflight
|
|
25
25
|
|
|
@@ -32,12 +32,13 @@ A host that answers a CORS preflight for an operation by granting the requesting
|
|
|
32
32
|
| `Cache-Control` | 2 | Standard HTTP caching directive (RFC 9111), set per operation: public content-page delivery, and prompt templates (immutable semantics when the version was pinned); see each operation. |
|
|
33
33
|
| `Content-Encoding` | 1 | Present only when the host negotiated compression from `Accept-Encoding`; pairs with `Vary: Accept-Encoding`. The decoded body is byte-identical to the identity body. |
|
|
34
34
|
| `Content-Language` | 1 | The BCP-47 locale actually used (equals the response `locale`). |
|
|
35
|
+
| `Content-Security-Policy` | 1 | The plugin frame's isolation and egress policy. |
|
|
35
36
|
| `ETag` | 3 | Standard HTTP validator (RFC 9110 §8.8.3). The obligation is per operation: MUST on the discovery document (capabilities.md §1), SHOULD on the run snapshot (runs.md §Snapshot), a content hash on a prompt template (getPromptTemplate); see each operation. |
|
|
36
37
|
| `Location` | 1 | Canonical URI of the new template. |
|
|
37
38
|
| `OpenWOP-Idempotent-Replay` | 1 | Set when the response was served from the idempotency cache. |
|
|
38
|
-
| `OpenWOP-Version` |
|
|
39
|
+
| `OpenWOP-Version` | 60 | The contract that produced this response. It MUST equal the one used. |
|
|
39
40
|
| `Retry-After` | 1 | Seconds until the active claim is stale-eligible. |
|
|
40
|
-
| `WWW-Authenticate` |
|
|
41
|
+
| `WWW-Authenticate` | 53 | A `Bearer` challenge. On a host with an oauth2 or oidc lane it carries `resource_metadata` and `error="invalid_token"`. Never sent on a non-disclosure 404. |
|
|
41
42
|
|
|
42
43
|
## Webhook delivery headers
|
|
43
44
|
|
package/spec/v2/core/packs.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Pack manifests, the registry tree, peer-dependency identifiers, and signing. Per-kind rules live in [connection-packs.md](connection-packs.md), [form-content-packs.md](form-content-packs.md), [workflow-chain-packs.md](workflow-chain-packs.md), and [artifact-type-packs.md](artifact-type-packs.md); the capability vocabulary a pack requires is [capabilities.md](capabilities.md).
|
|
9
9
|
|
|
10
10
|
## The engine range
|
|
11
11
|
|
|
@@ -39,7 +39,7 @@ The registry is versioned by tree, not header. It publishes `registry/v2/packs/<
|
|
|
39
39
|
|
|
40
40
|
- A signed compatibility overlay MUST be rejected; a mirror re-derives the signer at ingest.
|
|
41
41
|
- `.well-known/openwop-registry.json` `endpoints` is the negotiation: it names both trees, and a client MUST resolve every registry path through it rather than construct one.
|
|
42
|
-
- `publicKey` is unversioned
|
|
42
|
+
- `publicKey` is unversioned.
|
|
43
43
|
|
|
44
44
|
## Peer-dependency identifiers
|
|
45
45
|
|
|
@@ -59,7 +59,7 @@ Facet paths are not identifiers: a pack requires a family by its key and names f
|
|
|
59
59
|
|
|
60
60
|
## The alias table
|
|
61
61
|
|
|
62
|
-
`spec/v2/peer-dependency-aliases.json` is generated from the declaration file and the published-manifest inventory, never hand-kept. It is how a v1-era key reaches a v2 family through the overlap. Each row is `{ alias, family, facets?, publishedUses, removalTrigger }
|
|
62
|
+
`spec/v2/peer-dependency-aliases.json` is generated from the declaration file and the published-manifest inventory, never hand-kept. It is how a v1-era key reaches a v2 family through the overlap. Each row is `{ alias, family, facets?, publishedUses, removalTrigger }`.
|
|
63
63
|
|
|
64
64
|
A v2 host MAY resolve an alias through the table during the overlap, and MUST NOT resolve one after v1 end-of-support (`removalTrigger: v1-end-of-support`).
|
|
65
65
|
|
|
@@ -79,7 +79,7 @@ Every pack-authored document MUST admit `patternProperties` `^(openwop-|x-|vendo
|
|
|
79
79
|
|
|
80
80
|
## Signing
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
`signing` on a version manifest (`schemas/v2/registry-version-manifest.schema.json`) is the closed object `{ keyId, scheme }`, both REQUIRED:
|
|
83
83
|
|
|
84
84
|
- **`scheme`** MUST be `ed25519-canonical-json`: a detached 64-byte Ed25519 signature over the RFC 8785 (JCS) bytes of `pack.json` inside a deterministic tarball. The input MUST satisfy `conformance.md` §"Canonical JSON".
|
|
85
85
|
- **`keyId`** is the signing key id.
|
|
@@ -124,6 +124,8 @@ A `frontend-plugin` pack (`schemas/v2/frontend-plugin-manifest.schema.json`) shi
|
|
|
124
124
|
- with `artifact.write`, MUST return an opaque `version` from each read and write and refuse a stale one with `artifact_conflict`, persisting nothing;
|
|
125
125
|
- MUST treat a plugin needing an unadvertised `surfaces` or `hostApi` entry as inert there, not an error.
|
|
126
126
|
|
|
127
|
+
With `uiPlugins.served`, a host MUST mount each plugin only from `getUiPluginFrame` and serve `dispatchUiPluginRequest`, whose rules bind.
|
|
128
|
+
|
|
127
129
|
A host without `uiPlugins` MUST reject the pack and render its own way.
|
|
128
130
|
|
|
129
131
|
On the message protocol:
|
|
@@ -139,4 +141,4 @@ On the message protocol:
|
|
|
139
141
|
- The v1 registry tree is frozen through the overlap, behind the v2 tree.
|
|
140
142
|
- `testMode` advertises the v1 `/v1/packs-test/*` mirror, a conformance seam ([conformance.md §"The seams profile"](conformance.md)). It remains advertisable through the overlap and is removed at 3.0.
|
|
141
143
|
|
|
142
|
-
*Sources: RFCs 0117, 0119, 0130, 0177, 0212, 0222.*
|
|
144
|
+
*Sources: RFCs 0117, 0119, 0130, 0177, 0212, 0222, 0238.*
|
package/spec/v2/core/replay.md
CHANGED
|
@@ -128,6 +128,6 @@ A host advertising `replay` MUST document retention for source snapshots, source
|
|
|
128
128
|
|
|
129
129
|
## Declared nondeterminism
|
|
130
130
|
|
|
131
|
-
`nondeterminismPolicy`
|
|
131
|
+
`nondeterminismPolicy.sources` lists the sources a host declares rather than suppresses: `clock`, `random`, `id`, `env` or `x-*`. A host MUST record each value drawn from a listed source where it is read, and a `replay` fork MUST reproduce it. An unlisted, unsuppressed source is a replay defect. `declared: false` is not a v2 state.
|
|
132
132
|
|
|
133
133
|
*Sources: RFCs 0036, 0039, 0041, 0057, 0104, 0111, 0140, 0173, 0176, 0194, 0228.*
|
package/spec/v2/declaration.json
CHANGED
|
@@ -1272,17 +1272,19 @@
|
|
|
1272
1272
|
"anchor": "core",
|
|
1273
1273
|
"section": "core/capabilities.md#nondeterminismPolicy",
|
|
1274
1274
|
"peerDependencyId": "nondeterminismPolicy",
|
|
1275
|
-
"witness": "
|
|
1275
|
+
"witness": "witnessable-gated",
|
|
1276
1276
|
"maturity": {
|
|
1277
1277
|
"technical": "experimental",
|
|
1278
1278
|
"adoption": "none"
|
|
1279
1279
|
},
|
|
1280
1280
|
"facets": [
|
|
1281
|
-
"declared"
|
|
1281
|
+
"declared",
|
|
1282
|
+
"sources"
|
|
1282
1283
|
],
|
|
1283
1284
|
"floorScenarios": [],
|
|
1284
1285
|
"requirementIds": [],
|
|
1285
|
-
"owningRfc": "0085"
|
|
1286
|
+
"owningRfc": "0085",
|
|
1287
|
+
"facetsFrom": "spec/v2/facets/nondeterminismPolicy.schema.json"
|
|
1286
1288
|
},
|
|
1287
1289
|
{
|
|
1288
1290
|
"key": "workspace",
|
|
@@ -1322,11 +1324,13 @@
|
|
|
1322
1324
|
"isolation",
|
|
1323
1325
|
"surfaces",
|
|
1324
1326
|
"hostApi",
|
|
1325
|
-
"maxEntryBytes"
|
|
1327
|
+
"maxEntryBytes",
|
|
1328
|
+
"served"
|
|
1326
1329
|
],
|
|
1327
1330
|
"floorScenarios": [],
|
|
1328
1331
|
"requirementIds": [],
|
|
1329
|
-
"owningRfc": "0117"
|
|
1332
|
+
"owningRfc": "0117",
|
|
1333
|
+
"facetsFrom": "spec/v2/facets/uiPlugins.schema.json"
|
|
1330
1334
|
},
|
|
1331
1335
|
{
|
|
1332
1336
|
"key": "sql",
|
package/spec/v2/errors.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://openwop.dev/spec/v2/errors.schema.json",
|
|
3
3
|
"$comment": "RFC 0171 §B.1 — the error registry: one row per code {code, meaning?, httpStatus, retriable, details, since, deprecated?}. schemas/v2/error-envelope.schema.json is GENERATED from it (scripts/generate-error-envelope.mjs). Retry timing lives in Retry-After only (§B.2). statusSource records whether the status was stated in v1 prose, a v1 convention, or decided here. details is null until a code's details schema is registered (a null row means details is an open object for that code — closure over details is the RFC 0171 Phase 3 follow-up G-row).",
|
|
4
4
|
"version": "2.0",
|
|
5
|
-
"updated": "2026-
|
|
5
|
+
"updated": "2026-10-06",
|
|
6
6
|
"vendorCodePattern": "^(?!openwop\\.)[a-z][a-z0-9]*(-[a-z0-9]+)*\\.[a-z][a-z0-9_]*$",
|
|
7
7
|
"rows": [
|
|
8
8
|
{
|
|
@@ -1390,6 +1390,40 @@
|
|
|
1390
1390
|
},
|
|
1391
1391
|
"since": "2.45",
|
|
1392
1392
|
"source": "RFC 0228 §C (measured: MyndHyve `host/agentDeployment.ts`, answered at 422)"
|
|
1393
|
+
},
|
|
1394
|
+
{
|
|
1395
|
+
"code": "conversation_speaker_not_participant",
|
|
1396
|
+
"meaning": "A resumed conversation turn names a speaker absent from the conversation's roster; the interrupt stays open. details.speakerId names it.",
|
|
1397
|
+
"httpStatus": 422,
|
|
1398
|
+
"statusSource": "v2 decision",
|
|
1399
|
+
"retriable": false,
|
|
1400
|
+
"details": {
|
|
1401
|
+
"type": "object",
|
|
1402
|
+
"required": ["speakerId"],
|
|
1403
|
+
"properties": {
|
|
1404
|
+
"speakerId": { "type": "string", "description": "The refused turn's speakerId (conversation.md §multiPartyConversation)." }
|
|
1405
|
+
},
|
|
1406
|
+
"additionalProperties": true
|
|
1407
|
+
},
|
|
1408
|
+
"since": "2.45",
|
|
1409
|
+
"source": "spec/v2/core/conversation.md §multiPartyConversation; RFC 0239 §B"
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
"code": "conversation_roster_exceeded",
|
|
1413
|
+
"meaning": "A core.conversationGate roster exceeds the host's advertised multiPartyConversation.maxParticipants; details.maxParticipants names the ceiling.",
|
|
1414
|
+
"httpStatus": 422,
|
|
1415
|
+
"statusSource": "v2 decision",
|
|
1416
|
+
"retriable": false,
|
|
1417
|
+
"details": {
|
|
1418
|
+
"type": "object",
|
|
1419
|
+
"required": ["maxParticipants"],
|
|
1420
|
+
"properties": {
|
|
1421
|
+
"maxParticipants": { "type": "integer", "minimum": 2, "description": "The host's advertised ceiling (conversation.md §multiPartyConversation)." }
|
|
1422
|
+
},
|
|
1423
|
+
"additionalProperties": true
|
|
1424
|
+
},
|
|
1425
|
+
"since": "2.45",
|
|
1426
|
+
"source": "spec/v2/core/conversation.md §multiPartyConversation; RFC 0239 §C"
|
|
1393
1427
|
}
|
|
1394
1428
|
]
|
|
1395
1429
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC 0237 §A — `sources` names the nondeterministic sources the host declares; `declared` stays required until 3.0 (overview.md §0a predicate 4) and MUST NOT be false (§C)",
|
|
3
|
+
"properties": {
|
|
4
|
+
"declared": {
|
|
5
|
+
"type": "boolean",
|
|
6
|
+
"description": "When `true`, the host documents its nondeterminism (it does not guarantee deterministic replay). A bare flag for v1.x (RFC 0085 §UQ2); a structured per-source policy is a future refinement."
|
|
7
|
+
},
|
|
8
|
+
"sources": {
|
|
9
|
+
"type": "array",
|
|
10
|
+
"uniqueItems": true,
|
|
11
|
+
"minItems": 1,
|
|
12
|
+
"items": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"pattern": "^(clock|random|id|env|x-[a-z0-9][a-z0-9-]*)$"
|
|
15
|
+
},
|
|
16
|
+
"description": "RFC 0237 §A. The nondeterministic sources the host declares rather than suppresses: `clock`, `random`, `id` (identifiers minted during a run), `env` (host configuration read during a run), or a vendor `x-*`. Each value drawn from a listed source is recorded where it is read, and a `replay` fork reproduces it (replay.md §Declared nondeterminism)."
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": [
|
|
20
|
+
"declared"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC 0117 + RFC 0238 — the uiPlugins family's facets. isolation, surfaces, hostApi and maxEntryBytes are carried unchanged from the v1 seed; served is v2-only (RFC 0238).",
|
|
3
|
+
"properties": {
|
|
4
|
+
"isolation": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"anyOf": [
|
|
7
|
+
{
|
|
8
|
+
"enum": [
|
|
9
|
+
"cross-origin-iframe",
|
|
10
|
+
"wasm",
|
|
11
|
+
"process",
|
|
12
|
+
"container",
|
|
13
|
+
"vm"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"pattern": "^x-host-[a-z0-9-]+-[a-z0-9-]+$"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"default": "cross-origin-iframe",
|
|
21
|
+
"description": "RFC 0117 (amended by RFC 0119). The categorical isolation model the host enforces for plugin bytes. `cross-origin-iframe` = a distinct-origin sandboxed browser frame (the browser default; §Isolation). `wasm`/`process`/`container`/`vm` mirror `sandbox.isolationModel` (RFC 0035) for non-browser hosts that enforce the SAME isolation property. Vendor-specific models advertise `^x-host-<host>-<key>$` per `host-extensions.md`. ALL values denote the SAME mandatory property (`frontend-plugin-isolation`): plugin bytes execute in a boundary with no access to the host's execution context / DOM / origin-storage / credentials, deny-egress by default, and all host interaction mediated by the closed `ui-plugin/1` RPC. The field names the MECHANISM, never relaxes the property. In-process / same-origin / module-federation loading is a protocol-tier MUST NOT regardless of the advertised value."
|
|
22
|
+
},
|
|
23
|
+
"surfaces": {
|
|
24
|
+
"type": "array",
|
|
25
|
+
"description": "Plugin surfaces this host renders. A pack's `uiPlugins[].surface` not in this set is installable-but-inert (§Degradation). `canvas-preview` (RFC 0130) mounts inside a host-owned canvas editor.",
|
|
26
|
+
"items": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"enum": [
|
|
29
|
+
"artifact-viewer",
|
|
30
|
+
"route",
|
|
31
|
+
"settings-panel",
|
|
32
|
+
"canvas-preview"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"uniqueItems": true
|
|
36
|
+
},
|
|
37
|
+
"hostApi": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"description": "The `ui-plugin/1` host-RPC methods this host honors. A plugin call to a method not in this set (regardless of the plugin's declared `hostApi`) MUST be rejected with `method_not_allowed` (`frontend-plugin-rpc-allowlist`). A host advertising `artifact.write` MUST enforce the `version`-token optimistic concurrency (RFC 0117 §Concurrency).",
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"enum": [
|
|
43
|
+
"artifact.read",
|
|
44
|
+
"artifact.write",
|
|
45
|
+
"host.toast",
|
|
46
|
+
"host.navigate",
|
|
47
|
+
"host.announce"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"uniqueItems": true
|
|
51
|
+
},
|
|
52
|
+
"maxEntryBytes": {
|
|
53
|
+
"type": "integer",
|
|
54
|
+
"minimum": 1,
|
|
55
|
+
"description": "Per-plugin entry-bundle byte ceiling the host will load."
|
|
56
|
+
},
|
|
57
|
+
"served": {
|
|
58
|
+
"type": "boolean",
|
|
59
|
+
"description": "RFC 0238 §A — `true` means the host serves `GET /host/ui-plugins/{packName}/{pluginId}/frame` (the frame document, isolation and egress in its `Content-Security-Policy`) and `POST /host/ui-plugins/{packName}/{pluginId}/rpc` (the `ui-plugin/1` dispatch) for every plugin it has installed (`packs.md` §Front-end plugin packs). A host advertising `uiPlugins` SHOULD advertise it."
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Status: Stable.** Generated from `spec/v2/errors.json` by `scripts/generate-error-envelope.mjs`; do not edit.
|
|
4
4
|
|
|
5
|
-
Every registered code (
|
|
5
|
+
Every registered code (122 codes), by HTTP status. The registry is normative; this table restates it for reading. `retriable` and `statusSource` are in the registry. The rules are in [errors.md](../core/errors.md).
|
|
6
6
|
|
|
7
7
|
Code | Status
|
|
8
8
|
--- | ---
|
|
@@ -93,6 +93,8 @@ Code | Status
|
|
|
93
93
|
`capability_not_provided` | 422
|
|
94
94
|
`capability_required` | 422
|
|
95
95
|
`connection_auth_metadata_mismatch` | 422
|
|
96
|
+
`conversation_roster_exceeded` | 422
|
|
97
|
+
`conversation_speaker_not_participant` | 422
|
|
96
98
|
`credential_required` | 422
|
|
97
99
|
`envelope_invalid` | 422
|
|
98
100
|
`envelope_refusal` | 422
|
|
@@ -240,6 +240,28 @@
|
|
|
240
240
|
"authenticated": true,
|
|
241
241
|
"requestBody": false
|
|
242
242
|
},
|
|
243
|
+
{
|
|
244
|
+
"method": "GET",
|
|
245
|
+
"path": "/host/ui-plugins/{packName}/{pluginId}/frame",
|
|
246
|
+
"operationId": "getUiPluginFrame",
|
|
247
|
+
"requestHeaders": [
|
|
248
|
+
"OpenWOP-Client-Version",
|
|
249
|
+
"OpenWOP-Version"
|
|
250
|
+
],
|
|
251
|
+
"authenticated": true,
|
|
252
|
+
"requestBody": false
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"method": "POST",
|
|
256
|
+
"path": "/host/ui-plugins/{packName}/{pluginId}/rpc",
|
|
257
|
+
"operationId": "dispatchUiPluginRequest",
|
|
258
|
+
"requestHeaders": [
|
|
259
|
+
"OpenWOP-Client-Version",
|
|
260
|
+
"OpenWOP-Version"
|
|
261
|
+
],
|
|
262
|
+
"authenticated": true,
|
|
263
|
+
"requestBody": true
|
|
264
|
+
},
|
|
243
265
|
{
|
|
244
266
|
"method": "GET",
|
|
245
267
|
"path": "/interrupts/{token}",
|
|
@@ -677,7 +699,7 @@
|
|
|
677
699
|
}
|
|
678
700
|
],
|
|
679
701
|
"counts": {
|
|
680
|
-
"operations":
|
|
702
|
+
"operations": 60,
|
|
681
703
|
"channels": 2
|
|
682
704
|
}
|
|
683
705
|
}
|
package/spec/v2/release.json
CHANGED
|
@@ -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.45.
|
|
4
|
-
"corpusTag": "v2.45.
|
|
3
|
+
"version": "2.45.23",
|
|
4
|
+
"corpusTag": "v2.45.23",
|
|
5
5
|
"updated": "2026-10-06"
|
|
6
6
|
}
|