@openwop/spec-artifacts 2.44.1 → 2.44.3

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.1",
5
- "corpusTag": "v2.44.1",
4
+ "version": "2.44.3",
5
+ "corpusTag": "v2.44.3",
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": "6f9780f7751804b6dd9f57cb5474728326de805fcca667979f6b4f39c9c97336",
13
- "api/v2/asyncapi.yaml": "ec6520792f7c4661403053003de7669430178597b5e0250ba5264b65dc82dbef",
14
- "api/v2/openapi.yaml": "46314e02c9aeb4cb7a4ca0cfd5997dc24bd11c3971341e505cd0b7bef3150cd8",
12
+ "api/seams-v2.yaml": "3319d19f95c90c82ad611d3698daa77062760aaed9c703000f0eaa93cdcb3ed3",
13
+ "api/v2/asyncapi.yaml": "fc977f137a3a40ac20c17911f9987e55f1b93ab5e73d039e94ab2749537ad4b3",
14
+ "api/v2/openapi.yaml": "353fe2c7b556dfa12f45f85783e0b1409ae3f6e59755719f08ba525b830189ac",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "75d5049dea8bd873ff0e7546f1c60c8d36c219bec7084264360be54a8be30ae1",
@@ -204,50 +204,51 @@
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": "b6efb5d51e1432088bfeff049f310ae0095f3852a59e877e9d628a30782f5580",
207
+ "spec/v1/core-standard-manifest.json": "8789a8c30013d9137db12e2cac6bd38b461a0f16147617366263b26bd265a1d8",
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": "3eb4316a7895eeefd9bb918e496b145d8fc0e39d5cbc5dcc72e2fbefda6803ed",
214
214
  "spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
215
215
  "spec/v1/migrations.json": "2efcd9064b2bc65a84a3b3d281aa86a91efd002690c1f4f14e8335c4a18194d1",
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": "ae7e9dceb3a6a1df75259de43c08244840c8ca8380a3eb4c727ae07dc4bdc4b1",
220
220
  "spec/v2/core/capabilities.md": "ad728e8a761153b55d036ece55043ff62d0982121e2e629e5e7cdf560fca3c03",
221
221
  "spec/v2/core/conformance.md": "0cfceb926eed87055550a5c23e640210c795fc8cf9dd1b2544db0e2b3842c564",
222
222
  "spec/v2/core/connection-packs.md": "1ee129d792c537bfe82393ccb92555d8e6ddc342b1aa781a13f101b27ec38171",
223
223
  "spec/v2/core/conversation.md": "354fa57c73d11062e523a44aa75a6353c5c81aefaf306d30c42416a228c82c86",
224
224
  "spec/v2/core/errors.md": "6d5a67389de84556f81e2558a30d83959c9283c8c5481ce7c759021e486d84fd",
225
- "spec/v2/core/events.md": "604abb6f9e2259a04103e1cb76d728712c3701c0d84dd915d4dc2949c912ee5e",
225
+ "spec/v2/core/events.md": "8a2767691f604b2adf76399edeeaccfc151c697fc9717dc17cf7dd57372a8c22",
226
+ "spec/v2/core/execution.md": "ec1afd30a2b7dab4a722f4502764cb752685e441ecd6ca61e96ed775163be139",
226
227
  "spec/v2/core/form-content-packs.md": "02931227899676fd4581a27017be2a6c4953904717be9b81c29d12f87ab3917d",
227
228
  "spec/v2/core/headers.md": "5cb1624fa63acc81992b6a6d842ec392cf7271aaf2f65d1f83c8c4fa286e6730",
228
- "spec/v2/core/host-services.md": "8b920bf2e9335ab04452068429b0c37d6eb8872b380a4d53368f2600d4afa241",
229
+ "spec/v2/core/host-services.md": "244e222ec6f7d4774751bd3cc124bbc9f548fdd84fabca65c19159ff00d49e84",
229
230
  "spec/v2/core/i18n.md": "2d5a67bd3b9b956d1144acab2fbc3646cdb50b3621f97d772087eaa953798286",
230
231
  "spec/v2/core/idempotency.md": "2084d756789c1faf5121593fb39e67ca36a4c227178e175004742e403178ea49",
231
- "spec/v2/core/identity.md": "2dceb1c2697015e4a4fa8a9b28f4fbd25fa44a76ca5a919c752e2a8163c819db",
232
+ "spec/v2/core/identity.md": "582eddbf2e1bad41911e886bd08524683837045404f7b8f6bceccf61792b2765",
232
233
  "spec/v2/core/interop.md": "e72e25dff864c83b2980d7366b34054cffa072af0225821199f260f6228d260e",
233
234
  "spec/v2/core/interrupt.md": "4c825634acac72900ebd3c5ac5941f55648fa33d2df92913ef16371dcb700a34",
234
235
  "spec/v2/core/node-pack-runtimes.md": "e1088cb69b8c3c67256c494063328916c2980ab1aa97a7063de25bab82fdb1e5",
235
236
  "spec/v2/core/oauth.md": "c96483a44b62978c596945fbb7d7c863cf6056cd980fdb4cf4e97555e3e10b72",
236
- "spec/v2/core/overview.md": "c8c3bedb8e02dd8ce244b8a7a75d23af1c30dc92a343af912489424a89674d70",
237
+ "spec/v2/core/overview.md": "76fdb48ea68de416d6a63ae3b3ec750cafda01d234ea22a1096426fded7b54f3",
237
238
  "spec/v2/core/packs.md": "5929e708bd4e79f6e1beea570af583c80f3b63bb21dec78a5df03c235e73364a",
238
239
  "spec/v2/core/persistence.md": "711874f74cb08b03cd118d683056db10a063517762fcea73ec70feb5d983e6a4",
239
240
  "spec/v2/core/portability.md": "87c4327f674f714fda6217fd79b99d2ba219ad47dc02f9751bb56c200fb2c17a",
240
241
  "spec/v2/core/replay.md": "4d379494057746c6883f6047972e93e621863b998ed291b9a691d3aa57c1ff43",
241
- "spec/v2/core/runs.md": "55e21292ae4b41d0d104199a6c2634ecb3f787c4a671f9ebc37084be38ceef03",
242
+ "spec/v2/core/runs.md": "d0e84ccf7cd7dfa657a8d9a90548dbe1d1f7033be30b405d56c41e36007af977",
242
243
  "spec/v2/core/security-defaults.md": "153884da7a2d54c30c81b5e649cfdef31e151b3a2a19dee1bc5a16c35d60a3aa",
243
244
  "spec/v2/core/storage.md": "598ad4f3775c297c698a20daf72a7d15a6836c1231ddbca5961865c704f765b5",
244
245
  "spec/v2/core/tool-catalog.md": "d16a9004418719c48301804aefa4d7ab6f41112a4ed83727f552aa1b92b418b0",
245
246
  "spec/v2/core/versioning.md": "e3b3ab6d76e51035039a32173e9b412628a52c8fe7b16687ff58a2d0d983faa0",
246
- "spec/v2/core/webhooks.md": "d2d33c6be777f217ade3e15dd369849e5c6ce67e1a4417216f0aa6ec5bdecc56",
247
+ "spec/v2/core/webhooks.md": "3f8730e0d15a5e4244e302adb910a0b6f745fbfa8e80920c14118117811ba881",
247
248
  "spec/v2/core/workflow-chain-packs.md": "fdce7a8477e269950a2bac05ee6eddbd66eb0b670b464d00054f7196ec05d29c",
248
249
  "spec/v2/corrections.json": "59f647f4d22477f6c2b06dcf913b682dde5d51dd5e607a5d0cf648ab60864d6e",
249
250
  "spec/v2/corrections.schema.json": "46bbffb954d13bd9995aebc912ceeb2544f7064331abf25fd6ab85c81a5cec94",
250
- "spec/v2/declaration.json": "56c85c6d49f93d08d3bd48ccf1c049191cfbc4d4c22a1cd5202c1b6252759aca",
251
+ "spec/v2/declaration.json": "25ceb30f1b055afa529c2d822e768498e8c3e95bdc652b5edb2404bf75ac96ee",
251
252
  "spec/v2/declaration.schema.json": "ef951633e4070899f64828f5cf1b5f4870270a0360f81dbb49b5b4d6cd407550",
252
253
  "spec/v2/errors.json": "fa650cbbdf25a140fdaf82ec5269f95b4585ac4bdde1fa6b0b3ffe48a3f7943c",
253
254
  "spec/v2/errors.schema.json": "47404ad53e6147cf9017b813483712466573e419fb33e6c4b6c12d3e7deba1bc",
@@ -299,9 +300,9 @@
299
300
  "spec/v2/path-manifest.json": "17298a245c5da9a70aa7ab0b7f2db4277e06209d6fcdd7187a8b4cea179c08f3",
300
301
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
301
302
  "spec/v2/profiles.json": "180beb9ef2d161766fa23b2987e7e829851e3d316273147cf6a4a3f324befd6b",
302
- "spec/v2/release.json": "af448fd044ab5b990a21945905f109dbbb9b0df9ab7f1105e79aa7d1e0f35a33",
303
+ "spec/v2/release.json": "f84bac4d5066e20022a2f9011a4f7441e74b261f3e41da59990cf52214896478",
303
304
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624",
304
- "spec/v2/surface-baseline.json": "2f79e3283946dd8a401db039109d403b9c386e6b91a4780cbcb1440e8d3a6ffe"
305
+ "spec/v2/surface-baseline.json": "8acb9fab0aca69abfe40dc56fcf48729aaf0d56a41467962e5c7247f3548eea3"
305
306
  },
306
- "corpusCommit": "bf414c875dba212893f0230d44f2b4a2e226311d"
307
+ "corpusCommit": "e8eda2ffa2042f1ab81232cfe4fe5657c9576032"
307
308
  }
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.1
4
+ version: 2.44.3
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.1
4
+ version: 2.44.3
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.1
4
+ version: 2.44.3
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.1",
3
+ "version": "2.44.3",
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": {
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.44.1"
7
+ "version": "2.44.3"
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": "69235de4e9c3b6575530596ba2539d8f042f5f512a8e179ec5f9b239c3a1463e"
424
+ "digest": "c17ddc3aba7cdb7887ebab4effa7a2f263e80fe17e735a7e2878329c4c236285"
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",
package/spec/v2/README.md CHANGED
@@ -31,7 +31,7 @@ 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) |
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
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) |
36
36
  | Reliability | [`errors`](./core/errors.md), [`security defaults`](./core/security-defaults.md), [`conformance`](./core/conformance.md) |
37
37
 
@@ -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,55 @@
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
+ At level 1, a workflow whose `core.orchestrator.supervisor` feeds `core.dispatch` runs this loop:
48
+
49
+ - 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.
50
+ - The loop MUST be re-entrant: replay from any iteration MUST reproduce its state.
51
+ - 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.
52
+ - `output.harvested` fires exactly when a child completes with a non-empty `outputMapping`.
53
+ - A host not advertising `executionModel` MUST NOT emit `core.workflowChain.event`.
54
+
55
+ *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`, `agentRuntime`, `mcp`, `workspace`, `secrets`, `modelCapabilities`, `scheduling`, `queueBus`, `toolHooks`, `httpClient`.
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
 
@@ -38,6 +38,78 @@ Each rejects only for an unknown `serverId` (`not_found`), an MCP error response
38
38
  - `readResource` resolves to the `ReadResourceResult` unaltered.
39
39
  - `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
40
 
41
+ ## `secrets`
42
+
43
+ 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.
44
+
45
+ - `scopes` lists the storage scopes it implements; a client MUST tolerate any subset. `resolution` is `host-managed`.
46
+ - A host offering `resolveInPack` MUST expose `ctx.secrets.resolve({ ref, purpose })`, returning `plaintext` and optional `expiresAt` and `rotatedAt`.
47
+
48
+ For `resolveInPack`, the host:
49
+
50
+ - 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;
51
+ - MUST resolve `ref` only to a credential the calling run may read, fail a `ref` from another workspace, and never substitute another credential.
52
+
53
+ 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.
54
+
55
+ ## `modelCapabilities`
56
+
57
+ `advertised` lists the capability identifiers the active model offers; a host-private identifier MUST be prefixed `x-host-<host>-`.
58
+
59
+ A host advertising `modelCapabilities` that dispatches a node declaring `requiredModelCapabilities` MUST check, then optionally substitute, then emit, then dispatch or refuse:
60
+
61
+ - all met: dispatch;
62
+ - 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;
63
+ - otherwise: emit `model.capability-insufficient` and fail the run `capability_not_provided`.
64
+
65
+ 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.
66
+
67
+ ## `scheduling`
68
+
69
+ 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:
70
+
71
+ - persist it so it survives a restart and fires on time;
72
+ - fire once per tick, never duplicate concurrent runs;
73
+ - reject a fire time beyond `maxFutureHorizon` with `schedule_horizon_exceeded`, whose `details.maxFutureHorizon` SHOULD echo the cap;
74
+ - after missing a tick while down, either fire once on recovery or skip to the next tick, as it documents, never the whole backlog.
75
+
76
+ ## `queueBus`
77
+
78
+ 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`.
79
+
80
+ - A tenant's consumer MUST NOT receive another tenant's messages, even on the same topic.
81
+ - `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)).
82
+ - A workflow triggered by a queue consume MUST get one run per inbound message, with no batching or skipping.
83
+ - The wire shape MUST NOT vary by backend.
84
+
85
+ ## `toolHooks`
86
+
87
+ A host advertising `toolHooks` extends `agent.toolCalled` and `agent.toolReturned` for every external tool call:
88
+
89
+ - **`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.
90
+ - **`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`.
91
+ - **`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"`.
92
+
93
+ 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.
94
+
95
+ ## `httpClient`
96
+
97
+ 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.
98
+
99
+ A host MAY expose `ctx.http.safeFetch(url, init?)` to pack code under `safeFetch`. It then:
100
+
101
+ - MUST apply that guard, enforce `maxResponseBodyBytes` and any `requestTimeoutMs`, and refuse a connection upgrade;
102
+ - MUST emit the `agent.toolCalled` and `agent.toolReturned` pair (`transport: http`) for every call when it also advertises `toolHooks.prePostEvents`;
103
+ - SHOULD NOT forward an `Authorization` header the pack did not build from a host-issued credential.
104
+
105
+ A host advertising `egressPolicy`, which requires `safeFetch`, attaches a `CredentialProvenance` (never the secret) when it binds a host-issued credential to an egress, and:
106
+
107
+ - MUST emit a content-free `egress.decided`, whose `destination` is the authority alone and whose `reason` is from its closed set;
108
+ - MUST NOT attach the credential to a destination outside its `audiences` (exact host or `*.domain`): the egress is `denied` or, where policy permits, `downgraded`;
109
+ - MUST deny when provenance cannot be evaluated, and MUST NOT attach an expired credential.
110
+
111
+ An egress is `allowed` only when the address guard and the audience check both pass.
112
+
41
113
  ## `workspace`
42
114
 
43
115
  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 +123,4 @@ A host advertising `workspace` keeps agent files (`schemas/v2/workspace-file.sch
51
123
 
52
124
  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
125
 
54
- *Sources: RFCs 0059, 0144.*
126
+ *Sources: RFCs 0017, 0031, 0052, 0059, 0064, 0076, 0079, 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
@@ -14,7 +14,7 @@
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
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
@@ -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
 
@@ -262,8 +262,18 @@ A host advertising `dataResidency` MUST honor-or-reject, and MUST NOT silently a
262
262
 
263
263
  A host that does not advertise `dataResidency` MAY ignore or reject a `residency` constraint, but MUST NOT claim to honor it.
264
264
 
265
+ ## Dead letters
266
+
267
+ A host advertising `deadLetter` MUST, when a run or node exhausts its retry policy:
268
+
269
+ - 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;
270
+ - keep the failed run fork-eligible for `retentionDays`, and not purge it sooner;
271
+ - purge it after `retentionDays`, after which a fork fails as for an unknown run.
272
+
273
+ 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.
274
+
265
275
  ## During the v1 overlap
266
276
 
267
277
  A non-terminal run inherited from v1 continues, or is cancelled `v1_pin_unsupported`, per [persistence.md](persistence.md) §"Runs pinned to v1".
268
278
 
269
- *Sources: RFCs 0170, 0171, 0176, 0182.*
279
+ *Sources: RFCs 0053, 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.
@@ -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",
@@ -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",
@@ -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",
@@ -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",
@@ -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.1",
4
- "corpusTag": "v2.44.1",
3
+ "version": "2.44.3",
4
+ "corpusTag": "v2.44.3",
5
5
  "updated": "2026-09-28"
6
6
  }
@@ -4,7 +4,7 @@
4
4
  "schemas/v2/**/*.json",
5
5
  "spec/v2/path-manifest.json"
6
6
  ],
7
- "release": "2.44.1",
7
+ "release": "2.44.3",
8
8
  "kinds": {
9
9
  "union": [
10
10
  "channel",