@openwop/spec-artifacts 2.44.2 → 2.44.4

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.44.2",
5
- "corpusTag": "v2.44.2",
4
+ "version": "2.44.4",
5
+ "corpusTag": "v2.44.4",
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": "69464bc0e1e71ef3b543a73d4fa4f67202343d2603c80af8033f6c3619ef1b30",
11
11
  "api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
12
- "api/seams-v2.yaml": "f24127f3cd544f1c5a942859ffc492b438d37b1b7d7a660c631fb87f70cd24f6",
13
- "api/v2/asyncapi.yaml": "3283ff1bbe962dc75e6d66d2b755d4eb7d53770ce8511f2d671b923d6ca0e51a",
14
- "api/v2/openapi.yaml": "4a455ba22c81718e2842adce60e5d3c5970e6f8a55b301d9154ccc8060f6cf91",
12
+ "api/seams-v2.yaml": "0c5a5ce153d5ac87b89f331f1e13ac25389937f966adbd3207bdfcc17e7ef8f5",
13
+ "api/v2/asyncapi.yaml": "d195115d983cadc6ae08d617de1a1c2f09073b22b0e5309ddd9119319164c566",
14
+ "api/v2/openapi.yaml": "d928ce4c62122954da1fecd5a79baff89957e65d4cc54606868bed92127b70c6",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "75d5049dea8bd873ff0e7546f1c60c8d36c219bec7084264360be54a8be30ae1",
@@ -112,7 +112,7 @@
112
112
  "schemas/v2/ai-envelope.schema.json": "0dc7dfbf032a37239ffd81fc2d67f999a40782ff5074866a56e414164cdee809",
113
113
  "schemas/v2/annotation-create.schema.json": "ec32c22a243b343eeb6956a23be2d76ba5b50c8018ec3ec9d6efa5a1d9b0c792",
114
114
  "schemas/v2/annotation.schema.json": "eb4813cdaa8e325412cfcaeeee5c8a28f3751c946dec64e546c7ba0ad3aad8d4",
115
- "schemas/v2/artifact-type-pack-manifest.schema.json": "c8820351a2ab93855bd654ad3d8a9788f97975d09b3a7a0418e374ed6114595d",
115
+ "schemas/v2/artifact-type-pack-manifest.schema.json": "acbbf14d32da4e0cb81254bbd6cc48fc10083890572044ddef71c59a0f65c185",
116
116
  "schemas/v2/artifact.schema.json": "85b9dc284d39b99d2a66fa8cbf47f2dd3d8526d3bd6cc411ad315b372de38975",
117
117
  "schemas/v2/audit-verify-result.schema.json": "14af8e9283510f0a40e48a2059c929ee44e0fc9fa3cc66a95bfbe90b17c48297",
118
118
  "schemas/v2/budget-policy.schema.json": "c7449daeb6e1d95e7a047b8c2814d3d54748697c27046972834874867d9b5f4c",
@@ -193,61 +193,63 @@
193
193
  "schemas/v2/webhook-delivery.schema.json": "4e8ab3b722ad1731adf0548c1217f0de62da40de14e8abf77533aee4ace4c079",
194
194
  "schemas/v2/webhook-verification.schema.json": "76e4e0d81143ffd2649bc7adba2aa34f2525e2c4e9f0300a425d908b3163196b",
195
195
  "schemas/v2/workflow-chain-pack-manifest.schema.json": "0816c6c59a91452d6fa1931394b766780eaf90949c9f7cd0ced522dadd32ff81",
196
- "schemas/v2/workflow-definition.schema.json": "b9043e3413fc01d939e7b2892cc0fe28bdfd77d5bacc561b6ca4ae20197b985b",
196
+ "schemas/v2/workflow-definition.schema.json": "3f031c0cb1644ac21f203945a0860e04dcea4bd1ab722f280bdcdc788edd0a22",
197
197
  "schemas/v2/workload-identity.schema.json": "1f589debfac6d70e0908da511550ec69a27b4bcc8314551cd843b6d923605efc",
198
198
  "schemas/v2/workspace-file-create.schema.json": "b6b5260857318c3b67de0231ed15e3a746f525880a763e7b36a7854178dd10d0",
199
199
  "schemas/v2/workspace-file.schema.json": "d2ed39e8c229dde33b56905c8df6f8b2ff056c97e1c5f615e3124baa54a6254f",
200
200
  "schemas/workflow-chain-pack-manifest.schema.json": "c027571913c44d8d9678750c72701a710a02fa0df55e86849da03e13e95c333a",
201
- "schemas/workflow-definition.schema.json": "28b050ffe22121796c9d4a5a8c7e57c901bb283bd08d3fd3ff2ea25a898108c1",
201
+ "schemas/workflow-definition.schema.json": "fbab3787707fc0e00ecf2adea8de8aba582e6057af9cde893b1b0eb969adea83",
202
202
  "schemas/workload-identity.schema.json": "64ed93e12cc9f0657e56ff9b8f045e5d68d397df5276d103c07f42c7f34f0579",
203
203
  "schemas/workspace-file-create.schema.json": "70a23b92c2958c0165d7d29aea9020a045dc7816af82c80c5f50d0aac19c4856",
204
204
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
205
205
  "spec/v1/alias-detectors.json": "29f21e0fb2c7a232a92a5c19b4cba3a86bc3b5e16f06780452f0421c66c6ec38",
206
206
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
207
- "spec/v1/core-standard-manifest.json": "3d7fd99cd02153094723c2bf383d757c282e653526aa3b199d9bdb4b9cfd7c80",
207
+ "spec/v1/core-standard-manifest.json": "8f01c8ce3e66e4ff879e28da7f0de8bb8e2f3f85e5855cae17f0563c902328e5",
208
208
  "spec/v1/deprecations.json": "46df807fb4adf0aae24671c20f69975cf3496e3bc3a521cb7e6ea556bdce563c",
209
209
  "spec/v1/deprecations.schema.json": "3e393c405d2a41b467d8c5e3c468549078df1ce6a6d2588fc488097b95d9b55b",
210
210
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
211
211
  "spec/v1/event-codemap.schema.json": "d05933b2e88103aff51a2f774df97b9bda065e0fc88dbd9b114cc47a32189174",
212
212
  "spec/v1/extensions.json": "79a60754aa16cbdbdb604f8e5c00038af535a1690a4d07bd5ff7c38f0256a7bc",
213
- "spec/v1/gaps.json": "07b0f5a206a015336307dd343b75adec647f06a9bae59ee08dbbfac851c503d5",
213
+ "spec/v1/gaps.json": "11c35393ad666899fe8a668c45fa69f79d20361ab57e84949dce3bc2f528d5c3",
214
214
  "spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
215
- "spec/v1/migrations.json": "2efcd9064b2bc65a84a3b3d281aa86a91efd002690c1f4f14e8335c4a18194d1",
215
+ "spec/v1/migrations.json": "ca57b7ce335a681aaa78573ce229e9c3d7d75859f03e087ae93bbfc889359127",
216
216
  "spec/v1/migrations.schema.json": "886779aa6c22e646db097f5df210adb018a4dd14a7b815465a18c8a7056c8f72",
217
217
  "spec/v1/operation-path-manifest.json": "fada0342815fb129c1ae61f1829bd6e34417717408ce86fcc54280f373c19e74",
218
218
  "spec/v1/spec-gaps.json": "ea9612af55bea9dae3e82223d4f714243f8f590b0193f1188257b13491a38afc",
219
- "spec/v2/README.md": "377639de1dad1ed71aba6dae8d34fdb6ee954fb23106e89454fe8d29cdde6349",
219
+ "spec/v2/README.md": "ddea90d7cf14aefffe1a43eeeecd4222dadad1d1e5ac64dceb073990eb93d9ef",
220
+ "spec/v2/core/artifact-type-packs.md": "e143bfd6f98d4867855bb57090a6b854e98d4b0a6202b9b3734cb45366f99854",
220
221
  "spec/v2/core/capabilities.md": "ad728e8a761153b55d036ece55043ff62d0982121e2e629e5e7cdf560fca3c03",
221
222
  "spec/v2/core/conformance.md": "0cfceb926eed87055550a5c23e640210c795fc8cf9dd1b2544db0e2b3842c564",
222
223
  "spec/v2/core/connection-packs.md": "1ee129d792c537bfe82393ccb92555d8e6ddc342b1aa781a13f101b27ec38171",
223
224
  "spec/v2/core/conversation.md": "354fa57c73d11062e523a44aa75a6353c5c81aefaf306d30c42416a228c82c86",
224
225
  "spec/v2/core/errors.md": "6d5a67389de84556f81e2558a30d83959c9283c8c5481ce7c759021e486d84fd",
225
- "spec/v2/core/events.md": "604abb6f9e2259a04103e1cb76d728712c3701c0d84dd915d4dc2949c912ee5e",
226
+ "spec/v2/core/events.md": "8a2767691f604b2adf76399edeeaccfc151c697fc9717dc17cf7dd57372a8c22",
227
+ "spec/v2/core/execution.md": "299c4d548e16e5a0809957a47cbd34b56a38de82b8c9b3a5d036b2c7abca09c6",
226
228
  "spec/v2/core/form-content-packs.md": "02931227899676fd4581a27017be2a6c4953904717be9b81c29d12f87ab3917d",
227
229
  "spec/v2/core/headers.md": "5cb1624fa63acc81992b6a6d842ec392cf7271aaf2f65d1f83c8c4fa286e6730",
228
- "spec/v2/core/host-services.md": "8b920bf2e9335ab04452068429b0c37d6eb8872b380a4d53368f2600d4afa241",
230
+ "spec/v2/core/host-services.md": "aa8b269e6348bdcb797da1a23c82f9df95c2133a7b947253799f6eaf88ccd3f1",
229
231
  "spec/v2/core/i18n.md": "2d5a67bd3b9b956d1144acab2fbc3646cdb50b3621f97d772087eaa953798286",
230
232
  "spec/v2/core/idempotency.md": "2084d756789c1faf5121593fb39e67ca36a4c227178e175004742e403178ea49",
231
- "spec/v2/core/identity.md": "2dceb1c2697015e4a4fa8a9b28f4fbd25fa44a76ca5a919c752e2a8163c819db",
233
+ "spec/v2/core/identity.md": "582eddbf2e1bad41911e886bd08524683837045404f7b8f6bceccf61792b2765",
232
234
  "spec/v2/core/interop.md": "e72e25dff864c83b2980d7366b34054cffa072af0225821199f260f6228d260e",
233
- "spec/v2/core/interrupt.md": "4c825634acac72900ebd3c5ac5941f55648fa33d2df92913ef16371dcb700a34",
235
+ "spec/v2/core/interrupt.md": "c1e13179e792bf8099b2d1c7891542646bb1d4cdee1757590f190833cae6047c",
234
236
  "spec/v2/core/node-pack-runtimes.md": "e1088cb69b8c3c67256c494063328916c2980ab1aa97a7063de25bab82fdb1e5",
235
237
  "spec/v2/core/oauth.md": "c96483a44b62978c596945fbb7d7c863cf6056cd980fdb4cf4e97555e3e10b72",
236
- "spec/v2/core/overview.md": "c8c3bedb8e02dd8ce244b8a7a75d23af1c30dc92a343af912489424a89674d70",
237
- "spec/v2/core/packs.md": "5929e708bd4e79f6e1beea570af583c80f3b63bb21dec78a5df03c235e73364a",
238
+ "spec/v2/core/overview.md": "d7000fbcd2f59280870fc592f5d5ea28a5195b9eb209029f09c5de59e0f2bf9c",
239
+ "spec/v2/core/packs.md": "935fc2f633c68fa98ad6c9cdb083dd556e955b1a15eff32f4773d13329a57238",
238
240
  "spec/v2/core/persistence.md": "711874f74cb08b03cd118d683056db10a063517762fcea73ec70feb5d983e6a4",
239
241
  "spec/v2/core/portability.md": "87c4327f674f714fda6217fd79b99d2ba219ad47dc02f9751bb56c200fb2c17a",
240
- "spec/v2/core/replay.md": "4d379494057746c6883f6047972e93e621863b998ed291b9a691d3aa57c1ff43",
241
- "spec/v2/core/runs.md": "55e21292ae4b41d0d104199a6c2634ecb3f787c4a671f9ebc37084be38ceef03",
242
+ "spec/v2/core/replay.md": "f406d71fb690b2e71f4b86ff799a49e6f1a0662c98fc59bcfe517d100eb6117c",
243
+ "spec/v2/core/runs.md": "8a1d71fb9305fd0df31150bfbbd892f96b8aab553400a36196212f7d0a24906d",
242
244
  "spec/v2/core/security-defaults.md": "153884da7a2d54c30c81b5e649cfdef31e151b3a2a19dee1bc5a16c35d60a3aa",
243
245
  "spec/v2/core/storage.md": "598ad4f3775c297c698a20daf72a7d15a6836c1231ddbca5961865c704f765b5",
244
246
  "spec/v2/core/tool-catalog.md": "d16a9004418719c48301804aefa4d7ab6f41112a4ed83727f552aa1b92b418b0",
245
247
  "spec/v2/core/versioning.md": "e3b3ab6d76e51035039a32173e9b412628a52c8fe7b16687ff58a2d0d983faa0",
246
- "spec/v2/core/webhooks.md": "d2d33c6be777f217ade3e15dd369849e5c6ce67e1a4417216f0aa6ec5bdecc56",
248
+ "spec/v2/core/webhooks.md": "3f8730e0d15a5e4244e302adb910a0b6f745fbfa8e80920c14118117811ba881",
247
249
  "spec/v2/core/workflow-chain-packs.md": "fdce7a8477e269950a2bac05ee6eddbd66eb0b670b464d00054f7196ec05d29c",
248
250
  "spec/v2/corrections.json": "59f647f4d22477f6c2b06dcf913b682dde5d51dd5e607a5d0cf648ab60864d6e",
249
251
  "spec/v2/corrections.schema.json": "46bbffb954d13bd9995aebc912ceeb2544f7064331abf25fd6ab85c81a5cec94",
250
- "spec/v2/declaration.json": "56c85c6d49f93d08d3bd48ccf1c049191cfbc4d4c22a1cd5202c1b6252759aca",
252
+ "spec/v2/declaration.json": "edace8c4ec7e32aba44828f459e2ae8933dc88ec8129f16549bca6279e3ca24c",
251
253
  "spec/v2/declaration.schema.json": "ef951633e4070899f64828f5cf1b5f4870270a0360f81dbb49b5b4d6cd407550",
252
254
  "spec/v2/errors.json": "fa650cbbdf25a140fdaf82ec5269f95b4585ac4bdde1fa6b0b3ffe48a3f7943c",
253
255
  "spec/v2/errors.schema.json": "47404ad53e6147cf9017b813483712466573e419fb33e6c4b6c12d3e7deba1bc",
@@ -265,11 +267,11 @@
265
267
  "spec/v2/ext/kanban/README.md": "bfc386dc0f874a4afa1e3ec6a2f99084b547dcce9bd363da3b8ebd8786b9c184",
266
268
  "spec/v2/ext/knowledge/README.md": "cbe1f945a757791dedac0fd542a68c86c5b457778b831d58d9ae44a2baa270f2",
267
269
  "spec/v2/ext/launchStudio/README.md": "a941ef1d2401438a412eaea48d2d6ca807a032b44ea08719fea33120daf088a0",
268
- "spec/v2/ext/messaging/README.md": "949f350e35294f52ad490e42699f8c560cd154549516fbaa1805f06312b7f342",
270
+ "spec/v2/ext/messaging/README.md": "ee2d19fb6f6c2de11d889e966a41e6d1ff34272771689a81d7de039105a5be03",
269
271
  "spec/v2/ext/portability/README.md": "c59423ee446638b748a911b9e97e803c4786157be6120f656f0a060586bc7b82",
270
272
  "spec/v2/ext/provider-idempotency/README.md": "9d1bccef0ec16a19a3370ae79c2f5a1726ce0d1d25a51352907f288a2ccb15d7",
271
273
  "spec/v2/ext/provider-idempotency/registry.json": "5b5fecad604fb4ab38da39f5abe697a4e57b05406c398f8afeb377331b2bd965",
272
- "spec/v2/ext/restTransport/README.md": "c875fd7ae4818a5d5e93ab9b21e569de8700bb07c4dafacd60a46a46e4022ddb",
274
+ "spec/v2/ext/restTransport/README.md": "bd7207683b2fbcead78bdb7d474fa723e08adad500185ea10804fd4e99541c0c",
273
275
  "spec/v2/ext/sandbox-runtime-notes/README.md": "0d1290fb1e20b2e35c0b15051541ab6546e4e2a6f693b4f912cb3f7d6a65e92c",
274
276
  "spec/v2/ext/webResearch/README.md": "b675e6f6646128d781b661f754c2393eed86e5935d16c3a22df582a5ce025b9b",
275
277
  "spec/v2/facets/a2a.schema.json": "b68bf5e29e455e46c2ad7cfcccf5963730ec2310ff9db81884550d8df30fd6ef",
@@ -299,9 +301,9 @@
299
301
  "spec/v2/path-manifest.json": "17298a245c5da9a70aa7ab0b7f2db4277e06209d6fcdd7187a8b4cea179c08f3",
300
302
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
301
303
  "spec/v2/profiles.json": "180beb9ef2d161766fa23b2987e7e829851e3d316273147cf6a4a3f324befd6b",
302
- "spec/v2/release.json": "28b407019929da55701a718110d440f08899646af0b74d62f6adc5542c9c1c91",
304
+ "spec/v2/release.json": "8b868146a0b8fef709478ed80a75a204c980d0c761463e0602c921c6b25fd0d8",
303
305
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
304
- "spec/v2/surface-baseline.json": "d0540276e74001f5058dd81909100ea6ee3c1925c6ac02918418f5ec941d0661"
306
+ "spec/v2/surface-baseline.json": "d074465ed4ee594016bfb842fc3161d278394e84740133daf4fd93d1b3b0c4d8"
305
307
  },
306
- "corpusCommit": "c486eafcfa16908a7b57c98b33cfd66fdf8e599d"
308
+ "corpusCommit": "95fbb4c9963f9da47eb0e870bf402bad3f4db29d"
307
309
  }
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.44.2
4
+ version: 2.44.4
5
5
  description: 'The OpenWOP conformance seams profile (`openwop-conformance-seams-v2`): test-only operations in their own
6
6
  path space, `/conformance/seams/…`. The profile is versioned and validated against the canonical v2 schemas with no tolerance
7
7
  path. It is not a capability: a host advertises the profile, never a `testSeams` flag.
@@ -1,7 +1,7 @@
1
1
  asyncapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 event streams
4
- version: 2.44.2
4
+ version: 2.44.4
5
5
  description: 'OpenWOP v2 event streams over SSE. The run-events channel''s address is the OpenAPI path key, and the server
6
6
  pathname is empty (bare origin). `streamMode` is a stream mode from the closed set, or a comma-separated combination of
7
7
  them; `values` never combines. `hostEvents` has a default address, `/host/events`; a host MAY declare another under `heartbeat.deliveryChannel`.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 API
4
- version: 2.44.2
4
+ version: 2.44.4
5
5
  summary: REST surface for declaring, executing, suspending, resuming, and observing multi-step workflows.
6
6
  description: 'The OpenWOP v2 REST API. Paths are unversioned and served at the bare origin; a client selects a version with
7
7
  the `OpenWOP-Version` header from the host''s `protocolVersions[]`. Conformance seams and test-mode operations are not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/spec-artifacts",
3
- "version": "2.44.2",
3
+ "version": "2.44.4",
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": {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://openwop.dev/spec/v2/artifact-type-pack-manifest.schema.json",
4
4
  "title": "ArtifactTypePackManifest",
5
- "description": "Manifest for a published OpenWOP artifact-type pack \u2014 `pack.json` at the pack root with `kind: \"artifact-type\"`. Peer to `node-pack-manifest.schema.json` (RFC 0003), `workflow-chain-pack-manifest.schema.json` (RFC 0013), and `prompt-pack-manifest.schema.json` (RFC 0028); disjoint from all three via the `kind` discriminator. See `spec/v1/artifact-type-packs.md` for the canonical contract and RFC 0071 for the rationale.\n\nArtifact-type packs distribute typed artifact definitions \u2014 the JSON Schema, rendering hint, lifecycle, and export-format hints for the rich outputs workflow nodes produce \u2014 via the same signed-tarball + Ed25519 + SRI pipeline that already serves node, workflow-chain, and prompt packs. When a host installs an artifact-type pack and advertises `host.artifactTypes: { supported: true }`, it validates produced artifacts of the declared `artifactTypeId`s against their `schemaRef` before emitting `artifact.created`.",
5
+ "description": "Manifest for a published OpenWOP artifact-type pack \u2014 `pack.json` at the pack root with `kind: \"artifact-type\"`. Peer to `node-pack-manifest.schema.json` (RFC 0003), `workflow-chain-pack-manifest.schema.json` (RFC 0013), and `prompt-pack-manifest.schema.json` (RFC 0028); disjoint from all three via the `kind` discriminator. See `spec/v2/core/artifact-type-packs.md` for the host contract and RFC 0071 for the rationale.\n\nArtifact-type packs distribute typed artifact definitions \u2014 the JSON Schema, rendering hint, lifecycle, and export-format hints for the rich outputs workflow nodes produce \u2014 via the same signed-tarball + Ed25519 + SRI pipeline that already serves node, workflow-chain, and prompt packs. When a host installs an artifact-type pack and advertises `host.artifactTypes: { supported: true }`, it validates produced artifacts of the declared `artifactTypeId`s against their `schemaRef` before emitting `artifact.created`.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "name",
@@ -82,7 +82,7 @@
82
82
  "additionalProperties": {
83
83
  "type": "string"
84
84
  },
85
- "description": "Engine-supplied capabilities the pack consumes (e.g., `{ \"host.artifactTypes\": \"supported\" }`). Resolved against the host's advertised capabilities at register time."
85
+ "description": "Engine-supplied capabilities the pack consumes, keyed by family (e.g., `{ \"artifactTypes\": \"required\" }`; spec/v2/core/packs.md \u00a7\"Peer-dependency identifiers\"). Resolved against the host's advertised capabilities at register time: a registry MUST refuse to register a pack requiring `artifactTypes` against a host that does not advertise it."
86
86
  },
87
87
  "artifactTypes": {
88
88
  "type": "array",
@@ -114,7 +114,7 @@
114
114
  "pattern": "^(core|vendor|community|private)\\.[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$"
115
115
  }
116
116
  ],
117
- "description": "Reverse-DNS artifact-type identifier. Same pattern and reserved scopes as a pack `name`. This is the value `WorkflowNode.artifactType`, `nodes[].artifact.typeId`, and `artifact.created.artifactType` reference. Third parties MUST NOT publish under `core.*`."
117
+ "description": "Reverse-DNS artifact-type identifier. Same pattern and reserved scopes as a pack `name`. This is the value `WorkflowNode.artifactType`, `nodes[].artifact.typeId`, and `artifact.created.artifactType` reference. Third parties MUST NOT publish under `core.*`. The pattern is definitional: a value outside it is unregistered (spec/v2/core/artifact-type-packs.md), and a host is under no obligation to migrate it. A host that migrates an identifier MUST NOT rewrite a recorded `artifact.created.artifactType`, or any other event-carried artifact-type identifier. It MAY keep a permanent, host-internal read-side alias map, consulted on lookup and never rewriting a stored or emitted identifier; a host that aliases MUST resolve the alias everywhere registration is decided, schema validation included. The legacy spellings stay non-conformant on the wire, and a host MUST NOT advertise or imply otherwise (RFC 0141)."
118
118
  },
119
119
  "schemaRef": {
120
120
  "type": "string",
@@ -132,7 +132,7 @@
132
132
  "open",
133
133
  "closed"
134
134
  ],
135
- "description": "RFC 0075. Strictness contract of the artifact's `schemaRef` schema. `closed` \u21d2 closed-world (`additionalProperties: false`); a consumer MAY rely on the absence of unknown fields. `open` (recommended for AI/LLM-produced artifacts) \u21d2 the schema tolerates extra fields to absorb model drift; consumers MUST ignore unknown fields per COMPATIBILITY.md \u00a72.1. Absent \u21d2 `open` (the forward-compatible default). The `additionalProperties:false` requirement on `schemaRef` was relaxed MUST \u2192 SHOULD by RFC 0075: a closed-world artifact contract contradicts the protocol's own forward-compat mandate and the first AI-native adopter cannot meet it."
135
+ "description": "RFC 0075. Strictness contract of the artifact's `schemaRef` schema. `closed` \u21d2 closed-world (`additionalProperties: false`); a consumer MAY rely on the absence of unknown fields. `open` (recommended for AI/LLM-produced artifacts) \u21d2 the schema tolerates extra fields to absorb model drift; consumers MUST ignore unknown fields per COMPATIBILITY.md \u00a72.1. Absent \u21d2 `open` (the forward-compatible default). A consumer MUST NOT assume closed-world shape unless `validation` is `closed`. The host validates emit-time output against the schema as written; it keeps no separate strict contract schema. The `additionalProperties:false` requirement on `schemaRef` was relaxed MUST \u2192 SHOULD by RFC 0075: a closed-world artifact contract contradicts the protocol's own forward-compat mandate and the first AI-native adopter cannot meet it."
136
136
  },
137
137
  "displayName": {
138
138
  "type": "string",
@@ -150,7 +150,7 @@
150
150
  "pattern": "^([a-z][a-z0-9]*|vendor\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*|x-[a-z][a-z0-9-]*|[a-z0-9][a-z0-9!#$&^_.+-]{0,126}/[a-z0-9][a-z0-9!#$&^_.+-]{0,126})$"
151
151
  },
152
152
  "uniqueItems": true,
153
- "description": "Export-format identifiers (hints) a renderer MAY offer. Spec-reserved core identifiers carry interoperable meaning (the lowercase file-extension / common name): `pdf`, `pptx`, `docx`, `xlsx`, `md`, `html`, `txt`, `csv`, `json`, `png`, `svg`, `jpeg`, `step`, `stl`, `dxf`. Domain-specific formats outside the core set MUST be `vendor.<org>.<format>`- or `x-<format>`-prefixed (mirrors the `requiredModelCapabilities` reserved-core + extension idiom). An entry MAY instead be a lowercase RFC 6838 media type (`type/subtype`, no parameters; RFC 0205 §C); each reserved alias names exactly one media type per artifact-type-packs.md §\"Export-format aliases\", and a consumer MUST treat the two spellings as one format. Advisory: this spec assigns no byte-level production semantics to any identifier \u2014 it standardizes the identifier so two hosts agree what `pptx` names, not how the bytes are produced."
153
+ "description": "Export-format identifiers (hints) a renderer MAY offer. Spec-reserved core identifiers carry interoperable meaning (the lowercase file-extension / common name): `pdf`, `pptx`, `docx`, `xlsx`, `md`, `html`, `txt`, `csv`, `json`, `png`, `svg`, `jpeg`, `step`, `stl`, `dxf`. Domain-specific formats outside the core set MUST be `vendor.<org>.<format>`- or `x-<format>`-prefixed (mirrors the `requiredModelCapabilities` reserved-core + extension idiom). An entry MAY instead be a lowercase RFC 6838 media type (`type/subtype`, no parameters; RFC 0205 §C); each reserved alias names exactly one media type: pdf=application/pdf, pptx=application/vnd.openxmlformats-officedocument.presentationml.presentation, docx=application/vnd.openxmlformats-officedocument.wordprocessingml.document, xlsx=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, md=text/markdown, html=text/html, txt=text/plain, csv=text/csv, json=application/json, png=image/png, svg=image/svg+xml, jpeg=image/jpeg, step=model/step, stl=model/stl, dxf=image/vnd.dxf. A consumer MUST treat an alias and its media type as one format, including when matching a host's `artifactTypes.export` advertisement against a type's `exportFormats`, and a manifest SHOULD NOT list both. A media type outside that list SHOULD be IANA-registered or use an RFC 6838 §3 tree. A pack meant to install on hosts that predate RFC 0205 SHOULD keep to the aliases. Advisory: this spec assigns no byte-level production semantics to any identifier \u2014 it standardizes the identifier so two hosts agree what `pptx` names, not how the bytes are produced."
154
154
  },
155
155
  "syncOn": {
156
156
  "type": "string",
@@ -845,7 +845,8 @@
845
845
  "maxLoopbackIterations": {
846
846
  "type": "integer",
847
847
  "minimum": 1,
848
- "default": 5
848
+ "default": 5,
849
+ "description": "Authoring hint. The protocol binds no enforcement to it: a run's loop bounds are configurable.run.recursionLimit and maxLoopIterations (v2 runs.md §run section) and node-level caps. Hosts differ on what it counts and what happens at the limit; a future additive RFC may bind it (openwop#1748)."
849
850
  },
850
851
  "compensation": {
851
852
  "$ref": "compensation-policy.schema.json",
@@ -838,7 +838,8 @@
838
838
  "maxLoopbackIterations": {
839
839
  "type": "integer",
840
840
  "minimum": 1,
841
- "default": 5
841
+ "default": 5,
842
+ "description": "Authoring hint. The protocol binds no enforcement to it: a run's loop bounds are configurable.run.recursionLimit and maxLoopIterations (v2 runs.md \u00a7run section) and node-level caps. Hosts differ on what it counts and what happens at the limit; a future additive RFC may bind it (openwop#1748)."
842
843
  },
843
844
  "compensation": {
844
845
  "$ref": "compensation-policy.schema.json",
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.44.2"
7
+ "version": "2.44.4"
8
8
  },
9
9
  "note": "Derived from the corpus at generation time. Regenerate with --write; verify with --check."
10
10
  },
@@ -421,5 +421,5 @@
421
421
  "$id": "https://openwop.dev/spec/v1/workspace-file.schema.json"
422
422
  }
423
423
  ],
424
- "digest": "b26ed1f28f51c00d0ceb3c5e479bee4d9d7daba38334b3cec14b06a0bbcb3e9a"
424
+ "digest": "038be26f7c3aec985b5eb28b0163d8b4172a15107f6557b313ea44f23027a570"
425
425
  }
package/spec/v1/gaps.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "./gaps.schema.json",
3
3
  "version": 1,
4
- "updated": "2026-09-28",
4
+ "updated": "2026-09-29",
5
5
  "witnessClasses": [
6
6
  "witnessable-unaided",
7
7
  "witnessable-gated",
@@ -13481,11 +13481,11 @@
13481
13481
  "rfc": "0225",
13482
13482
  "local": "G1",
13483
13483
  "section": "§Implementation notes",
13484
- "surface": "No host advertises `retryPolicy.maxElapsedMs` yet, so the new row has no witness.",
13484
+ "surface": "No host advertised `retryPolicy.maxElapsedMs`, so the row had no witness.",
13485
13485
  "witness": "unclassified",
13486
13486
  "requirementId": null,
13487
- "disposition": "externally-gated",
13488
- "target": "host-advertises-max-elapsed",
13487
+ "disposition": "closed",
13488
+ "target": null,
13489
13489
  "sources": [
13490
13490
  {
13491
13491
  "file": "RFCS/registers/0225-webhook-retry-max-elapsed.gaps.md",
@@ -13510,6 +13510,142 @@
13510
13510
  }
13511
13511
  ]
13512
13512
  },
13513
+ {
13514
+ "id": "openwop.gap.0228.1",
13515
+ "rfc": "0228",
13516
+ "local": "G1",
13517
+ "section": "§Compatibility",
13518
+ "surface": "MyndHyve emits `ssrf_blocked` and `fetch_failed` from `ctx.http.safeFetch` (`host/safeFetch.ts:68`), and a `503 service_unavailable` carrying `details.retryAfter` and `details.inflightCap` (`middleware/backpressureGate.ts:54-57`), which `errors.md` §Retry timing forbids.",
13519
+ "witness": "unclassified",
13520
+ "requirementId": null,
13521
+ "disposition": "externally-gated",
13522
+ "target": "rfc-0228-active",
13523
+ "sources": [
13524
+ {
13525
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13526
+ "token": "G1"
13527
+ }
13528
+ ]
13529
+ },
13530
+ {
13531
+ "id": "openwop.gap.0228.2",
13532
+ "rfc": "0228",
13533
+ "local": "G2",
13534
+ "section": "§Compatibility",
13535
+ "surface": "The v2 reference host emits `example.mcp_unreachable` (`mcp-client.ts:67`, `:73`) and `example.http_fetch_failed` (`executor.ts:264`), vendor codes chosen only because no row existed.",
13536
+ "witness": "unclassified",
13537
+ "requirementId": null,
13538
+ "disposition": "externally-gated",
13539
+ "target": "rfc-0228-active",
13540
+ "sources": [
13541
+ {
13542
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13543
+ "token": "G2"
13544
+ }
13545
+ ]
13546
+ },
13547
+ {
13548
+ "id": "openwop.gap.0228.3",
13549
+ "rfc": "0228",
13550
+ "local": "G3",
13551
+ "section": "§Compatibility",
13552
+ "surface": "openwop-app throws `path_outside_sandbox` (`host/durable/durableFs.ts:20`, `:27`) and `table_schema_violation` (`durableTable.ts:69`) from `ctx` storage; its `ads-publish-*` packs branch on the five `secret_*` names.",
13553
+ "witness": "unclassified",
13554
+ "requirementId": null,
13555
+ "disposition": "externally-gated",
13556
+ "target": "rfc-0228-active",
13557
+ "sources": [
13558
+ {
13559
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13560
+ "token": "G3"
13561
+ }
13562
+ ]
13563
+ },
13564
+ {
13565
+ "id": "openwop.gap.0228.4",
13566
+ "rfc": "0228",
13567
+ "local": "G4",
13568
+ "section": "§Conformance",
13569
+ "surface": "No v2 scenario exercises a host-service refusal: `fs-path-traversal`, `table-schema-enforcement`, `budget-enforcement`, `budget-policy-shape` and `production-backpressure` are major-1 only.",
13570
+ "witness": "unclassified",
13571
+ "requirementId": null,
13572
+ "disposition": "externally-gated",
13573
+ "target": "rfc-0228-active",
13574
+ "sources": [
13575
+ {
13576
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13577
+ "token": "G4"
13578
+ }
13579
+ ]
13580
+ },
13581
+ {
13582
+ "id": "openwop.gap.0228.5",
13583
+ "rfc": "0228",
13584
+ "local": "G5",
13585
+ "section": "§D",
13586
+ "surface": "The `aiProviders` codes for a provider that answered with a failure (`content_too_long`, `envelope_validation_failed`, the `*_generation_failed` codes, the provider arm of `speech_synthesis_failed`) are not decided here; the leaning is one `provider_error` row.",
13587
+ "witness": "unclassified",
13588
+ "requirementId": null,
13589
+ "disposition": "transferred",
13590
+ "target": "aiProviders-normative-home",
13591
+ "sources": [
13592
+ {
13593
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13594
+ "token": "G5"
13595
+ }
13596
+ ]
13597
+ },
13598
+ {
13599
+ "id": "openwop.gap.0228.6",
13600
+ "rfc": "0228",
13601
+ "local": "G6",
13602
+ "section": "§Compatibility, §H",
13603
+ "surface": "openwop-app answers ungated `/prompts*` with `501 capability_not_provided` (`routes/prompts.ts:147`, `:174`, `:178`, `:202`, `:242`), at a status the registry does not give that code, and emits `prompt_ref_ambiguous` (`:214`, `:330`) and the `aiProviders` modality codes.",
13604
+ "witness": "unclassified",
13605
+ "requirementId": null,
13606
+ "disposition": "externally-gated",
13607
+ "target": "rfc-0228-active",
13608
+ "sources": [
13609
+ {
13610
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13611
+ "token": "G6"
13612
+ }
13613
+ ]
13614
+ },
13615
+ {
13616
+ "id": "openwop.gap.0228.7",
13617
+ "rfc": "0228",
13618
+ "local": "G7",
13619
+ "section": "§Compatibility",
13620
+ "surface": "MyndHyve fails a run with `no_active_deployment` (`runExecutor.ts:2182`), emits the `aiProviders` modality codes, and answers an agent-deployment denial as `{ error, detail }` (`routes/agents.ts:719`) with unregistered codes (`illegal_transition`, `canary_unsupported`, `no_deployment`, `transition_denied`). The top-level `detail` breaks the envelope's `additionalProperties: false`.",
13621
+ "witness": "unclassified",
13622
+ "requirementId": null,
13623
+ "disposition": "externally-gated",
13624
+ "target": "rfc-0228-active",
13625
+ "sources": [
13626
+ {
13627
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13628
+ "token": "G7"
13629
+ }
13630
+ ]
13631
+ },
13632
+ {
13633
+ "id": "openwop.gap.0228.8",
13634
+ "rfc": "0228",
13635
+ "local": "G8",
13636
+ "section": "§G, §H",
13637
+ "surface": "`api/v2/openapi.yaml` is derived from the v1 document by `scripts/derive-v2-api.py`, which copies v1's `501` responses and the descriptions naming unregistered codes.",
13638
+ "witness": "unclassified",
13639
+ "requirementId": null,
13640
+ "disposition": "externally-gated",
13641
+ "target": "rfc-0228-active",
13642
+ "sources": [
13643
+ {
13644
+ "file": "RFCS/registers/0228-v1-host-service-error-codes.gaps.md",
13645
+ "token": "G8"
13646
+ }
13647
+ ]
13648
+ },
13513
13649
  {
13514
13650
  "id": "openwop.gap.spec.a2a-integration.g1",
13515
13651
  "rfc": "0152",
@@ -206,6 +206,7 @@
206
206
  },
207
207
  "codemod": "openwop.codemod.event-type-codemap",
208
208
  "persistedData": "translated",
209
+ "note": "Not translatable (corrected 2026-09-29, Class 3, openwop#1741): an era-2 approval.granted / approval.rejected / approval.overridden in the RFC 0051 governance shape {gateId, principal, …} has no v2 projection — the closed v2 interruptResolved requires interruptId, which cannot be sourced from the row without defaulting it — so a v2 read of one is 500 payload_unprojectable (events.md). Census at openwop-app 62705064c, MyndHyve d55ab6edb and openwop-examples b6302cd: 0 persisted writers of the governance shape. Tripwire: a host reporting persisted governance-shape rows files an additive RFC for a sanctioned interruptId derivation, failing closed when absent.",
209
210
  "requirementIds": [],
210
211
  "gapIds": [],
211
212
  "deprecationId": "openwop.deprecation.legacy-interrupt-payloads"
package/spec/v2/README.md CHANGED
@@ -31,8 +31,8 @@ when v1 ends.
31
31
  | Area | Documents |
32
32
  | --- | --- |
33
33
  | Foundation | [`overview`](./core/overview.md), [`versioning`](./core/versioning.md), [`headers`](./core/headers.md), [`identity`](./core/identity.md), [`oauth`](./core/oauth.md), [`capabilities`](./core/capabilities.md), [`i18n`](./core/i18n.md) |
34
- | Execution | [`runs`](./core/runs.md), [`events`](./core/events.md), [`interrupt`](./core/interrupt.md), [`conversation`](./core/conversation.md), [`persistence`](./core/persistence.md), [`idempotency`](./core/idempotency.md), [`replay`](./core/replay.md) |
35
- | Integration | [`webhooks`](./core/webhooks.md), [`interop`](./core/interop.md), [`host services`](./core/host-services.md), [`storage`](./core/storage.md), [`tool catalog`](./core/tool-catalog.md), [`portability`](./core/portability.md), [`packs`](./core/packs.md), [`node-pack runtimes`](./core/node-pack-runtimes.md), [`connection packs`](./core/connection-packs.md), [`form-content packs`](./core/form-content-packs.md), [`workflow-chain packs`](./core/workflow-chain-packs.md) |
34
+ | Execution | [`runs`](./core/runs.md), [`events`](./core/events.md), [`interrupt`](./core/interrupt.md), [`conversation`](./core/conversation.md), [`persistence`](./core/persistence.md), [`idempotency`](./core/idempotency.md), [`replay`](./core/replay.md), [`execution`](./core/execution.md) |
35
+ | Integration | [`webhooks`](./core/webhooks.md), [`interop`](./core/interop.md), [`host services`](./core/host-services.md), [`storage`](./core/storage.md), [`tool catalog`](./core/tool-catalog.md), [`portability`](./core/portability.md), [`packs`](./core/packs.md), [`node-pack runtimes`](./core/node-pack-runtimes.md), [`connection packs`](./core/connection-packs.md), [`form-content packs`](./core/form-content-packs.md), [`workflow-chain packs`](./core/workflow-chain-packs.md), [`artifact-type packs`](./core/artifact-type-packs.md) |
36
36
  | Reliability | [`errors`](./core/errors.md), [`security defaults`](./core/security-defaults.md), [`conformance`](./core/conformance.md) |
37
37
 
38
38
  ## Source-of-truth map
@@ -0,0 +1,37 @@
1
+ # Artifact-Type Packs
2
+
3
+ > **Status: Stable.**
4
+ > **Normative home:** `artifactTypes`.
5
+
6
+ ## Why this exists
7
+
8
+ An artifact-type pack binds an `artifactTypeId` to a JSON Schema, an advisory rendering hint and export formats, so two hosts mean the same thing by one type. The manifest is `schemas/v2/artifact-type-pack-manifest.schema.json`, whose descriptions carry the per-field rules; installation and signing follow [packs.md](packs.md).
9
+
10
+ A registry MUST refuse a manifest that mixes `kind: "artifact-type"` with `nodes[]`, `chains[]` or `prompts[]`, with `pack_kind_invalid`.
11
+
12
+ ## Schema distribution
13
+
14
+ The schema at `schemaRef`, inside the signed tarball, is the source of truth. Its canonical URL and `$id` is `{HostBase}/schemas/artifacts/{artifactTypeId}.schema.json`, served as `application/schema+json`.
15
+
16
+ - A host advertising `artifactTypes` SHOULD serve each installed type's schema there, and MUST for a host-registered type whose `schemaVersion` it advertises.
17
+ - A tarball copy and a served copy of one `(artifactTypeId, schemaVersion)` MUST be byte-identical.
18
+
19
+ At registry publish and at install, a host MUST reject, with `pack_validation_failed`, an artifact schema exceeding its bounds on serialized size, `$ref` depth or keyword/subschema count, and MUST compile under a wall-clock timeout. It SHOULD reject a `pattern` it cannot evaluate in linear time (invariant `artifact-schema-compile-bounded`).
20
+
21
+ ## Registration
22
+
23
+ A host advertising `artifactTypes` places each `WorkflowNode.artifactType`, `nodes[].artifact.typeId` and `artifact.created.artifactType` value in one tier: **pack-registered** (an installed pack declares it; `registrationSource: "pack"`), **host-registered** (a host-native type with a host-known schema; `"host"`), or **unregistered**.
24
+
25
+ - Before emitting `artifact.created` for a registered type, the host MUST validate the payload against its schema as written, per its `validation`. On failure it MUST NOT emit and MUST surface the error; on success it sets `registered: true` and the matching `registrationSource`.
26
+ - A host MAY emit `registered: true` for a host-registered type only if it serves that type's schema.
27
+ - A host MUST NOT reject or schema-validate an unregistered value. It SHOULD emit `registered: false` and SHOULD log an unresolved-type warning.
28
+ - A host not advertising `artifactTypes` treats every value as an opaque string.
29
+
30
+ ## The capability
31
+
32
+ `artifactTypes` advertises `store`, `render` and `export` independently; `types` overrides them per `artifactTypeId`, falling back to the global values (`schemas/v2/capabilities.schema.json`).
33
+
34
+ - **`store`** — every path by which a host persists an artifact of a registered type MUST emit `artifact.created`; a host with a silent path MUST NOT advertise `store: true` for that type.
35
+ - **`render`**, **`export`** — advisory. A host MUST NOT refuse to store an artifact, or fail a run, because it cannot render it.
36
+
37
+ *Sources: RFCs 0071, 0075, 0141, 0145, 0205.*
@@ -125,6 +125,18 @@ With `bufferMs` (0..5000) the host accumulates events into one `event: batch` fr
125
125
 
126
126
  `hostEvents` carries the heartbeat messages (`schemas/v2/heartbeat-evaluated.schema.json`, `schemas/v2/heartbeat-state-changed.schema.json`) at `/host/events` (`streamHostEvents`), the documented default. A host MAY declare another address under `heartbeat.deliveryChannel` ([capabilities.md](capabilities.md)). The channel is content-free of run data. There is no channel without an address.
127
127
 
128
+ #### `heartbeat`
129
+
130
+ A heartbeat evaluates a predicate on an interval (at least `minIntervalSec`) and acts only on a state change. A host advertising `heartbeat` SHOULD also advertise `scheduling`, and otherwise MUST document its own interval substrate. On each tick it MUST:
131
+
132
+ - skip, not queue, a tick while the prior evaluation still runs;
133
+ - bound the evaluation by `maxRuntimeMs`, itself capped by `limits.maxRunDurationMs`, terminating an overrun with `status: timeout`;
134
+ - pass the predicate the prior tick's state, and perform no side effect itself; the predicate MUST be a pure function of observed and prior state;
135
+ - emit `heartbeat.evaluated`;
136
+ - on a transition only, emit `heartbeat.stateChanged` and, if the predicate asks, call `createRun`; never on an unchanged tick.
137
+
138
+ The first tick of a `heartbeatId` MUST be treated as a transition from `{}`. A durable host SHOULD persist prior state so a restart does not re-notify.
139
+
128
140
  ## Poll
129
141
 
130
142
  `GET /runs/{runId}/events/poll` (`pollRunEvents`) is the long-poll fallback.
@@ -188,4 +200,45 @@ An absent `kinds` is not an empty catalog and is not an unrestricted one: a host
188
200
  - **`feedback.targets`** names the resources an annotation may be attached to. A host MUST refuse an annotation whose target is outside the advertised set, and MUST NOT write it to the replayable run event log.
189
201
  - **`providerUsage.costEstimates`** advertises that the host stamps a derived cost on the `provider.usage` event. That figure is an estimate from the host's own rate table; a consumer MUST NOT treat it as a billed amount.
190
202
 
191
- *Sources: RFCs 0171, 0172, 0176, 0185, 0194, 0213.*
203
+ ### `feedback`
204
+
205
+ `feedback.signals` lists the signal kinds a host accepts; absent means all four. A host advertising `feedback` MUST:
206
+
207
+ - accept an annotation on a terminal run;
208
+ - keep annotations visible only within the run's tenant (invariant `annotation-cross-tenant-isolation`);
209
+ - redact secret-shaped material in `signal.correction` and `note` before persistence, listing and export (invariant `annotation-content-redaction`);
210
+ - audit-log each recording with the acting principal.
211
+
212
+ ### `providerUsage`
213
+
214
+ A host advertising `providerUsage` MUST emit exactly one `provider.usage` per LLM provider invocation, before that node's `node.completed`. A host that does not advertise it omits the event.
215
+
216
+ - `inputTokens` and `outputTokens` MUST replay identically; `costEstimateUsd` MAY be omitted on replay.
217
+ - The payload MUST NOT carry credential refs, hashed credential identifiers, or prompt or response text (invariant `provider-usage-no-credential-leak`).
218
+ - `providerUsage.currency` is the ISO 4217 currency of `costEstimateUsd`; absent means USD.
219
+
220
+ ### `envelopes`
221
+
222
+ `envelopes.reasoning` advertises the host's prompt posture for the optional payload field `reasoning`.
223
+
224
+ - `reasoning` SHOULD be the first property where the schema dialect orders properties. A vendor kind whose payload needs multi-step reasoning SHOULD declare it as optional.
225
+ - Where a payload schema permits it, a host SHOULD instruct the model to populate it. A host MUST NOT reject an envelope without it, whatever `promptDirective` says.
226
+ - A host MUST NOT route on `reasoning`. A known secret in the input MUST NOT appear verbatim in it, in derived events, span attributes or the debug bundle (invariant `envelope-reasoning-secret-redaction`).
227
+
228
+ A host advertising `envelopes.reliability`:
229
+
230
+ - MUST emit `envelope.retry-exhausted` and `envelope.refusal`, and list in `reliability.events[]` both of them and only the other reliability events it emits;
231
+ - SHOULD emit `envelope.retry-attempted` before each retry past the first;
232
+ - MUST pass `previousError`, `finalError` and `refusalText` through the secret redaction applied to envelope payloads (invariants `envelope-refusal-no-prompt-leak`, `envelope-recovery-no-content-leak`);
233
+ - MUST replay `totalAttempts`, `outputTokenCount` and the recovery `path` identically. `refusalText` MAY differ, and a consumer MUST tolerate `null`.
234
+
235
+ Under `reliability.completion.distinguishesTruncation`, an envelope is complete only on a clean provider stop with a payload that validates against its kind's schema.
236
+
237
+ - **Truncation** (no clean stop, whatever the payload): the host MUST emit `envelope.truncated`. A retry SHOULD raise the output budget, by `truncationBudgetMultiplier` (default 2), and MUST NOT carry a schema-correcting fragment.
238
+ - **Schema violation** (clean stop, invalid payload): a retry's corrective fragment SHOULD reproduce the validator's failure and MUST NOT contain text from the model's output. The retry MUST NOT raise the output budget.
239
+ - **Refusal** is terminal: the node MUST fail with `envelope_refusal`.
240
+ - Each retry past the first MUST emit `envelope.retry-attempted` with that `reason`. Both paths count against `limits.schemaRounds`.
241
+ - On exhaustion the host MUST emit `envelope.retry-exhausted` with that `finalReason` and `cap.breached` `kind: "schema"`, and fail the node with `envelope_truncation_unrecoverable` or `envelope_invalid`.
242
+ - Lenient-parse recovery consumes no retry. It emits `envelope.recovery-applied` once per recovery, carrying only the path and an optional byte offset.
243
+
244
+ *Sources: RFCs 0026, 0030, 0032, 0033, 0056, 0060, 0171, 0172, 0176, 0185, 0194, 0213.*
@@ -0,0 +1,58 @@
1
+ # Execution
2
+
3
+ > **Status: Stable.**
4
+ > **Normative home:** `selfHostedRunner`, `subWorkflow`, `multiAgent`.
5
+
6
+ ## Why this exists
7
+
8
+ A step can run on a user's machine, in a child run, or under a supervisor loop; the host stays the orchestration, persistence and replay authority.
9
+
10
+ ## `selfHostedRunner`
11
+
12
+ A runner is a user-operated process that dials out, holds credentials the host cannot reach, and executes single model or tool steps. It receives dispatch frames over SSE and POSTs result frames, on host-defined paths. A host MUST NOT advertise `selfHostedRunner` unless it accepts registrations, routes matching dispatch and delivers results.
13
+
14
+ - **Records.** A registration (`schemas/v2/self-hosted-runner-registration.schema.json`) MUST NOT appear in discovery. `dispatchKinds` lists `model`, `tool` or both.
15
+ - **Subject isolation.** A host MUST NOT route a step to a runner its run's subject does not own, and MUST match on subject before capability.
16
+ - **Credentials.** A runner credential MUST NOT transit the host or appear in any frame, event, result, debug bundle or log. The runner bearer MUST NOT be a provider credential.
17
+ - **Untrusted output.** Runner output re-entering an agent loop MUST be fenced as untrusted.
18
+ - **At most once.** A frame's `seq` is a per-runner cursor, resumed by `Last-Event-ID`, and MUST NOT be conflated with event `sequence`. The host MUST drop, not re-dispatch, a `{runId, stepId}` already persisted; the runner MUST answer under the pair it received.
19
+ - **Liveness.** Dispatch to a departed runner MUST fail with retriable `runner_unavailable`, never hang.
20
+ - **Replay and fork.** Replay MUST NOT re-dispatch. A fork MUST NOT pin later dispatch to the original `runnerId`.
21
+
22
+ ## `subWorkflow`
23
+
24
+ `core.subWorkflow` starts a child run of another workflow and waits for its terminal status.
25
+
26
+ - **`workflowId`.** A host MUST refuse the parent run when that workflow is not loaded.
27
+ - **`waitForCompletion`** defaults to `true`; a host MAY refuse `false` with `validation_error`.
28
+ - **`onChildFailure`.** `fail-parent` (default) fails the node and the run; `absorb` records the failure and continues.
29
+ - **Output.** `node.completed` MUST carry `outputs.childRunId` and `outputs.childStatus` (`completed | failed | cancelled`), and MAY add fields.
30
+ - **`inputMapping`** (`childVar → parentVar`) seeds the child once, at creation, after and over its `variables[].defaultValue`, which MUST seed first. An unset parent variable MUST arrive undefined, never an error or `null`. A host not advertising `subWorkflow.inputMapping` MUST refuse a non-empty `inputMapping` at registration with `validation_error`, naming it in `details.requiredCapability`.
31
+ - **`outputMapping`** (`parentVar → childVar`). After the child completes, the host MUST copy each mapped variable into the parent, without throwing on or copying an undefined one.
32
+ - **`propagateCancellation`** (default `true`) cancels the child with its parent.
33
+
34
+ ## `multiAgent`
35
+
36
+ `multiAgent.executionModel.version` is cumulative: a host advertising `N` MUST implement levels 1 through `N`.
37
+
38
+ | Level | Adds |
39
+ | --- | --- |
40
+ | 1 | the supervisor loop and worker handoff |
41
+ | 2 | confidence escalation; memory across sub-runs |
42
+ | 3 | cross-host causation |
43
+ | 4 | replay determinism under nondeterministic models |
44
+ | 5 | stateful loop lifecycle and context budget |
45
+ | 6 | verifier turn and convergence |
46
+
47
+ Levels 2–6 are not yet restated in v2 prose. Their rules are those of their owning RFCs: level 2 [RFC 0039](https://github.com/openwop/openwop/blob/main/RFCS/0039-multi-agent-confidence-and-memory-lifecycle.md), level 3 [RFC 0040](https://github.com/openwop/openwop/blob/main/RFCS/0040-multi-agent-cross-host-causation.md), level 4 [RFC 0041](https://github.com/openwop/openwop/blob/main/RFCS/0041-multi-agent-replay-under-nondeterminism.md), level 5 [RFC 0061](https://github.com/openwop/openwop/blob/main/RFCS/0061-agent-loop-lifecycle.md) and [RFC 0111](https://github.com/openwop/openwop/blob/main/RFCS/0111-context-economy.md), level 6 [RFC 0090](https://github.com/openwop/openwop/blob/main/RFCS/0090-agent-verifier-and-convergence.md).
48
+
49
+
50
+ At level 1, a workflow whose `core.orchestrator.supervisor` feeds `core.dispatch` runs this loop:
51
+
52
+ - Each turn records one decision as `runOrchestrator.decided`. `terminate` completes the run; `clarify` and `escalate` suspend on a `clarification` or `approval` interrupt; `next-worker` dispatches each of `nextWorkerIds[]` as a child run, and the next turn waits for all of them.
53
+ - The loop MUST be re-entrant: replay from any iteration MUST reproduce its state.
54
+ - A worker moves `pending → dispatching → running → harvested`, or ends `failed` or `cancelled`. Each transition that occurs MUST emit `core.workflowChain.event` whose `causationId` names the prior transition, first `runOrchestrator.decided`. A host MUST NOT synthesize a phase it never produces.
55
+ - `output.harvested` fires exactly when a child completes with a non-empty `outputMapping`.
56
+ - A host not advertising `executionModel` MUST NOT emit `core.workflowChain.event`.
57
+
58
+ *Sources: RFCs 0007, 0022, 0037, 0122.*
@@ -1,11 +1,11 @@
1
1
  # Host services
2
2
 
3
3
  > **Status: Stable.**
4
- > **Normative home:** `aiEnvelope`, `promptLibrary`, `agentRuntime`, `mcp`, `workspace`.
4
+ > **Normative home:** `aiEnvelope`, `promptLibrary`, `prompts`, `aiProviders`, `agentRuntime`, `mcp`, `workspace`, `secrets`, `modelCapabilities`, `scheduling`, `queueBus`, `toolHooks`, `httpClient`, `memory`.
5
5
 
6
6
  ## Why this exists
7
7
 
8
- A node pack invokes advertised `host.*` services through `ctx`. This document states the contract a host takes on by advertising them.
8
+ A node pack invokes advertised `host.*` services through `ctx`. This document states the contract a host takes on by advertising them, and how it schedules runs, matches models and audits tool calls.
9
9
 
10
10
  ## `aiEnvelope`
11
11
 
@@ -23,6 +23,66 @@ A host advertising `promptLibrary`:
23
23
  - MUST return a pinned version verbatim, so that a replayed run resolves the same template;
24
24
  - MUST fail the calling node rather than substitute an unpinned one.
25
25
 
26
+ ## `prompts`
27
+
28
+ A host advertising `prompts` resolves node `config` PromptRefs (`systemPromptRef`, `userPromptRef`, `fewShotPromptRefs`, `schemaHintPromptRef`); otherwise they are opaque strings.
29
+
30
+ - `templateKinds` and `variableSources` narrow what is accepted; `secret` SHOULD appear only with `secrets`.
31
+ - `maxTemplateBytes` MUST NOT exceed 65536. `observability` is `off`, `hashed` (default) or `full`.
32
+ - `endpointsSupported` gates `/prompts*`, `mutableLibrary` its writes, `packsSupported` pack installs; ungated operations answer `501`. `library` carries `id`, `renderEndpoint`, `maxRenderRequestBytes`.
33
+
34
+ ### Resolution
35
+
36
+ For each `(nodeId, kind)` the host MUST take the first non-null ref below, and MUST emit `agent.prompt-resolved` (one `chain[]` entry per layer tried) before `prompt.composed`:
37
+
38
+ 1. node `config`; a ref beats an inline body;
39
+ 2. under `agentBindings`, the `config.agentId` agent: for `system` first its own prompt (tagged `agent-intrinsic`), then `promptOverrides`, then MAY a `promptLibraryRef` default. An unknown agent MUST log a warning and be skipped;
40
+ 3. the workflow's `defaults.promptRefs[kind]`;
41
+ 4. `prompts.defaults[kind]`.
42
+
43
+ All-null is fatal only if the node type says so. A host honoring `ai.promptOverrides` applies it first and MUST record a `run-configurable` entry.
44
+
45
+ ### Composition
46
+
47
+ - `{{varName}}` substitution is literal. An unbound required variable MUST fail the node; an unbound optional or undeclared one renders empty, and install SHOULD warn on an undeclared one.
48
+ - `secret` values MUST appear only as `[REDACTED:<secretId>]` in observability output.
49
+ - Untrusted input MUST be wrapped verbatim in `<UNTRUSTED>…</UNTRUSTED>`, making `contentTrust` `untrusted`.
50
+ - Unless `observability` is `off`, the host MUST emit `prompt.composed` per composition, with bodies only under `full`.
51
+ - On replay, `hash`, `variableHashes`, `refs`, the resolved ref and `chain[].applied` MUST match, and a mismatch MUST emit `replay.diverged`. Bodies MAY be omitted; `chain[].source` SHOULD match, and a rotated `host-defaults` source MUST be tolerated.
52
+
53
+ ### Library
54
+
55
+ - A version-less ref resolves the latest. A stringy ref matching several templates MUST be refused; `libraryId` disambiguates.
56
+ - `renderPromptTemplate` dispatches nothing, and its `hash` MUST equal the dispatch-time `prompt.composed` hash.
57
+ - `getPromptTemplate` SHOULD send `ETag` and `max-age=60`, `immutable` when `version` is pinned.
58
+ - Writes MUST be authenticated and SHOULD be role-scoped. An update MUST carry a greater SemVer; built-in and pack templates are read-only.
59
+ - For workspace-scoped reads and writes, the host MUST verify membership from the authenticated identity, never a caller's `workspaceId`, fail-closed (canonically `403 workspace_membership_required`), in the application tier even behind a privileged database client.
60
+ - A `kind: "prompt"` pack MUST NOT carry `nodes[]` or `chains[]`; its templates MUST carry `meta.packName` and `meta.packVersion`.
61
+
62
+ ## `aiProviders`
63
+
64
+ A host advertising `aiProviders` MUST expose `ctx.callAI`. A `provider` a `ctx` call names MUST be in `providers` ([runs.md](runs.md) §`ai` section covers `byok`).
65
+
66
+ - A part of a modality absent from `input` MUST be rejected, never dropped; non-text input is untrusted.
67
+ - A `media.*` envelope inlines base64 only up to `maxInlineMediaBytes` (default 256 KiB); above it the host MUST use a `url`.
68
+ - `imageGeneration`, `videoGeneration`, `speechSynthesis` and `realtimeVoice` add `ctx.callImageGenerator`, `callVideoGenerator`, `callSpeechSynthesizer`, and `callTranscriber` plus streamed synthesis. Unadvertised synthesis or transcription MUST be rejected, never a no-op or whole-file fallback.
69
+ - A video caller MUST honor `ctx.signal`. Synthesis MUST return exactly one of `url` or `base64`, a `url` served through the SSRF guard. The transcriber MUST reject inline or `mediaRef` audio.
70
+ - `voiceId`, `streamRef` and `cachePrefixId` MUST NOT encode secrets. Transcripts are untrusted; an interim one MUST NOT be persisted or drive a side-effecting tool.
71
+
72
+ `selfHosted` (operator-configured OpenAI-compatible endpoints) MUST be advertised only with one configured and reachable. A host MUST NOT disclose an endpoint's location on any wire surface or in a provider id. A client MUST NOT infer capabilities from the id; unadvertised ones fail `capability_not_provided`.
73
+
74
+ `authModes` (`apiKey`, `oauth-pkce`, `oauth-device`, `none`, `subscription`) is capability, not policy: a client MUST ignore an unknown mode and MUST NOT infer policy from one.
75
+
76
+ - OAuth and `subscription` credentials go by `ref`, never key material; an OAuth mode SHOULD come with `oauth`.
77
+ - A `subscription` credential MUST bind at user scope; a tenant or workspace binding MUST be rejected with `credential_scope_forbidden`.
78
+ - A host MUST NOT advertise `subscription` without a reachable acquisition mechanism.
79
+
80
+ `policies.modes` lists enforced modes; a client MUST tolerate any subset, and absence means `optional` only. The host MUST document its `scopes` precedence. `disabled` always refuses (`provider_disabled`); `required` refuses without `credentialRef` (`byok_required`) or a usable secret (`byok_required_but_unresolved`); `restricted` refuses a model matching no `allowedModels` glob (`model_not_allowed`).
81
+
82
+ A refusal MUST carry `policies.errorCode` (or its default), SHOULD carry `reason`, and MUST NOT echo the policy; each decision SHOULD be audited. An empty `restricted` policy MUST fail closed; a resolver outage SHOULD fail open.
83
+
84
+ A host advertising `promptPrefixCache` MAY honor `cachePrefixId` per routed provider, and otherwise MUST ignore it. It MUST key the cache by (authenticated tenant, `cachePrefixId`) and MUST NOT persist prompt or response substrings keyed by it. The envelope and `provider.usage` token counts MUST match on hit and miss, and on replay.
85
+
26
86
  ## `agentRuntime`
27
87
 
28
88
  A host advertising `agentRuntime` MUST expose `spawn`, `delegate`, `consensus` and `messageSend`, and MUST satisfy `agents.manifestRuntime`, which advertising it implies.
@@ -38,6 +98,78 @@ Each rejects only for an unknown `serverId` (`not_found`), an MCP error response
38
98
  - `readResource` resolves to the `ReadResourceResult` unaltered.
39
99
  - `serverHealth` MUST report `reachable`, `unreachable` or `incompatible` from a `server/discover` probe no older than its `ttlMs`, with the `DiscoverResult` when one was received. It MUST NOT report a connection or session state, which MCP 2026-07-28 does not have.
40
100
 
101
+ ## `secrets`
102
+
103
+ A host advertising `secrets` MUST resolve secrets to opaque references. Raw key material MUST NOT appear in any event, log, trace, prompt, error, export or screenshot, and the host MUST test this before exposing BYOK.
104
+
105
+ - `scopes` lists the storage scopes it implements; a client MUST tolerate any subset. `resolution` is `host-managed`.
106
+ - A host offering `resolveInPack` MUST expose `ctx.secrets.resolve({ ref, purpose })`, returning `plaintext` and optional `expiresAt` and `rotatedAt`.
107
+
108
+ For `resolveInPack`, the host:
109
+
110
+ - MUST keep the plaintext out of events, spans, logs, snapshots and replay state; a replay re-resolves it, and SHOULD record only `ref`, `purpose` and time;
111
+ - MUST resolve `ref` only to a credential the calling run may read, fail a `ref` from another workspace, and never substitute another credential.
112
+
113
+ A pack MUST pass a non-empty `purpose`, which the host audits. It MUST NOT log the plaintext, keep it past the consuming call, or pass it to any other `ctx` method, and MUST treat it as run input that may differ between runs.
114
+
115
+ ## `modelCapabilities`
116
+
117
+ `advertised` lists the capability identifiers the active model offers; a host-private identifier MUST be prefixed `x-host-<host>-`.
118
+
119
+ A host advertising `modelCapabilities` that dispatches a node declaring `requiredModelCapabilities` MUST check, then optionally substitute, then emit, then dispatch or refuse:
120
+
121
+ - all met: dispatch;
122
+ - unmet, with a `fallbackModel` declared, `substitutionSupported` advertised, and the fallback's provider in `aiProviders.providers` with a resolvable credential: emit `model.capability-substituted` and dispatch the fallback;
123
+ - otherwise: emit `model.capability-insufficient` and fail the run `capability_not_provided`.
124
+
125
+ It MUST NOT substitute silently or dispatch an unsuitable model. It MUST check a fallback's full capability set, and refuse one that falls short with `fallbackAttempted: true` rather than chain another. Checking capabilities before resolving prompts is RECOMMENDED.
126
+
127
+ ## `scheduling`
128
+
129
+ A host advertising `scheduling` starts runs from the `schedule` trigger in the forms it advertises (`cron`, `delayed`, `calendar`). It MAY do so without `queueBus`. For each schedule it MUST:
130
+
131
+ - persist it so it survives a restart and fires on time;
132
+ - fire once per tick, never duplicate concurrent runs;
133
+ - reject a fire time beyond `maxFutureHorizon` with `schedule_horizon_exceeded`, whose `details.maxFutureHorizon` SHOULD echo the cap;
134
+ - after missing a tick while down, either fire once on recovery or skip to the next tick, as it documents, never the whole backlog.
135
+
136
+ ## `queueBus`
137
+
138
+ A host advertising `queueBus` MUST expose `ctx.queueBus.publish`, `consume`, `ack` and `nack`; `deadLetter` when it advertises `deadLetterSupported`; and `streamSubscribe` when it advertises `stream`, honoring `fromBeginning` only under `stream.fromBeginning`. It MAY use any of its advertised `backends`.
139
+
140
+ - A tenant's consumer MUST NOT receive another tenant's messages, even on the same topic.
141
+ - `ack` MUST remove a message, `nack` MUST return it for redelivery, and `deadLetter` MUST route it to the configured dead-letter queue. That queue holds messages; the `deadLetter` family holds runs ([runs.md](runs.md)).
142
+ - A workflow triggered by a queue consume MUST get one run per inbound message, with no batching or skipping.
143
+ - The wire shape MUST NOT vary by backend.
144
+
145
+ ## `toolHooks`
146
+
147
+ A host advertising `toolHooks` extends `agent.toolCalled` and `agent.toolReturned` for every external tool call:
148
+
149
+ - **`prePostEvents`.** The host MUST set `argsHash`, `principal` and `transport` on the call, and `status` and `durationMs` on the return. `argsHash` is SHA-256 over the RFC 8785 canonical arguments with secrets already redacted. A non-agent egress uses the principal `core.system`. `durationMs` is re-emitted verbatim on replay or fork, never recomputed.
150
+ - **`perToolAuthorization`.** Before invoking, the host MUST check the principal's scopes against the tool's `requiredScopes`. If one is missing or cannot be evaluated, it MUST NOT invoke, MUST emit `agent.toolReturned` with `status: forbidden`, and MUST answer `403 forbidden` with `details.scope: "tool"`, `toolName` and `requiredScopes`.
151
+ - **`perToolRateLimit`.** The host MUST keep a token bucket per `(principal, toolName)`. When it is empty the host MUST NOT invoke, and emits `status: rate_limited` and answers `429 rate_limited` with `details.scope: "tool"`.
152
+
153
+ A host MAY refuse an allowlisted tool at loop start. That return has no call: the host MUST synthesize its `callId` (a stable derivation is RECOMMENDED), MAY omit `causationId`, and MUST NOT invent an `agent.toolCalled`. A consumer MUST tolerate an unpaired `forbidden` or `rate_limited` return.
154
+
155
+ ## `httpClient`
156
+
157
+ A host advertising `httpClient` MUST advertise `ssrfGuard: true` and a positive `maxResponseBodyBytes`. Before connecting it MUST resolve the target, reject loopback, RFC 1918, link-local and cloud-metadata addresses, and pin the resolved address for the connection (invariant `http-client-ssrf-guard`). `methods` lists the HTTP methods it accepts.
158
+
159
+ A host MAY expose `ctx.http.safeFetch(url, init?)` to pack code under `safeFetch`. It then:
160
+
161
+ - MUST apply that guard, enforce `maxResponseBodyBytes` and any `requestTimeoutMs`, and refuse a connection upgrade;
162
+ - MUST emit the `agent.toolCalled` and `agent.toolReturned` pair (`transport: http`) for every call when it also advertises `toolHooks.prePostEvents`;
163
+ - SHOULD NOT forward an `Authorization` header the pack did not build from a host-issued credential.
164
+
165
+ A host advertising `egressPolicy`, which requires `safeFetch`, attaches a `CredentialProvenance` (never the secret) when it binds a host-issued credential to an egress, and:
166
+
167
+ - MUST emit a content-free `egress.decided`, whose `destination` is the authority alone and whose `reason` is from its closed set;
168
+ - MUST NOT attach the credential to a destination outside its `audiences` (exact host or `*.domain`): the egress is `denied` or, where policy permits, `downgraded`;
169
+ - MUST deny when provenance cannot be evaluated, and MUST NOT attach an expired credential.
170
+
171
+ An egress is `allowed` only when the address guard and the audience check both pass.
172
+
41
173
  ## `workspace`
42
174
 
43
175
  A host advertising `workspace` keeps agent files (`schemas/v2/workspace-file.schema.json`) scoped to one `{tenant, workspace}`; no protocol path is defined for them. The host:
@@ -51,4 +183,20 @@ A host advertising `workspace` keeps agent files (`schemas/v2/workspace-file.sch
51
183
 
52
184
  A workflow calling `ctx.workspace` MUST NOT register on a host without the family. The memory-index manifest is the workspace file `MEMORY-INDEX.json`.
53
185
 
54
- *Sources: RFCs 0059, 0144.*
186
+ ## `memory`
187
+
188
+ A host advertising `memory` serves agent memory (`schemas/v2/memory-entry.schema.json`) to pack code as `ctx.memory`; no protocol path exists. `list` returns `[]` for an unknown ref and `get` returns `null`; writes are host-internal, and a read-only host sets `writable: false`.
189
+
190
+ - **Refs.** `memoryRef` is opaque; a host MUST NOT assume another host's ref resolves. A node MUST guard `ctx.memory`, which may be undefined.
191
+ - **Tenant isolation.** A ref MUST resolve to one tenant's entries, whatever the caller's permissions. A malformed ref (traversal, embedded null, oversize) MUST return `[]` or `null`. An adapter sharing a store MUST gate on the ref's shape, not trust the store. An adapter error MUST NOT carry entry data.
192
+ - **Redaction.** A persisted entry MUST carry `[REDACTED:<secretId>]` in place of any value the run's vault resolved at user, tenant or run scope; platform scope is excluded.
193
+ - **Size and expiry.** A host SHOULD reject a `put` over `maxEntrySizeBytes` with `validation_error`. Under `ttlSupported` or `retention.ttl`, an entry past `expiresAt` MUST NOT surface, purged or not.
194
+ - **Long-term.** A host whose `agents.memoryBackends` includes `long-term` MUST honor isolation, redaction and expiry end to end. A validator MUST NOT look for `memoryBackends` under `memory`.
195
+ - **`search`** advertises query `modes` beyond `list`. **`retention.forget`** is a tenant-scoped delete-by-subject of live memory only; replay reads the recorded snapshot and the log is untouched.
196
+ - **`attribution`.** Under `emitsWriteEvents: true` the host MUST emit a content-free `memory.written` for every memory write a run makes; otherwise a consumer MUST tolerate its absence.
197
+ - **`injectionBudget`** makes `list` honor `tokenBudget`, in `tokenCounter` units; otherwise it is ignored. The host MUST return a prefix of the ranked list within budget, omitting, never truncating, an entry that alone exceeds it, and with `limit` MUST honor whichever yields fewer. `rank: relevance` MUST carry `query` and requires `search` mode `semantic`; otherwise a host MUST reject it or fall back, as documented, to `recency` (the default), never fabricate a ranking. Ranking MUST run over the redacted, single-tenant set.
198
+ - **`compaction`** (`trigger: host-managed`) emits `memory.compacted`. Derived content MUST pass the same redaction as a fresh `put`. A client MUST NOT infer compaction or distillation from entry counts.
199
+ - **`distillation`** is budgeted compaction ([runs.md](runs.md)); an absent budget MUST default to `maxTokenBudget`, counting input and output. A run MUST read the ref's snapshot, MUST NOT re-expose a redacted secret at any recursion level, and MUST write an immutable, addressable archive, byte-stable per source set and budget, kept for `archiveRetention`. Under `indexEmitted` it updates `MEMORY-INDEX.json` (a `.md` sibling MAY accompany it). It emits `memory.compacted` with `distillation` and `trigger: host-managed`. Tenant isolation covers archive and index.
200
+ - **Degraded agents.** When an agent's `memoryShape` needs a dimension the host lacks, its inventory entry MUST set `memoryDegraded` and `degradedMemoryDimensions`; the agent MAY still dispatch. A `role: skill` manifest MUST keep `memoryShape` scratchpad-only, enforced by schema.
201
+
202
+ *Sources: RFCs 0004, 0012, 0017, 0027, 0028, 0029, 0031, 0048, 0052, 0055, 0057, 0059, 0062, 0064, 0067, 0076, 0079, 0080, 0091, 0105, 0106, 0108, 0113, 0116, 0121, 0131, 0144.*
@@ -1,7 +1,7 @@
1
1
  # Identity
2
2
 
3
3
  > **Status: Stable.**
4
- > **Normative home:** `auth`, `authorization`.
4
+ > **Normative home:** `auth`, `authorization`, `anonymousActor`.
5
5
 
6
6
  ## Why this exists
7
7
 
@@ -44,6 +44,19 @@ On fork the host MUST copy `owner` verbatim onto the child: `tenant`, `workspace
44
44
 
45
45
  An end user reaching the host through an A2A peer is `kind: anonymous`, `lane: anonymous`, with the forwarding peer's subject as `actor`. Such a subject MUST NOT be linked.
46
46
 
47
+ ### 1.5 `anonymousActor`
48
+
49
+ A host advertising `anonymousActor` MUST give a run dispatched through a public agent surface, an operator-configured entry point for unauthenticated callers, an anonymous subject.
50
+
51
+ - **The subject.** Its `subjectId` MUST be host-minted, opaque, PII-free and scoped to one surface session. It MUST NOT correlate two sessions or resolve to another subject, workspace or session.
52
+ - **Authority.** Only the surface's explicit tool allowlist. A host MUST NOT resolve a role, scope or default tool baseline for it, or widen it within a session.
53
+ - **`failClosed`.** A call whose grant is absent, unresolvable or errors MUST be denied.
54
+ - **`tiers`.** A host MUST list only tiers it enforces. `read`: tenant-scoped tools with no egress and no secret or BYOK reach. `bounded-write-egress`: writes or egress behind a control, over the SSRF-guarded egress path, attaching a credential only when its audience covers the destination and policy permits anonymous use.
55
+ - **`writeEgressControls`.** REQUIRED iff `bounded-write-egress` is listed, else absent: `hitl` or `rate-limit-session-cap` (a hard rate limit plus a per-session action cap).
56
+ - **Audit.** Every anonymous tool call MUST emit `authorization.decided` carrying no PII or credential. A denial's `reason` is `anon-not-granted`, `anon-write-ungated` or `anon-egress-denied`.
57
+
58
+ `listTools` scoped to the subject reads the effective grant.
59
+
47
60
  ## 2. One binding pipeline, every lane
48
61
 
49
62
  ### 2.1 The pipeline
@@ -54,7 +54,7 @@ Every kind uses two registered types ([events.md](events.md)):
54
54
  - `interrupt.requested` — the payload is the `InterruptPayload` verbatim.
55
55
  - `interrupt.resolved` — the closed payload is `interruptResolved`. Resolving an approval-kind interrupt MUST record the applied `action` there, with the field §Approval requires.
56
56
 
57
- The kind-specific `approval.*` and `clarification.*` types remain registered. Their payload definitions in `schemas/v2/run-event-payloads.schema.json` are `$ref` aliases of `interruptRequested` and `interruptResolved`. A host emitting `interrupt.requested` SHOULD also emit the kind-specific type until its consumers migrate.
57
+ The kind-specific `approval.*` and `clarification.*` types remain registered. Their payload definitions in `schemas/v2/run-event-payloads.schema.json` are `$ref` aliases of `interruptRequested` and `interruptResolved`. A host emitting `interrupt.requested` MAY also emit the kind-specific type.
58
58
 
59
59
  Both events are durable and appear in the `updates` and `debug` stream modes. While suspended, `RunSnapshot.currentNodeId` names the node and `status` is `waiting-approval`, `waiting-input` or `waiting-external`.
60
60
 
@@ -14,10 +14,10 @@
14
14
  4. [`identity.md`](identity.md) — Subject, lanes, `SubjectLink`, id grammars, resume tokens
15
15
  5. [`runs.md`](runs.md) — create, get, cancel, fork; `configurable`; snapshot; owner
16
16
  6. [`events.md`](events.md), [`errors.md`](errors.md), [`headers.md`](headers.md) — event `oneOf`, payload and error registries, `OpenWOP-*` headers
17
- 7. [`interrupt.md`](interrupt.md), [`idempotency.md`](idempotency.md), [`replay.md`](replay.md), [`conversation.md`](conversation.md) — run-side surfaces
17
+ 7. [`interrupt.md`](interrupt.md), [`idempotency.md`](idempotency.md), [`replay.md`](replay.md), [`conversation.md`](conversation.md), [`execution.md`](execution.md) — run-side surfaces
18
18
  8. [`persistence.md`](persistence.md) — era key, v1 reader rule, pinned runs
19
19
  9. [`security-defaults.md`](security-defaults.md), [`webhooks.md`](webhooks.md), [`interop.md`](interop.md), [`host-services.md`](host-services.md), [`storage.md`](storage.md), [`tool-catalog.md`](tool-catalog.md), [`i18n.md`](i18n.md), [`portability.md`](portability.md) — surface obligations, signatures, A2A and MCP, host services, storage, locale, estate export
20
- 10. [`packs.md`](packs.md), [`node-pack-runtimes.md`](node-pack-runtimes.md), [`connection-packs.md`](connection-packs.md), [`form-content-packs.md`](form-content-packs.md), [`workflow-chain-packs.md`](workflow-chain-packs.md) — pack identity, engines ceiling
20
+ 10. [`packs.md`](packs.md), [`node-pack-runtimes.md`](node-pack-runtimes.md), [`connection-packs.md`](connection-packs.md), [`form-content-packs.md`](form-content-packs.md), [`workflow-chain-packs.md`](workflow-chain-packs.md), [`artifact-type-packs.md`](artifact-type-packs.md) — pack identity, engines ceiling
21
21
  11. [`conformance.md`](conformance.md) — requirement ids, witness classes, bundle v3, seams profile
22
22
 
23
23
  ## Axioms in force
@@ -5,7 +5,7 @@
5
5
 
6
6
  ## Why this exists
7
7
 
8
- The v2 contract for pack manifests, the registry tree, peer-dependency identifiers, and signing. The per-kind rules live in [connection-packs.md](connection-packs.md), [form-content-packs.md](form-content-packs.md), and [workflow-chain-packs.md](workflow-chain-packs.md); the capability vocabulary a pack requires is [capabilities.md](capabilities.md).
8
+ The v2 contract for pack manifests, the registry tree, peer-dependency identifiers, and signing. The 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
 
@@ -74,7 +74,7 @@ Suppression is an obligation of the `replay` surface: advertising `replay` binds
74
74
  For a fork with `mode: replay`:
75
75
 
76
76
  1. A node that performs an external side effect — any operation observable outside the run's own event log — MUST NOT perform it.
77
- 2. The host MUST resolve the node's outcome from the source run's recorded terminal outcome keyed on `(sourceRunId, nodeId, n)`, never on the fork's own `runId`, where `n` counts the node's `node.started` events through this execution, including retries, later visits and the fork's inherited prefix.
77
+ 2. The host MUST resolve the node's outcome from the source run's `n`th recorded terminal outcome for the node, keyed on `(sourceRunId, nodeId, n)`, never on the fork's own `runId`, where `n` is one more than the node's `node.completed` and `node.failed` events before this execution, the fork's inherited prefix included.
78
78
  3. Absent a recorded outcome, the host MUST fail the node closed with `replay_source_missing`, MUST NOT perform the effect, and MUST NOT substitute a synthesized or empty success.
79
79
  4. A node whose pack manifest declares `role: "side-effect"` MUST be treated as side-effecting; a host classifier MAY add nodes and MUST NOT remove any. A throwing seam satisfies rule 1 only.
80
80
  5. The guarantee is whole-run and requires both classification before execution and a default-deny guard at every effect seam.
@@ -1,7 +1,7 @@
1
1
  # Runs
2
2
 
3
3
  > **Status: Stable.**
4
- > **Normative home:** `runList`, `limits`, `conversationPrimitive`, `dataResidency`.
4
+ > **Normative home:** `runList`, `limits`, `conversationPrimitive`, `dataResidency`, `deadLetter`.
5
5
 
6
6
  ## Why this exists
7
7
 
@@ -91,11 +91,18 @@ The `201` response is `{ runId, status, eventsUrl, statusUrl? }`. `status` is on
91
91
 
92
92
  ### `run` section
93
93
 
94
- - `recursionLimit` is clamped to `limits.maxNodeExecutions`.
95
- - `runTimeoutMs` resolves to `min(runTimeoutMs, limits.maxRunDurationMs)`. An out-of-range value MUST return `400 validation_error` at create. A breach MUST emit `cap.breached { kind: 'run-duration' }` and terminate the run `failed` with `run_timeout`.
96
- - `maxLoopIterations` resolves against `limits.maxLoopIterations`. A breach MUST emit `cap.breached { kind: 'loop-iterations' }` and fail with `loop_limit_exceeded`.
94
+ - `recursionLimit` is clamped to `limits.maxNodeExecutions`. A breach, counted in node starts, MUST emit `cap.breached { kind: 'node-executions' }` and fail the run with `recursion_limit_exceeded`.
95
+ - `runTimeoutMs` resolves to `min(runTimeoutMs, limits.maxRunDurationMs)`, measured from `run.started`. A breach MUST emit `cap.breached { kind: 'run-duration' }` and terminate the run `failed` with `run_timeout`.
96
+ - `maxLoopIterations` resolves against `limits.maxLoopIterations`, counted in orchestrator turns. A breach MUST emit `cap.breached { kind: 'loop-iterations' }` and fail with `loop_limit_exceeded`.
97
+ - An out-of-range `recursionLimit` or `runTimeoutMs` MUST return `400 validation_error` at create. After a breach the host schedules nothing more.
97
98
  - `escalationThreshold` is the `low-confidence` threshold ([interrupt.md](interrupt.md)).
98
99
 
100
+ ### Limits
101
+
102
+ `limits` always carries `clarificationRounds` (per task), `schemaRounds` (per envelope) and `envelopesPerTurn` (per chat turn). A host advertising `maxNodeExecutions`, `maxRunDurationMs` or `maxLoopIterations` MUST enforce it. On any breach the host MUST emit `cap.breached`, with `nodeId` for `clarification` and `schema`, and fail the node or run. Its `observed` exceeds `limit` and MUST be reused on replay and fork, never recomputed.
103
+
104
+ `budget.maxTokens` and `budget.maxCostUsd` clamp to `maxBudgetTokens` and `maxBudgetCostUsd`. `maxRequestBodyBytes` is the largest REST request body accepted.
105
+
99
106
  ### `ai` section
100
107
 
101
108
  - `provider` MUST be in `aiProviders.providers`, else `400 validation_error`.
@@ -262,8 +269,18 @@ A host advertising `dataResidency` MUST honor-or-reject, and MUST NOT silently a
262
269
 
263
270
  A host that does not advertise `dataResidency` MAY ignore or reject a `residency` constraint, but MUST NOT claim to honor it.
264
271
 
272
+ ## Dead letters
273
+
274
+ A host advertising `deadLetter` MUST, when a run or node exhausts its retry policy:
275
+
276
+ - route it to the dead-letter sink and emit `run.dead-lettered`, whose `reason` is redaction-safe and which carries no credential or payload material;
277
+ - keep the failed run fork-eligible for `retentionDays`, and not purge it sooner;
278
+ - purge it after `retentionDays`, after which a fork fails as for an unknown run.
279
+
280
+ This sink holds runs. Queue messages ([host-services.md](host-services.md) §`queueBus`) and webhook deliveries ([webhooks.md](webhooks.md) §Dead letters) have their own.
281
+
265
282
  ## During the v1 overlap
266
283
 
267
284
  A non-terminal run inherited from v1 continues, or is cancelled `v1_pin_unsupported`, per [persistence.md](persistence.md) §"Runs pinned to v1".
268
285
 
269
- *Sources: RFCs 0170, 0171, 0176, 0182.*
286
+ *Sources: RFCs 0053, 0058, 0084, 0170, 0171, 0176, 0182.*
@@ -99,7 +99,7 @@ An attempt whose request the host had begun sending before `unregisterWebhook` a
99
99
 
100
100
  ### Dead letters
101
101
 
102
- This sink is the delivery sink; the `deadLetter` family is the run sink and is a different thing.
102
+ This sink is the delivery sink; the `deadLetter` family is the run sink ([runs.md](runs.md) §Dead letters) and is a different thing.
103
103
 
104
104
  - A host advertising `webhooks.deadLetter` MUST serve `GET /webhooks/{webhookId}/dead-letters`.
105
105
  - A record MUST NOT carry the delivered body, the delivery headers, or the subscription secret — a dead-letter read names a delivery, it does not replay one.
@@ -206,7 +206,7 @@
206
206
  {
207
207
  "key": "limits",
208
208
  "kind": "family",
209
- "normativeText": ["spec/v2/core/runs.md", "spec/v1/capabilities.md", "spec/v1/budget-policy.md"],
209
+ "normativeText": ["spec/v2/core/runs.md"],
210
210
  "anchor": "core",
211
211
  "section": "core/capabilities.md#limits",
212
212
  "peerDependencyId": "limits",
@@ -269,7 +269,7 @@
269
269
  {
270
270
  "key": "envelopes",
271
271
  "kind": "family",
272
- "normativeText": ["spec/v1/ai-envelope.md", "spec/v2/core/events.md"],
272
+ "normativeText": ["spec/v2/core/events.md"],
273
273
  "anchor": "core",
274
274
  "section": "core/capabilities.md#envelopes",
275
275
  "peerDependencyId": "envelopes",
@@ -290,7 +290,7 @@
290
290
  {
291
291
  "key": "prompts",
292
292
  "kind": "family",
293
- "normativeText": ["spec/v1/prompts.md", "spec/v1/capabilities.md"],
293
+ "normativeText": ["spec/v2/core/host-services.md"],
294
294
  "anchor": "core",
295
295
  "section": "core/capabilities.md#prompts",
296
296
  "peerDependencyId": "prompts",
@@ -343,7 +343,7 @@
343
343
  {
344
344
  "key": "secrets",
345
345
  "kind": "family",
346
- "normativeText": ["spec/v1/host-capabilities.md"],
346
+ "normativeText": ["spec/v2/core/host-services.md"],
347
347
  "anchor": "core",
348
348
  "section": "core/capabilities.md#secrets",
349
349
  "peerDependencyId": "secrets",
@@ -386,7 +386,7 @@
386
386
  {
387
387
  "key": "selfHostedRunner",
388
388
  "kind": "family",
389
- "normativeText": ["spec/v1/capabilities.md"],
389
+ "normativeText": ["spec/v2/core/execution.md"],
390
390
  "anchor": "core",
391
391
  "section": "core/capabilities.md#selfHostedRunner",
392
392
  "peerDependencyId": "selfHostedRunner",
@@ -443,7 +443,7 @@
443
443
  {
444
444
  "key": "anonymousActor",
445
445
  "kind": "family",
446
- "normativeText": ["spec/v1/capabilities.md"],
446
+ "normativeText": ["spec/v2/core/identity.md"],
447
447
  "anchor": "core",
448
448
  "section": "core/capabilities.md#anonymousActor",
449
449
  "peerDependencyId": "anonymousActor",
@@ -486,7 +486,7 @@
486
486
  {
487
487
  "key": "feedback",
488
488
  "kind": "family",
489
- "normativeText": ["spec/v1/observability.md", "spec/v2/core/events.md"],
489
+ "normativeText": ["spec/v2/core/events.md"],
490
490
  "anchor": "core",
491
491
  "section": "core/capabilities.md#feedback",
492
492
  "peerDependencyId": "feedback",
@@ -625,7 +625,7 @@
625
625
  {
626
626
  "key": "multiAgent",
627
627
  "kind": "family",
628
- "normativeText": ["spec/v1/multi-agent-execution.md"],
628
+ "normativeText": ["spec/v2/core/execution.md"],
629
629
  "anchor": "core",
630
630
  "section": "core/capabilities.md#multiAgent",
631
631
  "peerDependencyId": "multiAgent",
@@ -645,7 +645,7 @@
645
645
  {
646
646
  "key": "modelCapabilities",
647
647
  "kind": "family",
648
- "normativeText": ["spec/v1/host-capabilities.md"],
648
+ "normativeText": ["spec/v2/core/host-services.md"],
649
649
  "anchor": "core",
650
650
  "section": "core/capabilities.md#modelCapabilities",
651
651
  "peerDependencyId": "modelCapabilities",
@@ -665,7 +665,7 @@
665
665
  {
666
666
  "key": "providerUsage",
667
667
  "kind": "family",
668
- "normativeText": ["spec/v1/observability.md", "spec/v2/core/events.md"],
668
+ "normativeText": ["spec/v2/core/events.md"],
669
669
  "anchor": "core",
670
670
  "section": "core/capabilities.md#providerUsage",
671
671
  "peerDependencyId": "providerUsage",
@@ -685,7 +685,7 @@
685
685
  {
686
686
  "key": "aiProviders",
687
687
  "kind": "family",
688
- "normativeText": ["spec/v1/host-capabilities.md", "spec/v1/capabilities.md", "spec/v1/ai-envelope.md"],
688
+ "normativeText": ["spec/v2/core/host-services.md"],
689
689
  "anchor": "core",
690
690
  "section": "core/capabilities.md#aiProviders",
691
691
  "peerDependencyId": "aiProviders",
@@ -755,7 +755,7 @@
755
755
  {
756
756
  "key": "memory",
757
757
  "kind": "family",
758
- "normativeText": ["spec/v1/agent-memory.md", "spec/v1/capabilities.md"],
758
+ "normativeText": ["spec/v2/core/host-services.md"],
759
759
  "anchor": "core",
760
760
  "section": "core/capabilities.md#memory",
761
761
  "peerDependencyId": "memory",
@@ -800,7 +800,7 @@
800
800
  {
801
801
  "key": "subWorkflow",
802
802
  "kind": "family",
803
- "normativeText": ["spec/v1/node-packs.md"],
803
+ "normativeText": ["spec/v2/core/execution.md"],
804
804
  "anchor": "core",
805
805
  "section": "core/capabilities.md#subWorkflow",
806
806
  "peerDependencyId": "subWorkflow",
@@ -887,7 +887,7 @@
887
887
  {
888
888
  "key": "queueBus",
889
889
  "kind": "family",
890
- "normativeText": ["spec/v1/host-capabilities.md"],
890
+ "normativeText": ["spec/v2/core/host-services.md"],
891
891
  "anchor": "core",
892
892
  "section": "core/capabilities.md#queueBus",
893
893
  "peerDependencyId": "queueBus",
@@ -908,7 +908,7 @@
908
908
  {
909
909
  "key": "scheduling",
910
910
  "kind": "family",
911
- "normativeText": ["spec/v1/host-capabilities.md"],
911
+ "normativeText": ["spec/v2/core/host-services.md"],
912
912
  "anchor": "core",
913
913
  "section": "core/capabilities.md#scheduling",
914
914
  "peerDependencyId": "scheduling",
@@ -930,7 +930,7 @@
930
930
  {
931
931
  "key": "heartbeat",
932
932
  "kind": "family",
933
- "normativeText": ["spec/v2/core/events.md", "spec/v1/host-capabilities.md"],
933
+ "normativeText": ["spec/v2/core/events.md"],
934
934
  "anchor": "core",
935
935
  "section": "core/capabilities.md#heartbeat",
936
936
  "peerDependencyId": "heartbeat",
@@ -969,7 +969,7 @@
969
969
  "requirementIds": [],
970
970
  "owningRfc": "0064",
971
971
  "normativeText": [
972
- "spec/v1/host-capabilities.md"
972
+ "spec/v2/core/host-services.md"
973
973
  ]
974
974
  },
975
975
  {
@@ -998,7 +998,7 @@
998
998
  {
999
999
  "key": "httpClient",
1000
1000
  "kind": "family",
1001
- "normativeText": ["spec/v1/host-capabilities.md"],
1001
+ "normativeText": ["spec/v2/core/host-services.md"],
1002
1002
  "anchor": "core",
1003
1003
  "section": "core/capabilities.md#httpClient",
1004
1004
  "peerDependencyId": "httpClient",
@@ -1022,7 +1022,7 @@
1022
1022
  {
1023
1023
  "key": "artifactTypes",
1024
1024
  "kind": "family",
1025
- "normativeText": ["spec/v1/artifact-type-packs.md"],
1025
+ "normativeText": ["spec/v2/core/artifact-type-packs.md", "schemas/v2/artifact-type-pack-manifest.schema.json"],
1026
1026
  "anchor": "core",
1027
1027
  "section": "core/capabilities.md#artifactTypes",
1028
1028
  "peerDependencyId": "artifactTypes",
@@ -1118,7 +1118,7 @@
1118
1118
  {
1119
1119
  "key": "deadLetter",
1120
1120
  "kind": "family",
1121
- "normativeText": ["spec/v1/host-capabilities.md"],
1121
+ "normativeText": ["spec/v2/core/runs.md"],
1122
1122
  "anchor": "core",
1123
1123
  "section": "core/capabilities.md#deadLetter",
1124
1124
  "peerDependencyId": "deadLetter",
@@ -1763,7 +1763,7 @@
1763
1763
  "witness": "witnessable-gated",
1764
1764
  "maturity": {
1765
1765
  "technical": "stable",
1766
- "adoption": "single-witness"
1766
+ "adoption": "multi-witness"
1767
1767
  },
1768
1768
  "facets": [
1769
1769
  "conditionalRunGet",
@@ -1966,7 +1966,7 @@
1966
1966
  "witness": "claims-check",
1967
1967
  "maturity": {
1968
1968
  "technical": "stable",
1969
- "adoption": "single-witness"
1969
+ "adoption": "multi-witness"
1970
1970
  },
1971
1971
  "facets": [],
1972
1972
  "floorScenarios": [],
@@ -8,7 +8,7 @@
8
8
  | --- | --- |
9
9
  | **witness:** | `claims-check` |
10
10
  | **technical:** | `stable` |
11
- | **adoption:** | `single-witness` |
11
+ | **adoption:** | `multi-witness` |
12
12
  | **peer-dependency id** | `messaging` |
13
13
  | **advertised as** | `extensions.<org>.messaging` |
14
14
  | **declared facets** | none defined |
@@ -8,7 +8,7 @@
8
8
  | --- | --- |
9
9
  | **witness:** | `witnessable-gated` |
10
10
  | **technical:** | `stable` |
11
- | **adoption:** | `single-witness` |
11
+ | **adoption:** | `multi-witness` |
12
12
  | **peer-dependency id** | `restTransport` |
13
13
  | **advertised as** | `extensions.<org>.rest-transport` |
14
14
  | **declared facets** | `conditionalRunGet`, `contentEncodings` |
@@ -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.44.2",
4
- "corpusTag": "v2.44.2",
5
- "updated": "2026-09-28"
3
+ "version": "2.44.4",
4
+ "corpusTag": "v2.44.4",
5
+ "updated": "2026-09-29"
6
6
  }
@@ -4,7 +4,7 @@
4
4
  "schemas/v2/**/*.json",
5
5
  "spec/v2/path-manifest.json"
6
6
  ],
7
- "release": "2.44.2",
7
+ "release": "2.44.4",
8
8
  "kinds": {
9
9
  "union": [
10
10
  "channel",