@openwop/spec-artifacts 2.3.3 → 2.4.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.
Files changed (45) hide show
  1. package/CORPUS-STAMP.json +46 -46
  2. package/api/seams-v2.yaml +1 -1
  3. package/api/v2/asyncapi.yaml +1 -1
  4. package/api/v2/openapi.yaml +8 -4
  5. package/package.json +1 -1
  6. package/schemas/v2/form-content-pack-manifest.schema.json +31 -0
  7. package/schemas/v2/ids.schema.json +7 -7
  8. package/schemas/v2/run-event.schema.json +1 -1
  9. package/schemas/v2/trigger-subscription.schema.json +2 -3
  10. package/schemas/v2/webhook-delivery.schema.json +5 -5
  11. package/schemas/v2/workflow-chain-pack-manifest.schema.json +41 -40
  12. package/spec/v1/alias-detectors.json +7 -1
  13. package/spec/v1/core-standard-manifest.json +2 -2
  14. package/spec/v1/deprecations.json +86 -68
  15. package/spec/v1/gaps.json +41 -825
  16. package/spec/v1/spec-gaps.json +0 -784
  17. package/spec/v2/README.md +54 -15
  18. package/spec/v2/core/conformance.md +9 -7
  19. package/spec/v2/core/events.md +6 -1
  20. package/spec/v2/core/headers.md +1 -1
  21. package/spec/v2/core/interrupt.md +6 -0
  22. package/spec/v2/core/persistence.md +10 -7
  23. package/spec/v2/core/security-defaults.md +6 -7
  24. package/spec/v2/core/versioning.md +19 -7
  25. package/spec/v2/core/webhooks.md +4 -1
  26. package/spec/v2/ext/README.md +23 -13
  27. package/spec/v2/ext/a2uiSurface/README.md +18 -7
  28. package/spec/v2/ext/brand/README.md +18 -7
  29. package/spec/v2/ext/canvas/README.md +18 -7
  30. package/spec/v2/ext/chat/README.md +18 -7
  31. package/spec/v2/ext/coordination/README.md +18 -7
  32. package/spec/v2/ext/dataIntegration/README.md +18 -7
  33. package/spec/v2/ext/entities/README.md +18 -7
  34. package/spec/v2/ext/grpc-transport/README.md +10 -5
  35. package/spec/v2/ext/kanban/README.md +18 -7
  36. package/spec/v2/ext/knowledge/README.md +18 -7
  37. package/spec/v2/ext/launchStudio/README.md +18 -7
  38. package/spec/v2/ext/messaging/README.md +18 -7
  39. package/spec/v2/ext/portability/README.md +11 -2
  40. package/spec/v2/ext/provider-idempotency/README.md +10 -2
  41. package/spec/v2/ext/restTransport/README.md +18 -7
  42. package/spec/v2/ext/sandbox-runtime-notes/README.md +9 -2
  43. package/spec/v2/ext/webResearch/README.md +18 -7
  44. package/spec/v2/id-field-bindings.json +4 -4
  45. package/spec/v2/release.json +3 -3
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.3.3",
5
- "corpusTag": "v2.3.3",
4
+ "version": "2.4.0",
5
+ "corpusTag": "v2.4.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": "ac5a7fdff795eeee34d61af878afd61657ade24745dc8e87b970a18148571ed5",
13
- "api/v2/asyncapi.yaml": "1bb9761fc9e90b5dd5c05f208b01d597691b52792dd2a488d4382467390d55dd",
14
- "api/v2/openapi.yaml": "883ac5a1e6d9056b1acdd79538341d05a005f3f58fb9751237fd6d9ba0167fc9",
12
+ "api/seams-v2.yaml": "d7297c933f4987c085f1427b1cb245c0e7f88d0ab91a1d1534c7959bb659940e",
13
+ "api/v2/asyncapi.yaml": "5730b64974958076b2da1e77990011228465c088334a8a5c6005e136cf86e20d",
14
+ "api/v2/openapi.yaml": "cc94e454854f28d7aae5f0cab264a21dfdc8ce43259dfd30ea4e2340ede756fc",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
@@ -144,12 +144,12 @@
144
144
  "schemas/v2/error-envelope.schema.json": "9c8f747e5bea81943d70e0930bc7d26586a4c3a3d90be77f46359b19b7e56cbe",
145
145
  "schemas/v2/eval-summary.schema.json": "9d31025752d0f67ad3b8a32e82a5314972c530ef9f780dd82e484ae8c5131198",
146
146
  "schemas/v2/export-bundle.schema.json": "bd28905a7729437ab7f2ad8bb33e13a371b2bf5605a7eb2962a0d246de312d69",
147
- "schemas/v2/form-content-pack-manifest.schema.json": "307884e57946703b6f86ec283034bf56beb68bea4a000743ebbc9eebeed31b07",
147
+ "schemas/v2/form-content-pack-manifest.schema.json": "461529e4287ec3b15a9fbcde57226a1c6f17ea3ae71b33b418e6f595ff0619fe",
148
148
  "schemas/v2/frontend-plugin-manifest.schema.json": "fed6b8ddb3056c53b1bfc91525410a4445a3c37a8bf9eb9f6f9964ffea26d993",
149
149
  "schemas/v2/goal.schema.json": "146c4182e36d3538778f947e668a92cdb69ec42ee0820104b00063b035e342d7",
150
150
  "schemas/v2/heartbeat-evaluated.schema.json": "4086b1ba1d0547c08b038dfb263ac89416a3e406430db1250156fb2f9b74f8d6",
151
151
  "schemas/v2/heartbeat-state-changed.schema.json": "eb68d0082aa996650e3a6b8ccf32457f959cebc7e6728cc7c331b9d171a4bef6",
152
- "schemas/v2/ids.schema.json": "6481cab16c9b89fab168627502dcbf2ee7489b5a636a4080ea8cfd2670d7b17e",
152
+ "schemas/v2/ids.schema.json": "65cfaa193be0ca9cf48af39c18c553979e3ec1f7fc04509aaa513b322d7b7e4a",
153
153
  "schemas/v2/localized-content-language-settings.schema.json": "92240f19a2b4b2f05ab41a797f703485a28813848035478e72f395edd04c1d35",
154
154
  "schemas/v2/localized-content-page-response.schema.json": "ef48329749758afb21e4d3cbc3f017abb911f75726819457f35b9f1390332c75",
155
155
  "schemas/v2/localized-content-page.schema.json": "e0f97660121955d6705d935f34e748adb739ac70f8536a009cd8d6f303735151",
@@ -170,7 +170,7 @@
170
170
  "schemas/v2/run-ancestry-response.schema.json": "334c17f2062dea62726ca1d07b8be3f169cdc422af843c1def5fb317039814c9",
171
171
  "schemas/v2/run-diff-response.schema.json": "8bdb2045c274580038bd74781f7d062f5049839797c164a89de4ed89edc53a74",
172
172
  "schemas/v2/run-event-payloads.schema.json": "29dec16f0d40c9022c169d4d413742ddd775a3d8c895d3a60ccc093e2a872439",
173
- "schemas/v2/run-event.schema.json": "1a9946374af9323b71635d00fed22abe02c300fa2cf3ae3e9c30f3e553e408ec",
173
+ "schemas/v2/run-event.schema.json": "2f0d7416bd376c56affe97b6b2b49981532e8e9ff45c0a162cf806c78b3e7fb7",
174
174
  "schemas/v2/run-list-response.schema.json": "c2dbc34768dcf64528914a213aa3cb55952e8e3e90a64b04a9423b2a19749d38",
175
175
  "schemas/v2/run-options.schema.json": "f0e9f494d80086c2ed2cf9fe87df54e5b4e66601699c4a1089f4edbc7ba58867",
176
176
  "schemas/v2/run-orchestrator-decided-event.schema.json": "bb76e15ff72e669f12938684033b55dc567470e1a378e19ffc3fa0e4034ab5a7",
@@ -185,10 +185,10 @@
185
185
  "schemas/v2/tool-descriptor.schema.json": "658b18ef173e0f12d732f92d4866a9b3daeb8f88b493db8b025a577e09dd681c",
186
186
  "schemas/v2/trigger-event.schema.json": "7227fb9a130c33374fa8eab35e4448c4e8f22c962b8f271781cf4dbb5e4288b7",
187
187
  "schemas/v2/trigger-subscription-registration.schema.json": "04bc314a07c7e8b565577cb8df5821d968ce2af915900dfdccd4a24e928d20db",
188
- "schemas/v2/trigger-subscription.schema.json": "074bec7f016aa9f4d60359c3a093296cc847045510f01e0a9dceaf4fa5084d12",
188
+ "schemas/v2/trigger-subscription.schema.json": "c887d4b9a12be0133f8c9dfd3a8bafcb518e27ecc2e800447ebc4d1fef111503",
189
189
  "schemas/v2/ui-plugin-message.schema.json": "879d65867c01656b3962d64283e66364dcb8f626ad26c5fcf2d2d55a79ae0ce9",
190
- "schemas/v2/webhook-delivery.schema.json": "66025cd7b7899b6897b61c61e99ec2c554e232a6c9742124441adcd81912cef0",
191
- "schemas/v2/workflow-chain-pack-manifest.schema.json": "22801f14845a3df30660e6f31a41e1a3fbff2425bf56c8a475eab96f1c95882a",
190
+ "schemas/v2/webhook-delivery.schema.json": "4e8ab3b722ad1731adf0548c1217f0de62da40de14e8abf77533aee4ace4c079",
191
+ "schemas/v2/workflow-chain-pack-manifest.schema.json": "b61cc945b4df1c7093a1058fa71ee59ef10bacb3433ae4d7ae7536136e616cc2",
192
192
  "schemas/v2/workflow-definition.schema.json": "9aafddec32b84eb6aec3185be024850f1b9444c6193568771b0b636595fef136",
193
193
  "schemas/v2/workload-identity.schema.json": "1f589debfac6d70e0908da511550ec69a27b4bcc8314551cd843b6d923605efc",
194
194
  "schemas/v2/workspace-file-create.schema.json": "b6b5260857318c3b67de0231ed15e3a746f525880a763e7b36a7854178dd10d0",
@@ -198,65 +198,65 @@
198
198
  "schemas/workload-identity.schema.json": "64ed93e12cc9f0657e56ff9b8f045e5d68d397df5276d103c07f42c7f34f0579",
199
199
  "schemas/workspace-file-create.schema.json": "70a23b92c2958c0165d7d29aea9020a045dc7816af82c80c5f50d0aac19c4856",
200
200
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
201
- "spec/v1/alias-detectors.json": "fee4594ef49953953ffcd0b3813300067d16b3e65ebff2aac722034ac9b3f545",
201
+ "spec/v1/alias-detectors.json": "e90916db12d2297e2e560b2d54d2c4702d6cb3bef7179a575844687a7ec17262",
202
202
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
203
- "spec/v1/core-standard-manifest.json": "2c9150bdde2ae37e788f947110acb2503ff33299f5cf74bc522bcf32f10bd02e",
204
- "spec/v1/deprecations.json": "508071308e762c281807b487e8f3840a1a69b978071894593e18f2e2d3e4b5c0",
203
+ "spec/v1/core-standard-manifest.json": "41af65d02636d651a99f0f48caa5dd5ed45be576f745166bd1510908674997e0",
204
+ "spec/v1/deprecations.json": "c81c8f71460936c8d489d8270477c7661cf4a5d7b7bad86c98899750b5656027",
205
205
  "spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
206
206
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
207
207
  "spec/v1/event-codemap.schema.json": "d05933b2e88103aff51a2f774df97b9bda065e0fc88dbd9b114cc47a32189174",
208
208
  "spec/v1/extensions.json": "79a60754aa16cbdbdb604f8e5c00038af535a1690a4d07bd5ff7c38f0256a7bc",
209
- "spec/v1/gaps.json": "96ca051cb20f1a669b355d67a89421c56fef28aa5e6710c9519f592f26af33a3",
209
+ "spec/v1/gaps.json": "6f595da01299deecf928d358449eb7f97ebf9bbfe82e40be82f629f0e256cdfd",
210
210
  "spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
211
211
  "spec/v1/migrations.json": "8839497d6a4830b53fa7867014a8336f0d725ef2346352e54fb580b7947897af",
212
212
  "spec/v1/migrations.schema.json": "886779aa6c22e646db097f5df210adb018a4dd14a7b815465a18c8a7056c8f72",
213
213
  "spec/v1/operation-path-manifest.json": "5f5f4e3842669371730ebbd1aace3fb794192615f0018dc144f484ba5db82ac3",
214
- "spec/v1/spec-gaps.json": "6cc9962c6b969f632e07a78b52a4f61447ff579e2990cbae989866f584a86042",
215
- "spec/v2/README.md": "0f8a5c36ca9af5c6aa80b2e24ecf2d6af5ede9964bf70e88839110d9beab5693",
214
+ "spec/v1/spec-gaps.json": "eb3bfcb9c7d05c9a6845d4a40ec9493cfaa5a671932daf1af561310136fdabe8",
215
+ "spec/v2/README.md": "5d49f56f41e06b44312c61ad8144b786c9a90ec42fd0660a40d89520ef206137",
216
216
  "spec/v2/core/capabilities.md": "c5107a4964e487c20bbb5254cfe1f706e0d9ba7e34da9070bc43b50b385e7948",
217
- "spec/v2/core/conformance.md": "622084e3c74c4549087f4d861b1bb98cec201a0c5aec23788d27f53a355fde3b",
217
+ "spec/v2/core/conformance.md": "b8d7dae142e3708a7597533cb77827363b6cfc91b89538081a9afe5e23c975f4",
218
218
  "spec/v2/core/connection-packs.md": "1d759681e2962f5103228c52c45f24607ed4bb9ae73e30605f690c1d5a59e9ee",
219
219
  "spec/v2/core/errors.md": "ad85fc830139e587f20deabf88297b91b1fb6ce31e80d5442624a650246ab16e",
220
- "spec/v2/core/events.md": "20112f459e7f1bcab0e93fbfc2e28719ecd1435228e87c5476b9eaa691558603",
220
+ "spec/v2/core/events.md": "f1bac16419740f3b722febb6f5caaabed8838e092cba3d080fe9184024049dcf",
221
221
  "spec/v2/core/form-content-packs.md": "6ffaae85d4550be48dd53fb6e2959af8aceb35bd87c5343b722885084f197713",
222
- "spec/v2/core/headers.md": "2dd67d71673539e16612f09f3f2513a384f6566052d7cd8a00885885689854c2",
222
+ "spec/v2/core/headers.md": "6f350e4a6893e82fcab40aec6cb515b989e8b56a20a74f6d10d24a0d3fdf5cf0",
223
223
  "spec/v2/core/idempotency.md": "b86c352d964aebad532727f314e26ed2177d49de382076fa64d3162e2f56118d",
224
224
  "spec/v2/core/identity.md": "9d2b823eb899463807452fe5721dcf09881837c161be024175957db27870b243",
225
225
  "spec/v2/core/interop.md": "d4c404e469e1d9d9be88bc2c939d777e7d7c1d0419b1251c18770f039838a401",
226
- "spec/v2/core/interrupt.md": "f525479a99104655219fa2e51c4cad2a03d8e3be93ff4dac173a684675e57348",
226
+ "spec/v2/core/interrupt.md": "548c7a7bdfcab56db33dfad3d397cae2ed5f9828a63418021936eb392395e3e4",
227
227
  "spec/v2/core/overview.md": "69377c90bbb87b6bfe4b8be4f1b65810094b0759c8d4f93ca6df92cc530ea023",
228
228
  "spec/v2/core/packs.md": "8b3e1587270bb1aec814befbd287181a05b7f76aeb0802787ee7ebdc85901205",
229
- "spec/v2/core/persistence.md": "2373c2815b25b7b4fe29dfdf3783d3f2f3e637d3abce5085e69f019546302fb6",
229
+ "spec/v2/core/persistence.md": "898dc929d021a03d245691148fe4fdec4582b4faa9237aa32037bbd3a2993b7d",
230
230
  "spec/v2/core/replay.md": "bd191a2565aa7ad0df9b35a0716f3de53be34b8722f1807c5e5b02859404a9b9",
231
231
  "spec/v2/core/runs.md": "f7a95fc82fda5b7c0c613de6e5edd376bbd6d8ba4c665a500c94eacbe42b86f2",
232
- "spec/v2/core/security-defaults.md": "1d38aa03b9d2507f1d4a985333cc57ae7892cecc7356f6342fbd1672e34f638a",
233
- "spec/v2/core/versioning.md": "d731782eeabb953919c7c7057340b7f9c2916b6186790e6b04c7d8ea60767189",
234
- "spec/v2/core/webhooks.md": "158aff629f66cf1ea483e188eba3ef9695d9868d9b525353189db6d7a3c099d6",
232
+ "spec/v2/core/security-defaults.md": "d69a8dfc9057e189caa61f14810e3090b3b053e8fde419d09db84729a42b84c7",
233
+ "spec/v2/core/versioning.md": "fd6564879cf043b68338db20b20de93755a1e7147000afb4738c07770deeddaf",
234
+ "spec/v2/core/webhooks.md": "969c367650e5e93beb090242bcbec59f43b95bdf646fa6c512f6c7fa1f05912e",
235
235
  "spec/v2/core/workflow-chain-packs.md": "ef2b07d2d99334eaec0cc370314e2ad2f84ea58deb699e5d92e6e52d6056613f",
236
236
  "spec/v2/declaration.json": "a09bac61c1b825e4a77b5abc0f86f1f8c20c381e0650eb08c2f6d0ef0aaec1dc",
237
237
  "spec/v2/declaration.schema.json": "c86e3083fb9789c1958ecb4576cc6f71aa90e6f339521139238543ed08211dd4",
238
238
  "spec/v2/errors.json": "4ff032033f02d7e3fb4204581456408ba5e7642b438c1f349bbd1c264e63e419",
239
239
  "spec/v2/event-codemap.json": "37869a03cdfd8758b57e6f350641a6ebbd383231cebda51f5473ad85f94ab74c",
240
240
  "spec/v2/event-codemap.schema.json": "b173f2a9bcc0bf9b62a474ce3b91e1431d597e64fd1560fc58662cd8606eaf9c",
241
- "spec/v2/ext/README.md": "c7dea12c48772047f18b111e73be1c236460e72d9bf98026351d148a2ac4f608",
242
- "spec/v2/ext/a2uiSurface/README.md": "176cb0542e1c236ffcd6d682536ba0081242684444e2dec790abd480a44a571e",
243
- "spec/v2/ext/brand/README.md": "1a80102a9cd766dcb6098c999e552af88f5b83c88951acde18d17cc0b29aa09d",
244
- "spec/v2/ext/canvas/README.md": "a2d5f28523753e8e85cc9042db39faf9207a2eebce1a8553be22e341f7ea58d9",
245
- "spec/v2/ext/chat/README.md": "39fe2961502d2937fe487cf52acfffeeb4a396731f0b2bf737b109eac2752bca",
246
- "spec/v2/ext/coordination/README.md": "a193aa9a59a2d9ac8d2e9775e5be40c29b6f7476ffef35231dbab49377af9207",
247
- "spec/v2/ext/dataIntegration/README.md": "8361c626ed9f77dc48a3bcaa0c9f769cb6706632941014700f7683efe0918bd1",
248
- "spec/v2/ext/entities/README.md": "c3bf6c59ddf2255c22a522e689f6e7a11646fbcd309b17699b6cf69a4e2e0f91",
249
- "spec/v2/ext/grpc-transport/README.md": "9913c3f5433b719533e0721af477917bf7a993372388aa800be8bff9d4f8e203",
250
- "spec/v2/ext/kanban/README.md": "6792926f7f0cb8a4dcb0acdedb86a1988574fb0b5de164b37159dfe3ba35f908",
251
- "spec/v2/ext/knowledge/README.md": "d2615320c7de4aec279f276381376a8881e962dd4e86b1435462d742dd00a52f",
252
- "spec/v2/ext/launchStudio/README.md": "bfe417e774689773f3bbced9fdfa0c18809577aa6040a1312d914c821beed026",
253
- "spec/v2/ext/messaging/README.md": "8a4702935483ce7900c0ee14793f9dfbeeb09d5e43f8943c946f8f94de2efa6f",
254
- "spec/v2/ext/portability/README.md": "7525fdc595b05dfd0b2bd22e2f7b3a13302164ebf49e4327c2e29e9da80766f4",
255
- "spec/v2/ext/provider-idempotency/README.md": "5efa5b220e22d8f9a93918d20d3be0c698445d828693c8e487f37abc39bfca7c",
241
+ "spec/v2/ext/README.md": "68b4203c1ffcb1434af79b5e04ae3d23501977e7d48b2256c18a6c92559f6270",
242
+ "spec/v2/ext/a2uiSurface/README.md": "7dfdd0db93b8bd2d8cfb0ebcc7c474f21f2cb0d3108cb66becf311288d21a9ef",
243
+ "spec/v2/ext/brand/README.md": "f5d3c6232e0a63fe445e9707dd6b0e117f8ececcec7194049fafa5562b63aa10",
244
+ "spec/v2/ext/canvas/README.md": "601537975b78d6f762a4a42c7cae583c54c61dfb73817cef99ac03177e671c11",
245
+ "spec/v2/ext/chat/README.md": "f4023b16b3749fbe3786439e370ee73c459c02f8d1c439b5df0287e1f24e1e56",
246
+ "spec/v2/ext/coordination/README.md": "70b00ede75f22c5fbdf4d8e0840d82d2dfeac61bda1459f94d6ebc2adb6d2865",
247
+ "spec/v2/ext/dataIntegration/README.md": "0a040215adbfc1cc176c2fbe052598701c9c36461367f0cd6b9e8d7bb1ee20da",
248
+ "spec/v2/ext/entities/README.md": "24cbf19103cb4711f41088a79a49077eaf4750b0c746764a8302e33b74ea54c8",
249
+ "spec/v2/ext/grpc-transport/README.md": "0d01d939fc7a4eab050f141b42e4fe145f312bcdd89ef78359a47e33c4e94751",
250
+ "spec/v2/ext/kanban/README.md": "c6b3b3bbf6c9cecae674fc7874e145dc3e4f723a864409ad6e96b0173868f801",
251
+ "spec/v2/ext/knowledge/README.md": "067280b15e14b3c46550d7b0ee68d49e7d1455ce86218d05bbc44535eb668bf1",
252
+ "spec/v2/ext/launchStudio/README.md": "3c4258e781d069dced34ab45552ce5b2b4af6ec7e08f0e2e00584d87a7981b15",
253
+ "spec/v2/ext/messaging/README.md": "0ce7535498458ad63d9b7d5b143da618a2da2ce4033ca53ea3fc4cb0c65419db",
254
+ "spec/v2/ext/portability/README.md": "15b8a881df861ff289489ca13a3a4871cf6e14aed90ca018afadff2388a05476",
255
+ "spec/v2/ext/provider-idempotency/README.md": "e3f159b2d1b53c4c279b911de91d80b5410a1e6a05ba940a7f4d2c0d547cf000",
256
256
  "spec/v2/ext/provider-idempotency/registry.json": "5b5fecad604fb4ab38da39f5abe697a4e57b05406c398f8afeb377331b2bd965",
257
- "spec/v2/ext/restTransport/README.md": "b39f4d1ddbabd72dd945a39e90218d8413e46baea1269798b96dffb4e429cb4f",
258
- "spec/v2/ext/sandbox-runtime-notes/README.md": "bd0c4ca4d0fbcba2ae948a02ddc768f50b08a33d9f0622efa1c9e2b7beab2969",
259
- "spec/v2/ext/webResearch/README.md": "941dfe8323fd536791167f9fc7d119dd4e165bb7937e3382a19f15cda3d9f19a",
257
+ "spec/v2/ext/restTransport/README.md": "8cfc6471ca1ca6e43bb53b21d47b33e73c6a5821e631eb4f565b971c01e2e5de",
258
+ "spec/v2/ext/sandbox-runtime-notes/README.md": "94a25409596e5122c217c566cb02bd44dde33c8130f52507988d498def598f29",
259
+ "spec/v2/ext/webResearch/README.md": "76409f9d6a4aa512ba2b8bdffe706b2b509503266037c3ef890950f7b8c9bd2b",
260
260
  "spec/v2/facets/a2a.schema.json": "6b0bceddec6d18d5115aa7d04720a0cc1ad7a9a0a78f53c208b34becaba5d16e",
261
261
  "spec/v2/facets/aiProviders.schema.json": "0c76e48e5d487b5be3b3ab1f6512a4e206c840ee5087d1336c7d7e2853b58d03",
262
262
  "spec/v2/facets/auth.schema.json": "73440c944ad12c41aab0618aeb799a90a0b59e97fc685527f248afb7d015381a",
@@ -267,12 +267,12 @@
267
267
  "spec/v2/facets/runList.schema.json": "6223e1baaebbb9f4faa71bfe968f8d22b4aa88046d0e43e8d5f56409e7f86e90",
268
268
  "spec/v2/facets/sandbox.schema.json": "e75f54486d387b2d089791aa93b5093cd1450f1920753a0f97fc23acdfe978ed",
269
269
  "spec/v2/facets/webhooks.schema.json": "0b766033ef4b4c6c2ac6f9979a19843ba024d3a1d1576972dcb55aaba52f1b9a",
270
- "spec/v2/id-field-bindings.json": "eecadfd11581ba2e075ccb320d85fc033b816edfdd51edb5c5727a181e55dcb4",
270
+ "spec/v2/id-field-bindings.json": "e73c06f3055ad30173507ac817a458b96362c8f26209ba105c53653292cf63d3",
271
271
  "spec/v2/path-manifest.json": "a6f4e652e866889e8bde815874062f62929aee95dc8e58e7152c56adee262163",
272
272
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
273
273
  "spec/v2/profiles.json": "0636f19fceae625390003a347e70ef4797d84766b5c24ce8a02cea52aadebca4",
274
- "spec/v2/release.json": "ffb0a24cba6ab87c4b99a76d51868e42eb07bd337157836cf5e59b9e13ad44e0",
274
+ "spec/v2/release.json": "975e8d6100d4c0697384dd093eb586eed3f41481a26b954e052fa321525a0273",
275
275
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
276
276
  },
277
- "corpusCommit": "c2e93ea53a5c87dea90697dc166d540b6fc0f945"
277
+ "corpusCommit": "5f410d86a87e25473f8e1d63ce08e9b0947c7e43"
278
278
  }
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.3.3
4
+ version: 2.4.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.3.3
4
+ version: 2.4.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.3.3
4
+ version: 2.4.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
@@ -2427,7 +2427,7 @@ paths:
2427
2427
  - webhookId
2428
2428
  properties:
2429
2429
  webhookId:
2430
- type: string
2430
+ $ref: ../../schemas/v2/ids.schema.json#/$defs/subscriptionId
2431
2431
  headers:
2432
2432
  OpenWOP-Version:
2433
2433
  $ref: '#/components/headers/OpenWOPVersion'
@@ -2448,8 +2448,12 @@ paths:
2448
2448
  name: webhookId
2449
2449
  required: true
2450
2450
  schema:
2451
- type: string
2452
- minLength: 1
2451
+ $ref: ../../schemas/v2/ids.schema.json#/$defs/subscriptionId
2452
+ description: 'Tenant-bound `<tenantId>/<opaque>` (`identity.md` §5, RFC 0187 §A.1), one path
2453
+
2454
+ segment: `~`-projected (RFC 0184) or percent-encoded.
2455
+
2456
+ '
2453
2457
  - $ref: '#/components/parameters/OpenWOPVersion'
2454
2458
  responses:
2455
2459
  '204':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/spec-artifacts",
3
- "version": "2.3.3",
3
+ "version": "2.4.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": {
@@ -208,6 +208,37 @@
208
208
  },
209
209
  "maxItems": 250,
210
210
  "description": "Choices for `type: \"select\"` / `\"multiselect\"`. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\". Mirrors `chat-card-pack-manifest.schema.json` `InputField.options`."
211
+ },
212
+ "when": {
213
+ "type": "object",
214
+ "description": "RFC 0177 §E.4 — conditional visibility. The grammar IS the `WorkflowEdge.condition` object of `workflow-definition.schema.json` (operators `expression | equals | notEquals | contains | regex | truthy | falsy`), inlined here for pack-loader validators exactly as the chain manifest inlines it. No second expression language is accepted: a form that hides a field and an edge that skips a node answer the same question, and answering it twice in two dialects is how the two drift.",
215
+ "properties": {
216
+ "type": {
217
+ "type": "string",
218
+ "enum": [
219
+ "expression",
220
+ "equals",
221
+ "notEquals",
222
+ "contains",
223
+ "regex",
224
+ "truthy",
225
+ "falsy"
226
+ ],
227
+ "description": "RFC 0134: `truthy`/`falsy` test the resolved value at `left` for truthiness and take NO `right` operand; `left` is required for all operators except `expression`."
228
+ },
229
+ "left": {
230
+ "type": "string",
231
+ "description": "Left operand path (e.g., 'status', 'output.approved'). Required for every operator except `expression`."
232
+ },
233
+ "right": {
234
+ "description": "Right operand value (any JSON value). Meaningless for `truthy`/`falsy` (RFC 0134)."
235
+ },
236
+ "expression": {
237
+ "type": "string",
238
+ "description": "Used when type='expression'."
239
+ }
240
+ },
241
+ "additionalProperties": false
211
242
  }
212
243
  }
213
244
  },
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://openwop.dev/spec/v2/ids.schema.json",
4
- "title": "OpenWOP v2 identifier grammars (RFC 0170 \u00a7D.1)",
4
+ "title": "OpenWOP v2 identifier grammars (RFC 0170 §D.1)",
5
5
  "description": "One $defs entry per id kind. Every id field in every v2 schema, OpenAPI parameter and response body $refs its kind. `minted` records who mints the id: host (opaque, checkable: `^[A-Za-z0-9._~-]{16,128}$` after any tenant segment), author (a workflow/pack author chooses it; the v1 grammar stands), registry (the pack registry mints it). Tenant-bound kinds (runId, interruptId, subscriptionId, deliveryId, effectId) carry the tenant segment: a host MUST reject an id whose tenant segment is not the caller's.",
6
- "$comment": "PATH PROJECTION (RFC 0184 \u00a7A.1). A tenant-bound id is TWO segments joined by `/`, and a URL path parameter is ONE segment, so the id must be projected. ENCODE: UTF-8 the id, then per byte emit it verbatim if it is in `[A-Za-z0-9._-]`, else `~` + two UPPERCASE hex digits (`/`\u2192`~2F`, `:`\u2192`~3A`, `~`\u2192`~7E`). DECODE: replace every `~HH`; a `~` not followed by two hex digits is `400 validation_error`. The escape marker is `~` and NOT `%` because `~` is RFC 3986 \u00a72.3 UNRESERVED: an intermediary has no license to rewrite it, so `~2F` reaches the origin byte-for-byte. `%2F` does not \u2014 handling it correctly requires an intermediary to distinguish a percent-encoded RESERVED octet (which \u00a76.2.2.2 says it MUST NOT decode) from an unreserved one (which it SHOULD), and deployed front doors demonstrably do not: a reference host lost every bound id at its origin to exactly this. The codec is TOTAL over bytes, so it cannot be invalidated by a later widening of any id grammar. It is injective because it escapes its own marker \u2014 but ONLY over its own output, which is why \u00a7A.2 forbids MINTING a tenant-bound id containing `~`: an unprojected legacy segment carrying a literal `~` is the one ambiguous input, and a host can resolve those from its OWN store because they are its own ids.APPLY EXACTLY ONCE: the codec is NOT idempotent \u2014 `a~3Ab` encodes to `a~7E3Ab`, which is required for injectivity but means a second application silently corrupts, and nothing marks an encoded id as already encoded. Both reporting hosts found they compose projections on one read path already (one of them caught itself writing two `payload:` keys where the second silently won), so the invariant is stated on the VALUE, not the call site: project where an id LEAVES the host, and never re-encode what was read back from its own output. SCOPE: only the TENANT-BOUND kinds. `nodeId` is author-chosen, carries no tenant segment and already admits `:` by design \u2014 projecting it would change ids that are legal today, which is the cost base64url was rejected for. `Idempotency-Key` (`idempotency.md` \u00a7Layer 1, `^[A-Za-z0-9._~-]{22,128}$`) is caller-supplied and tilde-LEGAL; it is not an id kind, \u00a75 does not bind it, and it is NOT projected \u2014 stated because \"escape `~` in identifiers\" is the sentence a later reader would apply to it. LENGTH: the `{16,128}` bounds govern the ID, never the projected segment. A bound id is already up to 257 characters before any byte escapes, so a validator that checks the projected segment against an id pattern is checking the wrong string.",
6
+ "$comment": "PATH PROJECTION (RFC 0184 §A.1). A tenant-bound id is TWO segments joined by `/`, and a URL path parameter is ONE segment, so the id must be projected. ENCODE: UTF-8 the id, then per byte emit it verbatim if it is in `[A-Za-z0-9._-]`, else `~` + two UPPERCASE hex digits (`/`→`~2F`, `:`→`~3A`, `~`→`~7E`). DECODE: replace every `~HH`; a `~` not followed by two hex digits is `400 validation_error`. The escape marker is `~` and NOT `%` because `~` is RFC 3986 §2.3 UNRESERVED: an intermediary has no license to rewrite it, so `~2F` reaches the origin byte-for-byte. `%2F` does not — handling it correctly requires an intermediary to distinguish a percent-encoded RESERVED octet (which §6.2.2.2 says it MUST NOT decode) from an unreserved one (which it SHOULD), and deployed front doors demonstrably do not: a reference host lost every bound id at its origin to exactly this. The codec is TOTAL over bytes, so it cannot be invalidated by a later widening of any id grammar. It is injective because it escapes its own marker — but ONLY over its own output, which is why §A.2 forbids MINTING a tenant-bound id containing `~`: an unprojected legacy segment carrying a literal `~` is the one ambiguous input, and a host can resolve those from its OWN store because they are its own ids.APPLY EXACTLY ONCE: the codec is NOT idempotent — `a~3Ab` encodes to `a~7E3Ab`, which is required for injectivity but means a second application silently corrupts, and nothing marks an encoded id as already encoded. Both reporting hosts found they compose projections on one read path already (one of them caught itself writing two `payload:` keys where the second silently won), so the invariant is stated on the VALUE, not the call site: project where an id LEAVES the host, and never re-encode what was read back from its own output. SCOPE: only the TENANT-BOUND kinds. `nodeId` is author-chosen, carries no tenant segment and already admits `:` by design — projecting it would change ids that are legal today, which is the cost base64url was rejected for. `Idempotency-Key` (`idempotency.md` §Layer 1, `^[A-Za-z0-9._~-]{22,128}$`) is caller-supplied and tilde-LEGAL; it is not an id kind, §5 does not bind it, and it is NOT projected — stated because \"escape `~` in identifiers\" is the sentence a later reader would apply to it. LENGTH: the `{16,128}` bounds govern the ID, never the projected segment. A bound id is already up to 257 characters before any byte escapes, so a validator that checks the projected segment against an id pattern is checking the wrong string.",
7
7
  "type": "object",
8
8
  "additionalProperties": false,
9
9
  "$defs": {
10
10
  "opaque": {
11
11
  "type": "string",
12
12
  "pattern": "^[A-Za-z0-9._~-]{16,128}$",
13
- "description": "Host-minted opaque token: no `@`, no whitespace, no `/`; 16\u2013128 characters."
13
+ "description": "Host-minted opaque token: no `@`, no whitespace, no `/`; 16–128 characters."
14
14
  },
15
15
  "tenantId": {
16
16
  "type": "string",
17
17
  "pattern": "^(anon:)?[A-Za-z0-9._~-]{1,128}$",
18
18
  "x-openwop-minted": "host",
19
- "description": "A tenant identifier. The optional `anon:` prefix is the ONLY colon admitted. Its ORIGINAL rationale here cited RFC 0132, and that citation was WRONG: RFC 0132 puts `anon:` on the **principal** and \u00a7C.1 requires the host to resolve a real `tenant` (the surface owner) \u2014 `{tenant: \"acme\", principal: \"anon:sess-3f9c\"}`. The prefix is kept because a REPORTING HOST was observed minting `tenantId: \"anon:<sid>\"` (`conformance/src/scenarios/test-seam-unauthenticated.test.ts`), and that grammar shipped in v2.0.0; removing it is a major-version change, not an erratum. Whether it belongs on a tenant at all is deferred to v3 (RFC 0184 \u00a7A.3). `:` is a legal path character (RFC 3986 pchar), but the claim that it \"stays safe inside the `<tenantId>/<opaque>` run-id form\" was FALSE ON ARRIVAL: this pattern admitted `anon:`, and all five tenant-bound kinds rejected it, so every runId an anon-tenant host minted was schema-invalid. RFC 0184 \u00a7A.3 widened those five to match. On the wire the question is moot \u2014 the \u00a7A.1 projection escapes `:` to `~3A` like any other non-passthrough byte. The alternative \u2014 renaming anonymous tenants at the cut \u2014 was rejected: it is a write to historical identity, which is the one thing the v2 migration does not do."
19
+ "description": "A tenant identifier. The optional `anon:` prefix is the ONLY colon admitted. Its ORIGINAL rationale here cited RFC 0132, and that citation was WRONG: RFC 0132 puts `anon:` on the **principal** and §C.1 requires the host to resolve a real `tenant` (the surface owner) — `{tenant: \"acme\", principal: \"anon:sess-3f9c\"}`. The prefix is kept because a REPORTING HOST was observed minting `tenantId: \"anon:<sid>\"` (`conformance/src/scenarios/test-seam-unauthenticated.test.ts`), and that grammar shipped in v2.0.0; removing it is a major-version change, not an erratum. Whether it belongs on a tenant at all is deferred to v3 (RFC 0184 §A.3). `:` is a legal path character (RFC 3986 pchar), but the claim that it \"stays safe inside the `<tenantId>/<opaque>` run-id form\" was FALSE ON ARRIVAL: this pattern admitted `anon:`, and all five tenant-bound kinds rejected it, so every runId an anon-tenant host minted was schema-invalid. RFC 0184 §A.3 widened those five to match. On the wire the question is moot — the §A.1 projection escapes `:` to `~3A` like any other non-passthrough byte. The alternative — renaming anonymous tenants at the cut — was rejected: it is a write to historical identity, which is the one thing the v2 migration does not do."
20
20
  },
21
21
  "workspaceId": {
22
22
  "type": "string",
@@ -26,7 +26,7 @@
26
26
  "subjectId": {
27
27
  "type": "string",
28
28
  "pattern": "^[^\\s/]{1,256}$",
29
- "description": "Issuer-scoped, stable, opaque (RFC 0170 \u00a7A); the issuer's grammar, never PII.",
29
+ "description": "Issuer-scoped, stable, opaque (RFC 0170 §A); the issuer's grammar, never PII.",
30
30
  "x-openwop-minted": "host"
31
31
  },
32
32
  "runId": {
@@ -121,8 +121,8 @@
121
121
  },
122
122
  "typeId": {
123
123
  "type": "string",
124
- "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$",
125
- "description": "A node type id (`core.ai.callPrompt`); the RFC 0107 grammar. Underscore is admitted because node-pack-manifest.schema.json's `name` pattern admits it and a pack's node type ids are DERIVED from its name \u2014 a pack legally named `vendor.acme.my_tools` must be able to declare `vendor.acme.my_tools.echo`. Without the underscore this kind rejected type ids that a legal pack name generates, which is a constraint that cannot express a legitimate value. maxLength is present because this was the ONLY kind whose pattern left length unbounded \u2014 every other $def bounds it inside the pattern ({1,128}, {16,128}). 256 is taken from the bound node-pack-manifest already carried locally, so this relocates it rather than inventing one, and binding those properties to this kind no longer drops it.",
124
+ "pattern": "^[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+(@[0-9]+\\.[0-9]+\\.[0-9]+)?$",
125
+ "description": "A node type id (`core.ai.callPrompt`); the RFC 0107 grammar. Underscore is admitted because node-pack-manifest.schema.json's `name` pattern admits it and a pack's node type ids are DERIVED from its name — a pack legally named `vendor.acme.my_tools` must be able to declare `vendor.acme.my_tools.echo`. Without the underscore this kind rejected type ids that a legal pack name generates, which is a constraint that cannot express a legitimate value. maxLength is present because this was the ONLY kind whose pattern left length unbounded — every other $def bounds it inside the pattern ({1,128}, {16,128}). 256 is taken from the bound node-pack-manifest already carried locally, so this relocates it rather than inventing one, and binding those properties to this kind no longer drops it. RFC 0177 §E.1: a document that REFERENCES a type MAY carry an exact version pin as the suffix `@<major>.<minor>.<patch>` (`core.ai.callPrompt@1.0.0`) — a chain fragment node MUST carry one, and a host refuses to register a chain whose reference is unpinned or carries a range, which this pattern cannot express. A document that DEFINES a type (a node-pack manifest's own `typeId`) MUST NOT carry the suffix: the definition is the version.",
126
126
  "x-openwop-minted": "author",
127
127
  "maxLength": 256
128
128
  }
@@ -195,7 +195,7 @@
195
195
  "description": "Optional ID of the event that caused this one (e.g., node.completed caused by approval.received). Lets projections build causal chains without inferring from timing."
196
196
  }
197
197
  },
198
- "$comment": "RFC 0171 §A / `events.md` §\"The envelope\": in v2 RunEventDoc is CLOSED (`additionalProperties: false`). This reverses the v1 rule, which left the envelope open so v1.x hosts could add optional fields additively. The v2 envelope carries host-specific data in the registered vendor branch, not at the root. Do not restore the v1 sentence: a host that follows it emits root-level extension fields and fails `v2-event-type-closed`, and the schema keyword is the contract while a comment is only a claim about it.",
198
+ "$comment": "RFC 0171 §A / `events.md` §\"The envelope\": in v2 RunEventDoc is CLOSED (`additionalProperties: false`). This reverses the v1 rule, which left the envelope open so v1.x hosts could add optional fields additively. The v2 envelope carries host-specific data in the registered vendor branch, not at the root. Do not restore the v1 sentence: a host that follows it emits root-level extension fields and fails `v2-event-type-closed`, and the schema keyword is the contract while a comment is only a claim about it. persistence.md §The reader rule: the translation seat is a claims-check. `v2-v1-events-translated` drives poll, SSE and a fork, and what those three legs witness is that THOSE THREE readers translate — not that the seat is at the storage boundary. Three wrappers pass them exactly as one correctly seated adapter does. A universal is not discharged by three examples: the scenario catches a reader that was missed, not an adapter that was misplaced.",
199
199
  "additionalProperties": false,
200
200
  "$defs": {}
201
201
  }
@@ -64,9 +64,8 @@
64
64
  }
65
65
  },
66
66
  "webhookId": {
67
- "type": "string",
68
- "minLength": 1,
69
- "description": "MAY — for `source: \"webhook\"`, the existing webhooks.md register key (unchanged; the state machine layers over it)."
67
+ "$ref": "ids.schema.json#/$defs/subscriptionId",
68
+ "description": "MAY — for `source: \"webhook\"`, the existing webhooks.md register key. Tenant-bound since RFC 0187 §A.1 (the state machine layers over it unchanged)."
70
69
  },
71
70
  "secretFingerprint": {
72
71
  "type": "string",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://openwop.dev/spec/v2/webhook-delivery.schema.json",
4
- "title": "Webhook delivery envelope (webhooks.md \u00a7Delivery)",
5
- "description": "The body of an outbound webhook delivery. Written 2026-09-04 because it did not exist: the envelope was specified by one sentence in webhooks.md \u00a7Delivery ('the body is `{ runId, workspaceId, event }` where `event` is the verbatim run event') and no artifact bound it, while the NESTED event.runId was bound all along through run-event.schema.json. Two production hosts arrived at that asymmetry independently \u2014 one asking what major an outbound payload speaks, the other answering from the $ref graph \u2014 and both concluded the gap was a missing artifact rather than a missing paragraph. An emitter that projects correctly could be asserted but not checked, which is the wrong way round.",
4
+ "title": "Webhook delivery envelope (webhooks.md §Delivery)",
5
+ "description": "The body of an outbound webhook delivery. Written 2026-09-04 because it did not exist: the envelope was specified by one sentence in webhooks.md §Delivery ('the body is `{ runId, workspaceId, event }` where `event` is the verbatim run event') and no artifact bound it, while the NESTED event.runId was bound all along through run-event.schema.json. Two production hosts arrived at that asymmetry independently — one asking what major an outbound payload speaks, the other answering from the $ref graph — and both concluded the gap was a missing artifact rather than a missing paragraph. An emitter that projects correctly could be asserted but not checked, which is the wrong way round.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [
@@ -12,15 +12,15 @@
12
12
  "properties": {
13
13
  "runId": {
14
14
  "$ref": "ids.schema.json#/$defs/runId",
15
- "description": "The run this delivery is about, tenant-bound per identity.md \u00a75. An outbound emission is not a response to a versioned request, so nothing about the request cycle supplies the form \u2014 the grammar does, and it is the same grammar everywhere a v2 runId is rendered. A host that projects on responses and not on emissions hands the subscriber an id the client never saw: the correlation filter matches nothing, with no error, no 4xx and no log line. A tier-1 host hit exactly that, and the silence is why this field is bound here rather than left to the prose."
15
+ "description": "The run this delivery is about, tenant-bound per identity.md §5. An outbound emission is not a response to a versioned request, so nothing about the request cycle supplies the form — the grammar does, and it is the same grammar everywhere a v2 runId is rendered. A host that projects on responses and not on emissions hands the subscriber an id the client never saw: the correlation filter matches nothing, with no error, no 4xx and no log line. A tier-1 host hit exactly that, and the silence is why this field is bound here rather than left to the prose. A host that projects on responses and not on emissions hands the subscriber an identifier the client has never seen, and the failure is silent: the correlation matches nothing, with no error, no 4xx and no log line. Until 2026-09-04 the nested `event.runId` was bound by run-event.schema.json while the envelope's own was carried by one paragraph of prose, which is how a real host shipped the split (webhooks.md §Delivery)."
16
16
  },
17
17
  "workspaceId": {
18
18
  "$ref": "ids.schema.json#/$defs/workspaceId",
19
- "description": "The workspace the run belongs to. OPTIONAL, and present exactly when RunSnapshot.owner.workspace is (identity.md \u00a71: owner is { tenant, workspace?, subject }). This field was REQUIRED for the first six hours of the schema's life, which made the envelope tighter than the identity model it renders: a run in a single-workspace tenant has no workspace, and the only way a host could satisfy the envelope was to put its tenant id in this field. A tier-1 host proposed exactly that \u2014 `owner.workspace ?? tenantId` \u2014 and asked for a veto. This is the veto. A tenant id in a workspace field is two facts wearing one name, and every consumer downstream would have to know which host lied."
19
+ "description": "The workspace the run belongs to. OPTIONAL, and present exactly when RunSnapshot.owner.workspace is (identity.md §1: owner is { tenant, workspace?, subject }). This field was REQUIRED for the first six hours of the schema's life, which made the envelope tighter than the identity model it renders: a run in a single-workspace tenant has no workspace, and the only way a host could satisfy the envelope was to put its tenant id in this field. A tier-1 host proposed exactly that — `owner.workspace ?? tenantId` — and asked for a veto. This is the veto. A tenant id in a workspace field is two facts wearing one name, and every consumer downstream would have to know which host lied."
20
20
  },
21
21
  "event": {
22
22
  "$ref": "run-event.schema.json",
23
- "description": "The verbatim run event (events.md). 'Verbatim' is load-bearing: the envelope is one of the three renderings generated from a single payload definition (RFC 0171 \u00a7A.4), so this is the event as persisted, not a re-serialization. Its own runId is bound by run-event.schema.json to the same $def as the envelope's, which is what made the envelope's omission survivable for as long as it did \u2014 and invisible for just as long."
23
+ "description": "The verbatim run event (events.md). 'Verbatim' is load-bearing: the envelope is one of the three renderings generated from a single payload definition (RFC 0171 §A.4), so this is the event as persisted, not a re-serialization. Its own runId is bound by run-event.schema.json to the same $def as the envelope's, which is what made the envelope's omission survivable for as long as it did — and invisible for just as long."
24
24
  }
25
25
  }
26
26
  }