@openwop/spec-artifacts 2.27.1 → 2.29.0

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.27.1",
5
- "corpusTag": "v2.27.1",
4
+ "version": "2.29.0",
5
+ "corpusTag": "v2.29.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": "d7dc6f96a9fe8269588355ebe8279ef3e5650307e30f47c58ce1658a7ffbad0d",
13
- "api/v2/asyncapi.yaml": "770337ea7e7f174afa489a4763bbcae2999147957fb5b0d61765477a82f0504b",
14
- "api/v2/openapi.yaml": "5cd0995f46ec397099f5a3eb6541dfe24c96087ce233ec7e533304f7b72bd8f3",
12
+ "api/seams-v2.yaml": "df6322b0d6fbc13f326ace5706827700dd96fe510b19927dabf6c3e17fb8478e",
13
+ "api/v2/asyncapi.yaml": "5aff670bfb1644a0a54789f139df0320a2f3a8523b815e0c975198cb45eefccb",
14
+ "api/v2/openapi.yaml": "2c0c820e9349f8bc4c6432bdacbf777505dead4b778b8b828b3f8cfa7a0b1be5",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
@@ -115,8 +115,8 @@
115
115
  "schemas/v2/artifact-type-pack-manifest.schema.json": "85630d1b760d0b41cf5a6fad2acfada39abaf7f0befd95cc4334e1e883e9615d",
116
116
  "schemas/v2/audit-verify-result.schema.json": "a748dfadb5155adfde8a91045e76b0db6695005fe559035d71670fdd55edb3ba",
117
117
  "schemas/v2/budget-policy.schema.json": "c7449daeb6e1d95e7a047b8c2814d3d54748697c27046972834874867d9b5f4c",
118
- "schemas/v2/capabilities.schema.json": "50d3f90d6f92637e2f16956c99bc4826f69f28d935fb75fb06ab6fb910078706",
119
- "schemas/v2/certification-bundle.schema.json": "be5de0cc4362207c27885c51165c92c9541a545c5bd2c59da1d5c28fc265c162",
118
+ "schemas/v2/capabilities.schema.json": "e62d44f23c21c8f64b273fcdb083636e801c0de976cbd1f93333f99928dd1025",
119
+ "schemas/v2/certification-bundle.schema.json": "ab9204e37f9e0bba79857275cd38be2da98e54d26b4ecb97469829efe6ebea28",
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": "8df0d9d273ae22efc6876d5586833f1d4c2e551edc3ac6cf6e8f0719329f03dd",
@@ -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": "797d6f7addb37af320548cc4d6e94c81812d23cbb00573b8871044fea8170a3f",
204
+ "spec/v1/core-standard-manifest.json": "4c8703b02457252f69900c57084200547dd00d074b972a69da82939d590fe775",
205
205
  "spec/v1/deprecations.json": "307083ce29c23fd406015951f99a30d78d6187ff061d38dc9732f62191b40f3f",
206
206
  "spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
207
207
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
@@ -214,7 +214,7 @@
214
214
  "spec/v1/operation-path-manifest.json": "5f5f4e3842669371730ebbd1aace3fb794192615f0018dc144f484ba5db82ac3",
215
215
  "spec/v1/spec-gaps.json": "eb3bfcb9c7d05c9a6845d4a40ec9493cfaa5a671932daf1af561310136fdabe8",
216
216
  "spec/v2/README.md": "8dbfc17b10f373dba95bdd2e8fec0580f35b380a834d304be3e24e7498170185",
217
- "spec/v2/core/capabilities.md": "b3977e799d1d16c6ef9b306d5f07341f52259c19171c02c273a7e8a7a4b34473",
217
+ "spec/v2/core/capabilities.md": "4c4e5577caf4ae20c84fe59d580de4c6599e76783471d3b59f9730fc3807de71",
218
218
  "spec/v2/core/conformance.md": "a451c0a2ba79d93c55e540ccef480eba7de9602d59bbb03eead05daafde0beac",
219
219
  "spec/v2/core/connection-packs.md": "466bdb9dde79d85615ad8281dacfb7bf923ca22d7fb3ed219749e59574c753ed",
220
220
  "spec/v2/core/conversation.md": "e425887c4ba199b8cdc5c99e792689f7bd7d46de492f28670de2e402fa6d9506",
@@ -261,7 +261,7 @@
261
261
  "spec/v2/ext/sandbox-runtime-notes/README.md": "f7d591670415138e3889b7841e33e6964b166929f5aa1b09a95a7f8df44c40f9",
262
262
  "spec/v2/ext/webResearch/README.md": "e74fbe55a8c00040f1f87b5448259ee4eb3a26769d607f7d2dd9a671a2e2832b",
263
263
  "spec/v2/facets/a2a.schema.json": "6b0bceddec6d18d5115aa7d04720a0cc1ad7a9a0a78f53c208b34becaba5d16e",
264
- "spec/v2/facets/aiProviders.schema.json": "0c76e48e5d487b5be3b3ab1f6512a4e206c840ee5087d1336c7d7e2853b58d03",
264
+ "spec/v2/facets/aiProviders.schema.json": "81fb39b6698564d9d07a0d10525ecb6360c152fe3f3a5ea0439112509ca130e2",
265
265
  "spec/v2/facets/auth.schema.json": "73440c944ad12c41aab0618aeb799a90a0b59e97fc685527f248afb7d015381a",
266
266
  "spec/v2/facets/envelopeStrictness.schema.json": "28be0a27f880bd45ec1222a16155f5e9167bbca57bf0322970fe1eb2654562aa",
267
267
  "spec/v2/facets/heartbeat.schema.json": "81d7fa1895a8b0241bd07cf00a7e7905bef0fd14eb3427325261c62eee5746a6",
@@ -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": "86b4a81213e237b3a6679ff61f3ddc1b293a97a4ed60863a669466404a8b1951",
282
+ "spec/v2/release.json": "ecbd0e302a71adec924ebeff91e36fdd742f4f6b605912a94c0c9284864fc2e5",
283
283
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
284
284
  },
285
- "corpusCommit": "4fc3e402e637344eae95a13209bf71180f9b7138"
285
+ "corpusCommit": "1b2bc22e00b886cf92f47f1bca2c9e8a6df119fe"
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.27.1
4
+ version: 2.29.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.27.1
4
+ version: 2.29.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.27.1
4
+ version: 2.29.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.27.1",
3
+ "version": "2.29.0",
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": {
@@ -2953,11 +2953,67 @@
2953
2953
  },
2954
2954
  "policies": {
2955
2955
  "type": "object",
2956
- "additionalProperties": true
2956
+ "description": "Optional v1 host-side policy enforcement modes for per-provider gating. Omitted → no enforcement; clients see only `optional` semantics. When present, MUST declare `modes` — an empty `{}` is not a valid third state. See `capabilities.md` §`aiProviders.policies`. **Restored 2026-09-19:** the v2 override had reduced this to `{type: object, additionalProperties: true}` — an open object with no properties, no enum and no description — so anything validated, including a misspelled member. It was one of only TWO such facets in the whole v2 schema. MyndHyve's live major-2 document already advertises exactly the v1 shape, so restoring the constraint rejects nothing published and makes a typo fail instead of ship.",
2957
+ "required": [
2958
+ "modes"
2959
+ ],
2960
+ "properties": {
2961
+ "modes": {
2962
+ "type": "array",
2963
+ "items": {
2964
+ "type": "string",
2965
+ "enum": [
2966
+ "disabled",
2967
+ "optional",
2968
+ "required",
2969
+ "restricted"
2970
+ ]
2971
+ },
2972
+ "uniqueItems": true,
2973
+ "description": "Subset of policy modes this host can enforce. `disabled` = provider may not be used; `optional` = no restriction (default); `required` = BYOK required; `restricted` = model must match the policy's `allowedModels` glob list. Hosts MAY support a subset; clients MUST tolerate any subset."
2974
+ },
2975
+ "scopes": {
2976
+ "type": "array",
2977
+ "items": {
2978
+ "type": "string",
2979
+ "minLength": 1
2980
+ },
2981
+ "uniqueItems": true,
2982
+ "description": "Resolution layers the host evaluates. Conventional ids: `workspace`, `project`, `canvas-type`. Precedence is host-defined and SHOULD be documented per-deployment."
2983
+ },
2984
+ "errorCode": {
2985
+ "type": "string",
2986
+ "minLength": 1,
2987
+ "description": "Wire-format error code returned on denial. Defaults to `provider_policy_denied`. Reserved for hosts that need a vendor-prefixed alias."
2988
+ }
2989
+ },
2990
+ "additionalProperties": false
2957
2991
  },
2958
2992
  "input": {
2959
2993
  "type": "object",
2960
- "additionalProperties": true
2994
+ "additionalProperties": false,
2995
+ "description": "RFC 0091. Multimodal PERCEPTION input on `ctx.callAI` — the modalities a `callAI` message ContentPart may carry as model INPUT. Absent ⇒ text-only (today's behavior); a `string` message content is always valid. Distinct from `imageGeneration` (output) and the `ai-envelope.md` media emission types (output). **Restored 2026-09-19:** the v2 override had reduced this to `{type: object, additionalProperties: true}` — an open object with no properties, no enum and no description — so anything validated, including a misspelled member. It was one of only TWO such facets in the whole v2 schema. MyndHyve's live major-2 document already advertises exactly the v1 shape, so restoring the constraint rejects nothing published and makes a typo fail instead of ship.",
2996
+ "properties": {
2997
+ "modalities": {
2998
+ "type": "array",
2999
+ "uniqueItems": true,
3000
+ "items": {
3001
+ "type": "string",
3002
+ "enum": [
3003
+ "text",
3004
+ "image",
3005
+ "audio",
3006
+ "document"
3007
+ ]
3008
+ },
3009
+ "description": "Input modalities the host's `callAI` accepts as ContentParts. `text` is implicit even when omitted. A ContentPart whose `type` is not advertised here MUST be rejected with `unsupported_modality` (never silently dropped)."
3010
+ },
3011
+ "maxBytesPerPart": {
3012
+ "type": "integer",
3013
+ "minimum": 1,
3014
+ "description": "Optional host cap on a single inline (`data`) or `mediaRef` part."
3015
+ }
3016
+ }
2961
3017
  }
2962
3018
  },
2963
3019
  "allOf": [
@@ -259,7 +259,7 @@
259
259
  "properties": {
260
260
  "id": {
261
261
  "type": "string",
262
- "pattern": "^openwop\\.(?!it\\.(?:artifact-schema-compile-bounded|artifact-type-legacy-ids|capability-example-root-layout|certification-floor-enforcement|chain-subchain-unsupported-refused|compensation-profile|core-manifest-and-extension-registry|discovery-canonical-family-no-shadow|edge-condition-truthy-falsy|effect-identity-composition|effect-identity-cross-scope|error-envelope-canonical-shape|event-codemap-complete|form-content-packs|multi-region-effect-vocabulary|normative-example-extraction|openapi-asyncapi-sdk-parity|pack-manifest-extensions|protocol-version-grammar|registry-declarative-kinds|rfc-0147-self-audit|rfc-lifecycle-coherence|semantic-digest-v2|spec-corpus-validity|spec-section-citations|tool-result-trust-monotone|v2-alias-covers-reword|v2-bundle-signature-attributable|v2-corpus-tag-pinned|v2-declaration-parity|v2-envelope-catalog|v2-eos-clock|v2-error-registry-prose-parity|v2-event-naming-rule|v2-events-channel-parity|v2-externally-gated-never-stable|v2-facet-advertisement|v2-id-kinds-bound|v2-normative-home-gate|v2-one-signing-scheme|v2-path-parity|v2-release-identity|v2-req-only-assertions|v2-retention-floors|v2-seams-not-in-canonical|v2-security-defaults-table|v2-spec-artifacts-digest|v2-threat-model-template|v2-umbrella-alias-covered|v2-umbrella-child-parts|v2-umbrella-codemod-at-active|v2-umbrella-codemod-legs|v2-umbrella-migration-deprecation|v2-witness-required|versioned-composition-profiles|workflow-chain-internal-flag|workload-identity-profile)\\.)(requirement|it|scenario|floor|profile|family)\\.[a-z0-9]",
262
+ "pattern": "^openwop\\.(?!it\\.(?:artifact-schema-compile-bounded|artifact-type-legacy-ids|capability-example-root-layout|certification-floor-enforcement|chain-subchain-unsupported-refused|compensation-profile|core-manifest-and-extension-registry|discovery-canonical-family-no-shadow|edge-condition-truthy-falsy|effect-identity-composition|effect-identity-cross-scope|error-envelope-canonical-shape|event-codemap-complete|form-content-packs|multi-region-effect-vocabulary|normative-example-extraction|openapi-asyncapi-sdk-parity|pack-manifest-extensions|protocol-version-grammar|registry-declarative-kinds|rfc-0147-self-audit|rfc-lifecycle-coherence|semantic-digest-v2|spec-corpus-validity|spec-section-citations|tool-result-trust-monotone|v2-alias-covers-reword|v2-bundle-signature-attributable|v2-corpus-tag-pinned|v2-declaration-parity|v2-envelope-catalog|v2-eos-clock|v2-error-registry-prose-parity|v2-event-naming-rule|v2-events-channel-parity|v2-externally-gated-never-stable|v2-facet-advertisement|v2-front-door-counts|v2-id-kinds-bound|v2-normative-home-gate|v2-one-signing-scheme|v2-path-parity|v2-release-identity|v2-req-only-assertions|v2-retention-floors|v2-seams-not-in-canonical|v2-security-defaults-table|v2-spec-artifacts-digest|v2-threat-model-template|v2-umbrella-alias-covered|v2-umbrella-child-parts|v2-umbrella-codemod-at-active|v2-umbrella-codemod-legs|v2-umbrella-migration-deprecation|v2-witness-required|versioned-composition-profiles|workflow-chain-internal-flag|workload-identity-profile)\\.)(requirement|it|scenario|floor|profile|family)\\.[a-z0-9]",
263
263
  "description": "RFC 0168 §A.1 — `openwop.<area>.<slug>`. The suite mints six areas: `requirement` (an explicit `req()` id), `it` (a per-test id from the scenario file and title), `scenario` and `floor` (per-file rows), `profile` (a claimed-profile row) and `family` (a capability gate). The lookahead refuses every id minted from a corpus-coherence file: those run in the spec repo’s CI and MUST NOT appear in a host bundle (conformance.md §\"Two products, two ledgers\"; RFC 0168 §D.1). `scripts/check-req-only.mjs` fails when the list drifts from `conformance/src/coherence/`."
264
264
  },
265
265
  "scenario": {
@@ -283,7 +283,8 @@
283
283
  "type": "string"
284
284
  }
285
285
  }
286
- }
286
+ },
287
+ "description": "RFC 0148 §A — **THE LEDGER, and the array a consumer counts.** One row per requirement id the run resolved, carrying `scenario`, the `result` disposition and `assertions`. `results.totals` is this array tallied. `detail.nonPass[]` re-lists the SAME ids as a derived view with a different, smaller field set, so a consumer that walks the document generically sees every non-pass id TWICE and, depending on where it stops, reports either count as the size of the run. Two sessions did exactly that on one file within an hour of each other on 2026-09-19 — one read 227 rows and the other 317 (227 + 90), and a blocked-row count came out as 3 or 6 by the same mechanism. Count THIS array; read `detail.nonPass[]` for its `reason` text and nothing else."
287
288
  }
288
289
  }
289
290
  },
@@ -323,10 +324,11 @@
323
324
  "type": "string"
324
325
  }
325
326
  }
326
- }
327
+ },
328
+ "description": "RFC 0148 §A — **a DERIVED VIEW, not a second ledger.** Every id here also appears in `results.requirements[]`; this array exists to carry the human-readable `reason` for each non-pass row in one place. It MAY omit fields the ledger carries (`scenario` and `assertions` are absent by design, not by accident), so its rows are NOT interchangeable with ledger rows and MUST NOT be summed with them. A tool counting dispositions reads `results.requirements[]` or `results.totals`."
327
329
  }
328
330
  },
329
- "description": "Required when any result is not executed-pass (allOf below)."
331
+ "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."
330
332
  },
331
333
  "signature": {
332
334
  "type": "object",
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.27.1"
7
+ "version": "2.29.0"
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": "01cd71ccfc88f0cee6968546332f84295444e6556276da9ce74e08bc24736cc7"
422
+ "digest": "52c4dbbe51437017a4d82ba9ce3ce9a7c2e0f58e0db46a0d770553a73318fd25"
423
423
  }
@@ -69,7 +69,7 @@ Vendor and host extensions live under one key, `extensions`, whose members MUST
69
69
 
70
70
  `spec/v2/declaration.json` (schema `spec/v2/declaration.schema.json`) is the single source for: the generated `schemas/v2/capabilities.schema.json`; each family's `witness` class and maturity; the pack peer-dependency identifier (identical to the root key); the spec anchor (`core/capabilities.md#<key>` or `ext/<key>/`); the floor scenarios and requirement ids that define `openwop-core-standard`; and the profile predicates (§7). It replaces `extensions.json`, `core-standard-manifest.json`, `capability-declaration-classes.json`, and the capabilities half of `operation-path-manifest.json` (the operations half is `spec/v2/path-manifest.json`, `versioning.md`). It is generated from nothing and checked against everything (`scripts/check-declaration.mjs`).
71
71
 
72
- ## 5. Core families (71)
72
+ ## 5. Core families (72)
73
73
 
74
74
  Each heading is a `spec/v2/declaration.json` row with `anchor: core`; `scripts/check-declaration.mjs` MUST fail when a heading here, a root key in the generated schema, or a pack peer-dependency identifier names a family the declaration does not. The peer-dependency identifier is identical to the key (`packs.md`). Maturity axes are §7; the sentence under each heading names the witness class, the owning RFC, and, where `spec/v2/facets/<key>.schema.json` exists, the hand-decided facets.
75
75
 
@@ -43,11 +43,67 @@
43
43
  },
44
44
  "policies": {
45
45
  "type": "object",
46
- "additionalProperties": true
46
+ "description": "Optional v1 host-side policy enforcement modes for per-provider gating. Omitted → no enforcement; clients see only `optional` semantics. When present, MUST declare `modes` — an empty `{}` is not a valid third state. See `capabilities.md` §`aiProviders.policies`. **Restored 2026-09-19:** the v2 override had reduced this to `{type: object, additionalProperties: true}` — an open object with no properties, no enum and no description — so anything validated, including a misspelled member. It was one of only TWO such facets in the whole v2 schema. MyndHyve's live major-2 document already advertises exactly the v1 shape, so restoring the constraint rejects nothing published and makes a typo fail instead of ship.",
47
+ "required": [
48
+ "modes"
49
+ ],
50
+ "properties": {
51
+ "modes": {
52
+ "type": "array",
53
+ "items": {
54
+ "type": "string",
55
+ "enum": [
56
+ "disabled",
57
+ "optional",
58
+ "required",
59
+ "restricted"
60
+ ]
61
+ },
62
+ "uniqueItems": true,
63
+ "description": "Subset of policy modes this host can enforce. `disabled` = provider may not be used; `optional` = no restriction (default); `required` = BYOK required; `restricted` = model must match the policy's `allowedModels` glob list. Hosts MAY support a subset; clients MUST tolerate any subset."
64
+ },
65
+ "scopes": {
66
+ "type": "array",
67
+ "items": {
68
+ "type": "string",
69
+ "minLength": 1
70
+ },
71
+ "uniqueItems": true,
72
+ "description": "Resolution layers the host evaluates. Conventional ids: `workspace`, `project`, `canvas-type`. Precedence is host-defined and SHOULD be documented per-deployment."
73
+ },
74
+ "errorCode": {
75
+ "type": "string",
76
+ "minLength": 1,
77
+ "description": "Wire-format error code returned on denial. Defaults to `provider_policy_denied`. Reserved for hosts that need a vendor-prefixed alias."
78
+ }
79
+ },
80
+ "additionalProperties": false
47
81
  },
48
82
  "input": {
49
83
  "type": "object",
50
- "additionalProperties": true
84
+ "additionalProperties": false,
85
+ "description": "RFC 0091. Multimodal PERCEPTION input on `ctx.callAI` — the modalities a `callAI` message ContentPart may carry as model INPUT. Absent ⇒ text-only (today's behavior); a `string` message content is always valid. Distinct from `imageGeneration` (output) and the `ai-envelope.md` media emission types (output). **Restored 2026-09-19:** the v2 override had reduced this to `{type: object, additionalProperties: true}` — an open object with no properties, no enum and no description — so anything validated, including a misspelled member. It was one of only TWO such facets in the whole v2 schema. MyndHyve's live major-2 document already advertises exactly the v1 shape, so restoring the constraint rejects nothing published and makes a typo fail instead of ship.",
86
+ "properties": {
87
+ "modalities": {
88
+ "type": "array",
89
+ "uniqueItems": true,
90
+ "items": {
91
+ "type": "string",
92
+ "enum": [
93
+ "text",
94
+ "image",
95
+ "audio",
96
+ "document"
97
+ ]
98
+ },
99
+ "description": "Input modalities the host's `callAI` accepts as ContentParts. `text` is implicit even when omitted. A ContentPart whose `type` is not advertised here MUST be rejected with `unsupported_modality` (never silently dropped)."
100
+ },
101
+ "maxBytesPerPart": {
102
+ "type": "integer",
103
+ "minimum": 1,
104
+ "description": "Optional host cap on a single inline (`data`) or `mediaRef` part."
105
+ }
106
+ }
51
107
  }
52
108
  },
53
109
  "required": [
@@ -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.27.1",
4
- "corpusTag": "v2.27.1",
3
+ "version": "2.29.0",
4
+ "corpusTag": "v2.29.0",
5
5
  "updated": "2026-09-18"
6
6
  }