@openwop/spec-artifacts 2.13.0 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CORPUS-STAMP.json +15 -15
- package/api/seams-v2.yaml +1 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +1 -1
- package/package.json +1 -1
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/gaps.json +51 -0
- package/spec/v2/core/events.md +1 -0
- package/spec/v2/core/identity.md +3 -1
- package/spec/v2/core/interop.md +1 -1
- package/spec/v2/core/runs.md +1 -1
- package/spec/v2/core/security-defaults.md +5 -0
- package/spec/v2/declaration.json +6 -0
- package/spec/v2/release.json +2 -2
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.
|
|
5
|
-
"corpusTag": "v2.
|
|
4
|
+
"version": "2.15.0",
|
|
5
|
+
"corpusTag": "v2.15.0",
|
|
6
6
|
"files": {
|
|
7
7
|
"api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
|
|
8
8
|
"api/asyncapi.yaml": "d5ecb9ee6114582be3b1f662c84bfac9ae96dae7bacb853e461168f70a8e1c7d",
|
|
9
9
|
"api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
|
|
10
10
|
"api/openapi.yaml": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
|
|
11
11
|
"api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
|
|
12
|
-
"api/seams-v2.yaml": "
|
|
13
|
-
"api/v2/asyncapi.yaml": "
|
|
14
|
-
"api/v2/openapi.yaml": "
|
|
12
|
+
"api/seams-v2.yaml": "2d36c5b143c3dbbd7e96f37a3dd135678ea02b3ff8e361ec4b290a21f1c90a59",
|
|
13
|
+
"api/v2/asyncapi.yaml": "3f6f1f023841bb7d33fff2169a38734e10d1ede267d8cef38f8a94e86d317e45",
|
|
14
|
+
"api/v2/openapi.yaml": "808f2519d3fbfaa6efd9563ca2990e5bf80f1fff3fc76945d59ce13708ab3016",
|
|
15
15
|
"api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
|
|
16
16
|
"schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
|
|
17
17
|
"schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
|
|
@@ -201,13 +201,13 @@
|
|
|
201
201
|
"schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
|
|
202
202
|
"spec/v1/alias-detectors.json": "40069d5976eeb6ba1384a648e57e5cfd673db3fce36175115fb8293bee9664d4",
|
|
203
203
|
"spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
|
|
204
|
-
"spec/v1/core-standard-manifest.json": "
|
|
204
|
+
"spec/v1/core-standard-manifest.json": "0478005e74f33a8b5c456805be12b9c34e5e3ab5be80569e007fb616fb29608f",
|
|
205
205
|
"spec/v1/deprecations.json": "307083ce29c23fd406015951f99a30d78d6187ff061d38dc9732f62191b40f3f",
|
|
206
206
|
"spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
|
|
207
207
|
"spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
|
|
208
208
|
"spec/v1/event-codemap.schema.json": "d05933b2e88103aff51a2f774df97b9bda065e0fc88dbd9b114cc47a32189174",
|
|
209
209
|
"spec/v1/extensions.json": "79a60754aa16cbdbdb604f8e5c00038af535a1690a4d07bd5ff7c38f0256a7bc",
|
|
210
|
-
"spec/v1/gaps.json": "
|
|
210
|
+
"spec/v1/gaps.json": "6e7f30b9413f4f57a97583376372a57d32c51a905e544fabf639ef796b78b269",
|
|
211
211
|
"spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
|
|
212
212
|
"spec/v1/migrations.json": "8839497d6a4830b53fa7867014a8336f0d725ef2346352e54fb580b7947897af",
|
|
213
213
|
"spec/v1/migrations.schema.json": "886779aa6c22e646db097f5df210adb018a4dd14a7b815465a18c8a7056c8f72",
|
|
@@ -218,23 +218,23 @@
|
|
|
218
218
|
"spec/v2/core/conformance.md": "a451c0a2ba79d93c55e540ccef480eba7de9602d59bbb03eead05daafde0beac",
|
|
219
219
|
"spec/v2/core/connection-packs.md": "466bdb9dde79d85615ad8281dacfb7bf923ca22d7fb3ed219749e59574c753ed",
|
|
220
220
|
"spec/v2/core/errors.md": "6b6a1480ed889013172d8ce8c6985e321d2f4f73e1d9fae0bac9b961d0dd1a8c",
|
|
221
|
-
"spec/v2/core/events.md": "
|
|
221
|
+
"spec/v2/core/events.md": "2fbf98662a72035afd7a3f811c30d4fe5f0ac823488a2cc9198a61cf6d27a049",
|
|
222
222
|
"spec/v2/core/form-content-packs.md": "af3517dd7125106088249c0e32220b0b9fc3e9304c10378a6327cc8ad84b6bf1",
|
|
223
223
|
"spec/v2/core/headers.md": "14cdf4ae9ee7d80eebfd426d7c3552e577baea0300915cd4bb3a68e8588195a8",
|
|
224
224
|
"spec/v2/core/idempotency.md": "e4edae1834101fd331379d84de77eaa9cead49383529c31f8bcd18322f67c965",
|
|
225
|
-
"spec/v2/core/identity.md": "
|
|
226
|
-
"spec/v2/core/interop.md": "
|
|
225
|
+
"spec/v2/core/identity.md": "e44f34f7c2db1f12babb19ca8ee1e5b1401a89f38fd5c90d0c4b74c95f6e5d42",
|
|
226
|
+
"spec/v2/core/interop.md": "6bd581556b9ab1a1509c01b9a1ec2bcb9e4a8300e68fb01570704417e70f20b9",
|
|
227
227
|
"spec/v2/core/interrupt.md": "3a926d84b942d4ee7daccc4443c93dc29f6a69f2936ba813182f2c1336db2cbb",
|
|
228
228
|
"spec/v2/core/overview.md": "7dc00ace32d4e4ce929a383651f0029fc4b7091ec87487b1bf26ead1be209e0e",
|
|
229
229
|
"spec/v2/core/packs.md": "cc06de2d49dd08410eececd5c279996ec839680553b332b4f33d6b31989b5757",
|
|
230
230
|
"spec/v2/core/persistence.md": "9e241f84259e38848f4a2ad1c21debb0dffd5f8aafbad26408aa6cc8969bf93b",
|
|
231
231
|
"spec/v2/core/replay.md": "10cc01bf9e4e921fcfac740f3174b2e95cda7ba9a1e13e85cf371c8c2d0fa46a",
|
|
232
|
-
"spec/v2/core/runs.md": "
|
|
233
|
-
"spec/v2/core/security-defaults.md": "
|
|
232
|
+
"spec/v2/core/runs.md": "f7641c111a3d6ce225656732515cf2fbd38f1c1455b39ee744a4fd2ad09ba379",
|
|
233
|
+
"spec/v2/core/security-defaults.md": "5c32c0bf4b47975c1428361b225a066cd3966cb37b023ca70bc30152fcbec33b",
|
|
234
234
|
"spec/v2/core/versioning.md": "27b88cde88f9060567ef7e46f4897b6be8892ade9f4a46c2ab16e314c515eabd",
|
|
235
235
|
"spec/v2/core/webhooks.md": "46c1311c1897236f9bf9db5025c8af31dd84cd19208da3e5e9ff69eec9436965",
|
|
236
236
|
"spec/v2/core/workflow-chain-packs.md": "df78b76dd79f2267fb6b72c08e0911e5f9d5bb1925c6efdd6deda62fe8a51dc8",
|
|
237
|
-
"spec/v2/declaration.json": "
|
|
237
|
+
"spec/v2/declaration.json": "1e47c155ab36bf0520c759c3aa3e67d2e3737d28a6c6a538cd281bb5a9930b13",
|
|
238
238
|
"spec/v2/declaration.schema.json": "c86e3083fb9789c1958ecb4576cc6f71aa90e6f339521139238543ed08211dd4",
|
|
239
239
|
"spec/v2/errors.json": "aac91b12f954cc90574d310070ae3c651b131055d4389d2c6155242763765195",
|
|
240
240
|
"spec/v2/event-codemap.json": "37869a03cdfd8758b57e6f350641a6ebbd383231cebda51f5473ad85f94ab74c",
|
|
@@ -274,8 +274,8 @@
|
|
|
274
274
|
"spec/v2/path-manifest.json": "c123c9fd77dc1b3f9c2e9346ace80cdae007e6511138894956abda01e61ec1c6",
|
|
275
275
|
"spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
|
|
276
276
|
"spec/v2/profiles.json": "0636f19fceae625390003a347e70ef4797d84766b5c24ce8a02cea52aadebca4",
|
|
277
|
-
"spec/v2/release.json": "
|
|
277
|
+
"spec/v2/release.json": "172c377ac413214f0d0ce857fdaf030526fd1085434b69e3b755e088b5be08f9",
|
|
278
278
|
"spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
|
|
279
279
|
},
|
|
280
|
-
"corpusCommit": "
|
|
280
|
+
"corpusCommit": "a60d21de057c9a096e960c13fb0d83950e037e24"
|
|
281
281
|
}
|
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.
|
|
4
|
+
version: 2.15.0
|
|
5
5
|
description: 'GENERATED by scripts/derive-v2-api.py. RFC 0168 §C: the seams are a versioned conformance profile with their
|
|
6
6
|
own document and path space (/conformance/seams/…), validated against the canonical v2 schemas with no tolerance path,
|
|
7
7
|
forbidden from the capability namespace (a host advertises the profile, never a testSeams flag). This document carries
|
package/api/v2/asyncapi.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
asyncapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: OpenWOP v2 event streams
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.15.0
|
|
5
5
|
description: GENERATED by scripts/derive-v2-api.py (RFC 0171 §E.1, RFC 0172 §C.2). One run-events channel whose address
|
|
6
6
|
is the OpenAPI path key; the server pathname is empty (bare origin). streamMode is a pattern over the closed set and its
|
|
7
7
|
comma-separated combinations (`values` never combines). hostEvents has a real address (RFC 0171 §E.1) — the documented
|
package/api/v2/openapi.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: OpenWOP v2 API
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.15.0
|
|
5
5
|
summary: REST surface for declaring, executing, suspending, resuming, and observing multi-step workflows.
|
|
6
6
|
description: GENERATED by scripts/derive-v2-api.py from api/openapi.yaml and the RFC 0167 children (v2 charter Phase 3,
|
|
7
7
|
P3-C). Bare origin, unversioned path keys, negotiation by `OpenWOP-Version` + `protocolVersions[]` (RFC 0172 §A). No seam
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/spec-artifacts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"description": "The OpenWOP machine-readable contract: api/ (OpenAPI, AsyncAPI, the seams profile), schemas/ (v1 and v2 JSON Schemas), the spec/v1 and spec/v2 registries (errors, event codemap, declaration, deprecations, migrations, gaps) and CORPUS-STAMP.json — published from the openwop/openwop corpus tag; the peer dependency @openwop/openwop-conformance digest-checks at start (RFC 0168 §D.2).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"provenance": {
|
|
5
5
|
"suite": {
|
|
6
6
|
"package": "@openwop/openwop-conformance",
|
|
7
|
-
"version": "2.
|
|
7
|
+
"version": "2.15.0"
|
|
8
8
|
},
|
|
9
9
|
"note": "Derived from the corpus at generation time. Regenerate with --write; verify with --check."
|
|
10
10
|
},
|
|
@@ -419,5 +419,5 @@
|
|
|
419
419
|
"$id": "https://openwop.dev/spec/v1/workspace-file.schema.json"
|
|
420
420
|
}
|
|
421
421
|
],
|
|
422
|
-
"digest": "
|
|
422
|
+
"digest": "4ff5b4a569f1ff03c71f0aec32ce5cb443cb4129a8d8cf5753c7808bd48afe58"
|
|
423
423
|
}
|
package/spec/v1/gaps.json
CHANGED
|
@@ -10365,6 +10365,57 @@
|
|
|
10365
10365
|
}
|
|
10366
10366
|
]
|
|
10367
10367
|
},
|
|
10368
|
+
{
|
|
10369
|
+
"id": "openwop.gap.0189.5",
|
|
10370
|
+
"rfc": "0189",
|
|
10371
|
+
"local": "G5",
|
|
10372
|
+
"section": "§B(b)/(c)",
|
|
10373
|
+
"surface": "`-`, `_`, `.` and `/` are not word boundaries for a family key, but `namesKey` treated every non-alphanumeric as one — so a key was \"named\" by any token merely CONTAINING it. Measured at 2.13.0, six of the twenty families that satisfied §B(c) did so ONLY through this: `fs` ← \"nodes are `fs-gated`\"; `budget` ← `token_budget_exceeded`; `i18n` ← \"see i18n.md\"; `portability` ← the path `spec/v2/ext/portability/`; `workspace` ← `RunSnapshot.owner.workspace`. A further five matched through plain English homonyms (`cache` the verb, `production` the adjective, `content` in `content-free`).",
|
|
10374
|
+
"witness": "unclassified",
|
|
10375
|
+
"requirementId": null,
|
|
10376
|
+
"disposition": "closed",
|
|
10377
|
+
"target": null,
|
|
10378
|
+
"sources": [
|
|
10379
|
+
{
|
|
10380
|
+
"file": "RFCS/registers/0189-normative-home.gaps.md",
|
|
10381
|
+
"token": "G5"
|
|
10382
|
+
}
|
|
10383
|
+
]
|
|
10384
|
+
},
|
|
10385
|
+
{
|
|
10386
|
+
"id": "openwop.gap.0189.6",
|
|
10387
|
+
"rfc": "0189",
|
|
10388
|
+
"local": "G6",
|
|
10389
|
+
"section": "§B.4",
|
|
10390
|
+
"surface": "`namesFacet`'s qualified form kept the FAMILY key's leading-boundary requirement, so it matched `limits.maxBudgetTokens` but not `Capabilities.limits.maxBudgetTokens` — the canonical spelling in v1 prose. `spec/v1/budget-policy.md` clamps to \"the host ceiling (`Capabilities.limits.maxBudgetTokens` / `maxBudgetCostUsd`)\": one sentence, a coordinated pair, and the gate covered the second and missed the first. G5's own closure note stated the intent correctly — *facet coverage takes the mirror rule* — but the implementation applied a family rule to a facet.",
|
|
10391
|
+
"witness": "unclassified",
|
|
10392
|
+
"requirementId": null,
|
|
10393
|
+
"disposition": "closed",
|
|
10394
|
+
"target": null,
|
|
10395
|
+
"sources": [
|
|
10396
|
+
{
|
|
10397
|
+
"file": "RFCS/registers/0189-normative-home.gaps.md",
|
|
10398
|
+
"token": "G6"
|
|
10399
|
+
}
|
|
10400
|
+
]
|
|
10401
|
+
},
|
|
10402
|
+
{
|
|
10403
|
+
"id": "openwop.gap.0189.7",
|
|
10404
|
+
"rfc": "0189",
|
|
10405
|
+
"local": "G7",
|
|
10406
|
+
"section": "§D",
|
|
10407
|
+
"surface": "The end-of-support fallback tested the banner's STATE (a regex matching `Stable` or `FINAL`) rather than whether it CHANGED — and §D's own words are \"deleted or its `Status:` banner changes\". The two differ, and the difference was already live: `spec/v1/multi-agent-execution.md` has read `Status: Draft` since long before `multiAgent` was carried into it in 2.13.0, so on 2026-12-04 the daily job would have gone permanently red on a banner that never changed. Introduced by RFC 0190 §C, which implemented the fallback that RFC 0189 had only printed — one layer down from the defect it was fixing.",
|
|
10408
|
+
"witness": "unclassified",
|
|
10409
|
+
"requirementId": null,
|
|
10410
|
+
"disposition": "closed",
|
|
10411
|
+
"target": null,
|
|
10412
|
+
"sources": [
|
|
10413
|
+
{
|
|
10414
|
+
"file": "RFCS/registers/0189-normative-home.gaps.md",
|
|
10415
|
+
"token": "G7"
|
|
10416
|
+
}
|
|
10417
|
+
]
|
|
10418
|
+
},
|
|
10368
10419
|
{
|
|
10369
10420
|
"id": "openwop.gap.0190.1",
|
|
10370
10421
|
"rfc": "0190",
|
package/spec/v2/core/events.md
CHANGED
package/spec/v2/core/identity.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Identity
|
|
2
2
|
|
|
3
3
|
> **Status: Stable · RFC 0170, 0165, 0176.**
|
|
4
|
-
> **Normative home:** `auth`.
|
|
4
|
+
> **Normative home:** `auth`, `authorization`.
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
@@ -43,6 +43,8 @@ An end user reaching the host through an A2A peer is `kind: anonymous`, `lane: a
|
|
|
43
43
|
|
|
44
44
|
Every lane MUST: verify the credential against the lane's trust root; bind the verified identity to the request, never to an asserted header; check audience; resolve to a Subject before any authorization decision; and fail closed. The closed reason vocabulary is the family-wide error set in §6. Every lane is advertised as one member of the `auth.lanes[]` facet (`spec/v2/facets/auth.schema.json`):
|
|
45
45
|
|
|
46
|
+
`authorization.failClosed` advertises that rule and MUST be `true` when present; it does not gate it (invariant `authorization-fail-closed`). `authorization.roles` is the host role catalog: a request is authorized when any role-derived scope matches the required scope, under the same scope-match semantics this document applies to a credential.
|
|
47
|
+
|
|
46
48
|
```json
|
|
47
49
|
{ "lane": "oidc", "issuers": ["https://idp.example"], "revocation": "exp-and-recheck",
|
|
48
50
|
"revocationWindowSeconds": 300, "minimumAssurance": "sender-constrained",
|
package/spec/v2/core/interop.md
CHANGED
|
@@ -13,7 +13,7 @@ REST and SSE are the wire. A host MUST NOT advertise a transport list; `supporte
|
|
|
13
13
|
|
|
14
14
|
## The facets
|
|
15
15
|
|
|
16
|
-
A host that speaks either protocol MUST advertise the corresponding facet with every required field (`spec/v2/facets/a2a.schema.json`, `spec/v2/facets/mcp.schema.json`).
|
|
16
|
+
A host that speaks either protocol MUST advertise the corresponding facet — `a2a` or `mcp` — with every required field (`spec/v2/facets/a2a.schema.json`, `spec/v2/facets/mcp.schema.json`).
|
|
17
17
|
|
|
18
18
|
| Facet field | A2A (`a2a`) | MCP (`mcp`) | Rule |
|
|
19
19
|
| --- | --- | --- | --- |
|
package/spec/v2/core/runs.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Security Defaults
|
|
2
2
|
|
|
3
3
|
> **Status: Stable · RFC 0173 (§A–§E), 0164 §22, 0170 §B.**
|
|
4
|
+
> **Normative home:** `sandbox`, `compensation`.
|
|
4
5
|
|
|
5
6
|
## Why this exists
|
|
6
7
|
|
|
@@ -45,10 +46,14 @@ A host that surfaces `approversList`, or advertises `refKinds` including `group`
|
|
|
45
46
|
|
|
46
47
|
A host that executes third-party packs MUST enforce the eight `node-pack-sandbox-*` invariants of `SECURITY/invariants.yaml` (`no-process`, `network-gated`, `fs-gated`, `no-env`, `timeout`, `memory-cap`, `isolated-context`, `no-eval`) and MUST advertise `sandbox.isolationModel ∈ wasm | process | container | vm` (`spec/v2/facets/sandbox.schema.json`). `node:vm` is not a value. A host that cannot isolate MUST NOT execute third-party packs; it MAY register and validate them. The `no-eval` row stays reference-impl in `ext/sandbox-runtime-notes` (§D.1). The `pack-isolation` scenario drives the eight legs.
|
|
47
48
|
|
|
49
|
+
The remaining `sandbox` facets name the bound each invariant already carries: `allowedHostCalls` is the host-call allowlist `network-gated` and `fs-gated` enforce, `memoryLimitBytes` is the ceiling of `memory-cap`, and `wallClockLimitMs` is the ceiling of `timeout`. An advertised bound MUST be enforced; none of the three gates the invariant, which binds whether or not the facet is advertised.
|
|
50
|
+
|
|
48
51
|
### Compensation
|
|
49
52
|
|
|
50
53
|
A host that advertises `compensation` MUST serve `GET /runs/{runId}/compensation` (`schemas/v2/compensation-projection.schema.json`): `{ runId, status, plan[], attempts[] }`, the plan carrying `{ nodeId, order, policy?, irreversibleEffect? }` and each attempt `{ nodeId, attempt, outcome, at, reason? }`, keyed on the node and attempt the operator family uses. The trichotomy of §D.1 resolves to core obligation with a declared witness; a host that does not advertise `compensation` has no obligation.
|
|
51
54
|
|
|
55
|
+
The facets bind the policy shape (`schemas/v2/compensation-policy.schema.json`): `compensation.orderingModels` MUST list `reverse-completion` and MAY add `dependency-graph`, and a policy naming a model outside it MUST be refused at registration; `compensation.profileVersion` participates in the inverse-action identity, so a policy naming a different one MUST be refused; `compensation.manualIntervention` is the `manual` status above — a host advertising it records the unwind rather than abandoning it.
|
|
56
|
+
|
|
52
57
|
### Layer-2 effect identity
|
|
53
58
|
|
|
54
59
|
A host that advertises `idempotency` MUST assign a logical effect id once per effect, stable across transport retries, and MUST inject it as the provider's idempotency key (RFC 0150 §B). Where a provider exposes no business key, the v1 activity recipe is the documented fallback. `GET /runs/{runId}/effects` (`schemas/v2/effect-ledger-projection.schema.json`) serves `{ runId, effects[] }`, each `{ effectId, nodeId, attempt, invocationId?, keying: business-identity | activity-recipe, providerKey?, state: claimed | completed | released | escaped, at }`, content-free of provider payloads. Layer-2 retention MUST be at least 14 days (RFC 0170 §D.3). No deployed history holds a v1 recipe key, so no dual-read migration exists (RFC 0147 UQ2).
|
package/spec/v2/declaration.json
CHANGED
|
@@ -205,6 +205,7 @@
|
|
|
205
205
|
{
|
|
206
206
|
"key": "limits",
|
|
207
207
|
"kind": "family",
|
|
208
|
+
"normativeText": ["spec/v2/core/runs.md", "spec/v1/capabilities.md", "spec/v1/budget-policy.md"],
|
|
208
209
|
"anchor": "core",
|
|
209
210
|
"section": "core/capabilities.md#limits",
|
|
210
211
|
"peerDependencyId": "limits",
|
|
@@ -516,6 +517,7 @@
|
|
|
516
517
|
{
|
|
517
518
|
"key": "oauth",
|
|
518
519
|
"kind": "family",
|
|
520
|
+
"normativeText": ["spec/v1/host-capabilities.md"],
|
|
519
521
|
"anchor": "core",
|
|
520
522
|
"section": "core/capabilities.md#oauth",
|
|
521
523
|
"peerDependencyId": "oauth",
|
|
@@ -535,6 +537,7 @@
|
|
|
535
537
|
{
|
|
536
538
|
"key": "authorization",
|
|
537
539
|
"kind": "family",
|
|
540
|
+
"normativeText": ["spec/v2/core/identity.md"],
|
|
538
541
|
"anchor": "core",
|
|
539
542
|
"section": "core/capabilities.md#authorization",
|
|
540
543
|
"peerDependencyId": "authorization",
|
|
@@ -897,6 +900,7 @@
|
|
|
897
900
|
{
|
|
898
901
|
"key": "heartbeat",
|
|
899
902
|
"kind": "family",
|
|
903
|
+
"normativeText": ["spec/v2/core/events.md", "spec/v1/host-capabilities.md"],
|
|
900
904
|
"anchor": "core",
|
|
901
905
|
"section": "core/capabilities.md#heartbeat",
|
|
902
906
|
"peerDependencyId": "heartbeat",
|
|
@@ -1437,6 +1441,7 @@
|
|
|
1437
1441
|
{
|
|
1438
1442
|
"key": "sandbox",
|
|
1439
1443
|
"kind": "family",
|
|
1444
|
+
"normativeText": ["spec/v2/core/security-defaults.md"],
|
|
1440
1445
|
"anchor": "core",
|
|
1441
1446
|
"section": "core/capabilities.md#sandbox",
|
|
1442
1447
|
"peerDependencyId": "sandbox",
|
|
@@ -1461,6 +1466,7 @@
|
|
|
1461
1466
|
{
|
|
1462
1467
|
"key": "compensation",
|
|
1463
1468
|
"kind": "family",
|
|
1469
|
+
"normativeText": ["spec/v2/core/security-defaults.md"],
|
|
1464
1470
|
"anchor": "core",
|
|
1465
1471
|
"section": "core/capabilities.md#compensation",
|
|
1466
1472
|
"peerDependencyId": "compensation",
|
package/spec/v2/release.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "RFC 0172 §D.1 — the one release identity the v2 artifacts derive from. `version` is the next corpus tag `v<version>` (the publish workflow's coordinated-release tag pattern `v*`; RFC 0172's `openwop/v2.<minor>.<patch>` spelling is amended to this at its flip). api/v2/*.yaml info.version, the suite's 2.x version and @openwop/spec-artifacts read it. Bumped by the release PR that cuts the tag, never by hand elsewhere.",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"corpusTag": "v2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
|
+
"corpusTag": "v2.15.0",
|
|
5
5
|
"updated": "2026-09-18"
|
|
6
6
|
}
|