@openwop/spec-artifacts 2.15.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CORPUS-STAMP.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "_comment": "Provenance of @openwop/spec-artifacts (RFC 0168 §D.2). files: SHA-256 per file; the conformance suite compares the installed peer against dist/spec-artifacts.lock.json at start.",
3
3
  "package": "@openwop/spec-artifacts",
4
- "version": "2.15.0",
5
- "corpusTag": "v2.15.0",
4
+ "version": "2.16.0",
5
+ "corpusTag": "v2.16.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": "2d36c5b143c3dbbd7e96f37a3dd135678ea02b3ff8e361ec4b290a21f1c90a59",
13
- "api/v2/asyncapi.yaml": "3f6f1f023841bb7d33fff2169a38734e10d1ede267d8cef38f8a94e86d317e45",
14
- "api/v2/openapi.yaml": "808f2519d3fbfaa6efd9563ca2990e5bf80f1fff3fc76945d59ce13708ab3016",
12
+ "api/seams-v2.yaml": "46bc549d6de6a8fa0a53f43e09249cd3e18936eecb114e1836e93e3ea8f1f5ea",
13
+ "api/v2/asyncapi.yaml": "c2e3abf4ee265d494fe38bca4b2148bc86e2a9520d61f8aec4b771cec08a699e",
14
+ "api/v2/openapi.yaml": "719478209c8a296f5d756010da2b5eeb1d058635253427148ca3f02598cb413c",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
@@ -115,7 +115,7 @@
115
115
  "schemas/v2/artifact-type-pack-manifest.schema.json": "85630d1b760d0b41cf5a6fad2acfada39abaf7f0befd95cc4334e1e883e9615d",
116
116
  "schemas/v2/audit-verify-result.schema.json": "a748dfadb5155adfde8a91045e76b0db6695005fe559035d71670fdd55edb3ba",
117
117
  "schemas/v2/budget-policy.schema.json": "c7449daeb6e1d95e7a047b8c2814d3d54748697c27046972834874867d9b5f4c",
118
- "schemas/v2/capabilities.schema.json": "ae1ece0c55cf467f11fe54d1374b42a249db57d8d69e45afc6f8d40e3712ca90",
118
+ "schemas/v2/capabilities.schema.json": "213c5cbe7ae7a337418c9183ed8ec39f1bc4dc39650a9b3c06cea9780dca3f24",
119
119
  "schemas/v2/certification-bundle.schema.json": "0bcf8f297266505ca39d30eea8100e3c0fb048f2651717fd746da8129fcb7920",
120
120
  "schemas/v2/channel-presence-payload.schema.json": "1c20ad810cb311d47aa0b95d928490826b2468fd161f884cd29e867053e6782f",
121
121
  "schemas/v2/channel-written-payload.schema.json": "ccecff3c71a3275ad8db035ac0e04db25e6f8d23cf091ddbcd5a60d1be1cbb6b",
@@ -201,20 +201,20 @@
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": "0478005e74f33a8b5c456805be12b9c34e5e3ab5be80569e007fb616fb29608f",
204
+ "spec/v1/core-standard-manifest.json": "e0cdcba53adf7cecf24fc64b69a58306fdea74b2830338a292927315ad4c355c",
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": "6e7f30b9413f4f57a97583376372a57d32c51a905e544fabf639ef796b78b269",
210
+ "spec/v1/gaps.json": "9d56a0eb3edde8daea94220343d8a784beebebf324ff3664163a56aa68a29876",
211
211
  "spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
212
212
  "spec/v1/migrations.json": "8839497d6a4830b53fa7867014a8336f0d725ef2346352e54fb580b7947897af",
213
213
  "spec/v1/migrations.schema.json": "886779aa6c22e646db097f5df210adb018a4dd14a7b815465a18c8a7056c8f72",
214
214
  "spec/v1/operation-path-manifest.json": "5f5f4e3842669371730ebbd1aace3fb794192615f0018dc144f484ba5db82ac3",
215
215
  "spec/v1/spec-gaps.json": "eb3bfcb9c7d05c9a6845d4a40ec9493cfaa5a671932daf1af561310136fdabe8",
216
216
  "spec/v2/README.md": "8dbfc17b10f373dba95bdd2e8fec0580f35b380a834d304be3e24e7498170185",
217
- "spec/v2/core/capabilities.md": "9e81d578e177f9875499677d22207df909e59e3d4ddaa3d90f18a7035cfb31f4",
217
+ "spec/v2/core/capabilities.md": "b3977e799d1d16c6ef9b306d5f07341f52259c19171c02c273a7e8a7a4b34473",
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",
@@ -264,18 +264,18 @@
264
264
  "spec/v2/facets/heartbeat.schema.json": "81d7fa1895a8b0241bd07cf00a7e7905bef0fd14eb3427325261c62eee5746a6",
265
265
  "spec/v2/facets/interrupt.schema.json": "c76c58c0abd99de619f8c8afad246568f5bc9cce3b7a0d097d16d87eba84be3a",
266
266
  "spec/v2/facets/mcp.schema.json": "f56609fe24ba6160ad29ae31aa16043354ff005e5cb6a0f3871c4d226087cc08",
267
- "spec/v2/facets/packs.schema.json": "fc8307f9230d4c2a780912bc4e506c92cc26b78d3e7fdd63418b3e7df2b365bd",
267
+ "spec/v2/facets/packs.schema.json": "d544a280419c0052ce0f3c3b378f7aa04085cadc31df52a3c8f43da600b131b1",
268
268
  "spec/v2/facets/replay.schema.json": "0a5aefb0108c708c6794fadd533cf256709704c4f16dbf44cd63fa8980c78018",
269
269
  "spec/v2/facets/runList.schema.json": "6223e1baaebbb9f4faa71bfe968f8d22b4aa88046d0e43e8d5f56409e7f86e90",
270
270
  "spec/v2/facets/sandbox.schema.json": "e75f54486d387b2d089791aa93b5093cd1450f1920753a0f97fc23acdfe978ed",
271
271
  "spec/v2/facets/webhooks.schema.json": "4bf3f8eb3161a43910efac4c44ccaf9567060c9da52d4cf09bcf3888d1b92192",
272
- "spec/v2/facets/workflowChainPacks.schema.json": "3c8786b91afb7a4477cb082f1b914438b901ce1c16512d001f3c83557d859687",
272
+ "spec/v2/facets/workflowChainPacks.schema.json": "cd30907ac92396866a524e4db8d8c1537e3818cfff455d780efd72bcd0ebdac1",
273
273
  "spec/v2/id-field-bindings.json": "e73c06f3055ad30173507ac817a458b96362c8f26209ba105c53653292cf63d3",
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": "172c377ac413214f0d0ce857fdaf030526fd1085434b69e3b755e088b5be08f9",
277
+ "spec/v2/release.json": "c7d72623c4045035f3a700b45e4ab7e0f41f2828135a0ea4de597c9a92efc219",
278
278
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
279
279
  },
280
- "corpusCommit": "a60d21de057c9a096e960c13fb0d83950e037e24"
280
+ "corpusCommit": "3ec0076d1f6f317f24bd204c89a03bb1920818d0"
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.15.0
4
+ version: 2.16.0
5
5
  description: 'GENERATED by scripts/derive-v2-api.py. RFC 0168 §C: the seams are a versioned conformance profile with their
6
6
  own document and path space (/conformance/seams/…), validated against the canonical v2 schemas with no tolerance path,
7
7
  forbidden from the capability namespace (a host advertises the profile, never a testSeams flag). This document carries
@@ -1,7 +1,7 @@
1
1
  asyncapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 event streams
4
- version: 2.15.0
4
+ version: 2.16.0
5
5
  description: GENERATED by scripts/derive-v2-api.py (RFC 0171 §E.1, RFC 0172 §C.2). One run-events channel whose address
6
6
  is the OpenAPI path key; the server pathname is empty (bare origin). streamMode is a pattern over the closed set and its
7
7
  comma-separated combinations (`values` never combines). hostEvents has a real address (RFC 0171 §E.1) — the documented
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: OpenWOP v2 API
4
- version: 2.15.0
4
+ version: 2.16.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.15.0",
3
+ "version": "2.16.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": {
@@ -458,7 +458,10 @@
458
458
  "required": [
459
459
  "status",
460
460
  "since",
461
- "witness"
461
+ "witness",
462
+ "clarificationRounds",
463
+ "schemaRounds",
464
+ "envelopesPerTurn"
462
465
  ],
463
466
  "properties": {
464
467
  "status": {
@@ -649,7 +652,8 @@
649
652
  "required": [
650
653
  "status",
651
654
  "since",
652
- "witness"
655
+ "witness",
656
+ "advertised"
653
657
  ],
654
658
  "properties": {
655
659
  "status": {
@@ -782,7 +786,7 @@
782
786
  "reliability": {
783
787
  "type": "object",
784
788
  "additionalProperties": false,
785
- "description": "RFC 0032 §C. Host emits the envelope-reliability event family on documented adverse paths. Hosts opt into the family via `supported: true` AND explicitly list the events they emit via `events[]`. Hosts that advertise `supported: true` MUST include at least `envelope.retry.exhausted` and `envelope.refusal` in `events[]` (the two MUST-tier events). The other four (`envelope.retry.attempted`, `envelope.truncated`, `envelope.nlToFormat.engaged`, `envelope.recovery.applied`) are SHOULD/MAY-tier per RFC 0032 §B and may be omitted.",
789
+ "description": "RFC 0032 §C. Host emits the envelope-reliability event family on documented adverse paths. Hosts advertise the family by emitting the record AND explicitly list the events they emit via `events[]`. A host advertising this facet MUST include at least `envelope.retry.exhausted` and `envelope.refusal` in `events[]` (the two MUST-tier events). The other four (`envelope.retry.attempted`, `envelope.truncated`, `envelope.nlToFormat.engaged`, `envelope.recovery.applied`) are SHOULD/MAY-tier per RFC 0032 §B and may be omitted.",
786
790
  "properties": {
787
791
  "events": {
788
792
  "type": "array",
@@ -798,7 +802,7 @@
798
802
  ]
799
803
  },
800
804
  "uniqueItems": true,
801
- "description": "Subset of the six reliability events the host actually emits. Hosts that advertise `supported: true` MUST include `envelope.retry.exhausted` and `envelope.refusal`. Conformance scenarios soft-skip for events absent from this list (the event-emission assertion is skipped; other host behavior assertions remain in force)."
805
+ "description": "Subset of the six reliability events the host actually emits. A host advertising this facet MUST include `envelope.retry.exhausted` and `envelope.refusal`. Conformance scenarios soft-skip for events absent from this list (the event-emission assertion is skipped; other host behavior assertions remain in force)."
802
806
  },
803
807
  "maxRetryAttempts": {
804
808
  "type": "integer",
@@ -903,7 +907,7 @@
903
907
  },
904
908
  "endpointsSupported": {
905
909
  "type": "boolean",
906
- "description": "RFC 0028 §A. When `true`, the host serves the `/prompts*` REST surface — at minimum the read endpoints (`listPromptTemplates`, `getPromptTemplate`, `renderPromptTemplate`). The mutating endpoints additionally require `mutableLibrary: true`; the pack-install path additionally requires `packsSupported: true`. False or absent = every `/prompts*` request returns `501 capability_not_provided`. Independent of `supported` — a host MAY advertise `supported: true, endpointsSupported: false` (composition without library REST) or `supported: false, endpointsSupported: true` (library REST against an external resolver, e.g., a façade host)."
910
+ "description": "RFC 0028 §A. When `true`, the host serves the `/prompts*` REST surface — at minimum the read endpoints (`listPromptTemplates`, `getPromptTemplate`, `renderPromptTemplate`). The mutating endpoints additionally require `mutableLibrary: true`; the pack-install path additionally requires `packsSupported: true`. False or absent = every `/prompts*` request returns `501 capability_not_provided`. Independent of the family record — a host MAY advertise the family with `endpointsSupported: false` (composition without library REST) or the family omitted and `endpointsSupported: true` (library REST against an external resolver, e.g., a façade host)."
907
911
  },
908
912
  "templateKinds": {
909
913
  "type": "array",
@@ -925,7 +929,7 @@
925
929
  ]
926
930
  },
927
931
  "uniqueItems": true,
928
- "description": "Subset of PromptVariable.source values the host supports. `secret` SHOULD only appear when `capabilities.secrets.supported` is also true."
932
+ "description": "Subset of PromptVariable.source values the host supports. `secret` SHOULD only appear when the `secrets` family is advertised."
929
933
  },
930
934
  "maxTemplateBytes": {
931
935
  "type": "integer",
@@ -1069,7 +1073,7 @@
1069
1073
  },
1070
1074
  "wasm": {
1071
1075
  "type": "object",
1072
- "description": "WASM core-module runtime per RFC 0008. Hosts that load `runtime.language: \"wasm\"` packs MUST advertise `supported: true` and at least one entry in `abiVersions[]`. `additionalProperties: true` preserved for future RFC 0008 amendments (e.g., per-pack memory accounting fields).",
1076
+ "description": "WASM core-module runtime per RFC 0008. Hosts that load `runtime.language: \"wasm\"` packs MUST advertise this facet and at least one entry in `abiVersions[]`. `additionalProperties: true` preserved for future RFC 0008 amendments (e.g., per-pack memory accounting fields).",
1073
1077
  "properties": {
1074
1078
  "abiVersions": {
1075
1079
  "type": "array",
@@ -1244,7 +1248,8 @@
1244
1248
  "required": [
1245
1249
  "status",
1246
1250
  "since",
1247
- "witness"
1251
+ "witness",
1252
+ "packsSupported"
1248
1253
  ],
1249
1254
  "properties": {
1250
1255
  "status": {
@@ -1436,7 +1441,7 @@
1436
1441
  },
1437
1442
  "propagatesOnward": {
1438
1443
  "type": "boolean",
1439
- "description": "RFC 0128. When `true`, the host's onward OpenWOP-envelope hops (A2A forwards, trigger/sync events to OpenWOP peers) re-emit the label. Distinct from `supported` only for hosts that read labels but have no onward-hop surface at all; a host WITH onward hops advertising `supported: true` MUST also propagate."
1444
+ "description": "RFC 0128. When `true`, the host's onward OpenWOP-envelope hops (A2A forwards, trigger/sync events to OpenWOP peers) re-emit the label. Distinct from the family record only for hosts that read labels but have no onward-hop surface at all; a host WITH onward hops that advertises this facet MUST also propagate."
1440
1445
  }
1441
1446
  },
1442
1447
  "allOf": [
@@ -1483,7 +1488,8 @@
1483
1488
  "required": [
1484
1489
  "status",
1485
1490
  "since",
1486
- "witness"
1491
+ "witness",
1492
+ "regions"
1487
1493
  ],
1488
1494
  "properties": {
1489
1495
  "status": {
@@ -1565,7 +1571,8 @@
1565
1571
  "required": [
1566
1572
  "status",
1567
1573
  "since",
1568
- "witness"
1574
+ "witness",
1575
+ "tiers"
1569
1576
  ],
1570
1577
  "properties": {
1571
1578
  "status": {
@@ -1655,6 +1662,33 @@
1655
1662
  "until"
1656
1663
  ]
1657
1664
  }
1665
+ },
1666
+ {
1667
+ "$comment": "RFC 0132 §B.2 — writeEgressControls is REQUIRED and non-empty when bounded-write-egress is advertised, and MUST be absent otherwise (a control-less write/egress tier is the fail-open shape this RFC forbids).",
1668
+ "if": {
1669
+ "properties": {
1670
+ "tiers": {
1671
+ "contains": {
1672
+ "const": "bounded-write-egress"
1673
+ }
1674
+ }
1675
+ },
1676
+ "required": [
1677
+ "tiers"
1678
+ ]
1679
+ },
1680
+ "then": {
1681
+ "required": [
1682
+ "writeEgressControls"
1683
+ ]
1684
+ },
1685
+ "else": {
1686
+ "not": {
1687
+ "required": [
1688
+ "writeEgressControls"
1689
+ ]
1690
+ }
1691
+ }
1658
1692
  }
1659
1693
  ],
1660
1694
  "description": "core/capabilities.md#anonymousActor — witness: seam-gated; maturity experimental/none; RFC 0132",
@@ -2450,6 +2484,10 @@
2450
2484
  "required": [
2451
2485
  "version"
2452
2486
  ],
2487
+ "if": {
2488
+ "properties": {}
2489
+ },
2490
+ "then": {},
2453
2491
  "properties": {
2454
2492
  "version": {
2455
2493
  "type": "integer",
@@ -2476,6 +2514,17 @@
2476
2514
  },
2477
2515
  "confidenceEscalationInterruptKind": {
2478
2516
  "type": "string",
2517
+ "anyOf": [
2518
+ {
2519
+ "const": "clarification"
2520
+ },
2521
+ {
2522
+ "const": "approval"
2523
+ },
2524
+ {
2525
+ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$"
2526
+ }
2527
+ ],
2479
2528
  "description": "RFC 0044 — the literal `interrupt.kind` the host emits when escalating a below-floor confidence decision per RFC 0039 §A. `clarification` and `approval` are the canonical values matching the clarify-OR-approval choice in RFC 0039 §A; vendor-extension kinds use the canonical host-extension namespace `^x-host-<host>-<kind>$` per `spec/v1/host-extensions.md` §\"Canonical prefixes\". When advertised, hosts MUST emit an interrupt of the advertised kind on every confidence-escalation event AND the host's downstream `interrupt.md` mapping determines the `waiting-*` terminal status. Absent: conformance assumes the host uses one of the two canonical kinds (the relaxed assertion accepts either). Hosts using vendor kinds MUST also publish a non-normative kind-mapping document per RFC 0044 §C."
2480
2529
  },
2481
2530
  "crossChildMemoryConcurrency": {
@@ -2488,7 +2537,7 @@
2488
2537
  },
2489
2538
  "crossHostCausation": {
2490
2539
  "type": "object",
2491
- "description": "RFC 0040 §D — Phase 3 cross-host causation linking. When advertised, the host honors the cross-host `causationId` extension (a `causationHostId` field on event payloads pointing at the originating host), W3C `traceparent` propagation across MCP + A2A composition boundaries, and (when `ancestryEndpointSupported: true`) the `GET /runs/{runId}/ancestry` cross-host parent-chain endpoint. Hosts advertising `version: 3` MUST advertise this sub-block with `supported: true` and a stable `hostId`.",
2540
+ "description": "RFC 0040 §D — Phase 3 cross-host causation linking. When advertised, the host honors the cross-host `causationId` extension (a `causationHostId` field on event payloads pointing at the originating host), W3C `traceparent` propagation across MCP + A2A composition boundaries, and (when `ancestryEndpointSupported: true`) the `GET /runs/{runId}/ancestry` cross-host parent-chain endpoint. Hosts advertising `version: 3` MUST advertise this sub-block with a stable `hostId`.",
2492
2541
  "additionalProperties": false,
2493
2542
  "properties": {
2494
2543
  "hostId": {
@@ -2498,17 +2547,25 @@
2498
2547
  },
2499
2548
  "ancestryEndpointSupported": {
2500
2549
  "type": "boolean",
2501
- "description": "Host serves `GET /runs/{runId}/ancestry` returning the cross-host parent chain per RFC 0040 §C. Optional even when crossHostCausation.supported is true — hosts that emit `causationHostId` but don't expose the ancestry-walking endpoint still satisfy the per-event chaining contract; this flag advertises the additional endpoint."
2550
+ "description": "Host serves `GET /runs/{runId}/ancestry` returning the cross-host parent chain per RFC 0040 §C. Optional even when `crossHostCausation` is advertised — hosts that emit `causationHostId` but don't expose the ancestry-walking endpoint still satisfy the per-event chaining contract; this flag advertises the additional endpoint."
2502
2551
  }
2503
2552
  }
2504
2553
  },
2505
2554
  "replayDeterminism": {
2506
2555
  "type": "object",
2507
- "description": "RFC 0041 §D — Phase 4 replay determinism. When advertised, the host honors the LLM cache-key recipe in `replay.md` §\"LLM cache-key recipe\" as NORMATIVE (graduated from informative for version >= 4), emits `replay.divergedAtRefusal` events + fails with `replay_diverged_at_refusal` on refusal-divergence (RFC 0041 §B), and guarantees observable-output-sequence determinism per RFC 0041 §C. Hosts advertising `version: 4` MUST advertise this sub-block with `supported: true`.",
2556
+ "description": "RFC 0041 §D — Phase 4 replay determinism. When advertised, the host honors the LLM cache-key recipe in `replay.md` §\"LLM cache-key recipe\" as NORMATIVE (graduated from informative for version >= 4), emits `replay.divergedAtRefusal` events + fails with `replay_diverged_at_refusal` on refusal-divergence (RFC 0041 §B), and guarantees observable-output-sequence determinism per RFC 0041 §C. Hosts advertising `version: 4` MUST advertise this sub-block.",
2508
2557
  "additionalProperties": false,
2509
2558
  "properties": {
2510
2559
  "llmCacheKeyRecipe": {
2511
2560
  "type": "string",
2561
+ "anyOf": [
2562
+ {
2563
+ "const": "spec-rfc-0041"
2564
+ },
2565
+ {
2566
+ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$"
2567
+ }
2568
+ ],
2512
2569
  "description": "The LLM cache-key recipe the host honors. `spec-rfc-0041` = the canonical recipe in `replay.md` §\"LLM cache-key recipe\" §A + §B + §C. Vendor-specific recipes use the canonical host-extension namespace string matching `^x-host-<host>-<recipe-name>$` per `spec/v1/host-extensions.md` §\"Canonical prefixes\"; the matching algorithm MUST be documented at the host's discovery doc."
2513
2570
  },
2514
2571
  "refusalDivergenceEmission": {
@@ -2528,7 +2585,7 @@
2528
2585
  },
2529
2586
  "contextBudget": {
2530
2587
  "type": "object",
2531
- "description": "RFC 0111 (`Active`, `version >= 5`). Opt-in, token-denominated bound on the orchestrator transcript the host feeds each iteration, plus a declared summarization contract for turns evicted beyond that budget. SCOPE: governs the RFC 0061 per-iteration ORCHESTRATOR-LOOP transcript (`multi-agent-execution.md` §\"Per-iteration state inputs\" input 3 — the same transcript `transcriptWindow` bounds), NOT a general chat-conversation history. A host whose orchestrator loop does not run real model turns (e.g. a mock supervisor) MUST NOT advertise this block, exactly as it MUST NOT dishonestly advertise `transcriptWindow`. Budget-only advertisement (`transcriptTokenBudget` + `tokenCounter` WITHOUT `summarization.supported`) is valid for a host that HAS a real orchestrator loop but does not summarize. Purely additive: a host that omits this block behaves exactly as today, including `transcriptWindow`'s `absent ⇒ unbounded` default (NOT flipped by this RFC). Complements (does not replace) the event-count `transcriptWindow`; when both bound a turn the host MUST honor whichever is tighter. Summarization here is a NONDETERMINISTIC host output governed exactly like an RFC 0041 envelope: each substitution MUST be recorded as a `context.summarized` event whose `summaryRef` artifact replay reuses (never re-summarizes) per `multi-agent-execution.md` §\"Context economy (RFC 0111)\".",
2588
+ "description": "RFC 0111 (`Active`, `version >= 5`). Opt-in, token-denominated bound on the orchestrator transcript the host feeds each iteration, plus a declared summarization contract for turns evicted beyond that budget. SCOPE: governs the RFC 0061 per-iteration ORCHESTRATOR-LOOP transcript (`multi-agent-execution.md` §\"Per-iteration state inputs\" input 3 — the same transcript `transcriptWindow` bounds), NOT a general chat-conversation history. A host whose orchestrator loop does not run real model turns (e.g. a mock supervisor) MUST NOT advertise this block, exactly as it MUST NOT dishonestly advertise `transcriptWindow`. Budget-only advertisement (`transcriptTokenBudget` + `tokenCounter` WITHOUT `summarization`) is valid for a host that HAS a real orchestrator loop but does not summarize. Purely additive: a host that omits this block behaves exactly as today, including `transcriptWindow`'s `absent ⇒ unbounded` default (NOT flipped by this RFC). Complements (does not replace) the event-count `transcriptWindow`; when both bound a turn the host MUST honor whichever is tighter. Summarization here is a NONDETERMINISTIC host output governed exactly like an RFC 0041 envelope: each substitution MUST be recorded as a `context.summarized` event whose `summaryRef` artifact replay reuses (never re-summarizes) per `multi-agent-execution.md` §\"Context economy (RFC 0111)\".",
2532
2589
  "additionalProperties": false,
2533
2590
  "properties": {
2534
2591
  "transcriptTokenBudget": {
@@ -2549,7 +2606,7 @@
2549
2606
  "summarization": {
2550
2607
  "type": "object",
2551
2608
  "additionalProperties": false,
2552
- "description": "RFC 0111. Declared contract for turns evicted beyond `transcriptTokenBudget`. When `supported: true`, the host MAY replace older in-window turns with a host-produced summary; it MUST keep the most recent `keepLastTurns` turns verbatim and MUST NOT summarize the active (most recent) turn. Each substitution MUST be recorded as a `context.summarized` event and is replay-governed under RFC 0041 (replay reuses the recorded `summaryRef`, never re-summarizes).",
2609
+ "description": "RFC 0111. Declared contract for turns evicted beyond `transcriptTokenBudget`. When this facet is present, the host MAY replace older in-window turns with a host-produced summary; it MUST keep the most recent `keepLastTurns` turns verbatim and MUST NOT summarize the active (most recent) turn. Each substitution MUST be recorded as a `context.summarized` event and is replay-governed under RFC 0041 (replay reuses the recorded `summaryRef`, never re-summarizes).",
2553
2610
  "properties": {
2554
2611
  "strategy": {
2555
2612
  "type": "string",
@@ -2567,6 +2624,17 @@
2567
2624
  }
2568
2625
  }
2569
2626
  }
2627
+ },
2628
+ "if": {
2629
+ "required": [
2630
+ "transcriptTokenBudget"
2631
+ ]
2632
+ },
2633
+ "then": {
2634
+ "required": [
2635
+ "transcriptTokenBudget",
2636
+ "tokenCounter"
2637
+ ]
2570
2638
  }
2571
2639
  }
2572
2640
  }
@@ -2984,7 +3052,7 @@
2984
3052
  "scheduled",
2985
3053
  "on-demand"
2986
3054
  ],
2987
- "description": "How a consolidation pass is initiated. `host-managed`: a host-internal cadence clients do not control (default when absent and supported:true). `scheduled`: bound to a `capabilities.scheduling` (RFC 0052) trigger. `on-demand`: the host runs a pass when explicitly requested. A host MAY honor more than one path but advertises the primary."
3055
+ "description": "How a consolidation pass is initiated. `host-managed`: a host-internal cadence clients do not control (the default when absent). `scheduled`: bound to a `capabilities.scheduling` (RFC 0052) trigger. `on-demand`: the host runs a pass when explicitly requested. A host MAY honor more than one path but advertises the primary."
2988
3056
  }
2989
3057
  }
2990
3058
  },
@@ -3017,7 +3085,7 @@
3017
3085
  },
3018
3086
  "manifestRuntime": {
3019
3087
  "type": "object",
3020
- "description": "RFC 0070. Agent-manifest runtime floor — the minimal tier that makes a published agent pack (RFC 0003) runnable. When `supported: true`, the host implements RFC 0003 `installAgents`: it loads each installed pack's `agents[]` into an in-process AgentRegistry, resolves `systemPromptRef` + `handoff.*SchemaRef` from the tarball at install (RFC 0003 §C/§D), and can DISPATCH a manifest agent on the existing `core.dispatch`/orchestrator loop (RFC 0007/0037/0061). Does NOT imply swarm/consensus (`host.agentRuntime`), long-term memory (`agents.memoryBackends`), or crews beyond `agents.dispatch`. A host advertising `host.agentRuntime: supported` is treated as also satisfying this flag (RFC 0070 §B). Hosts that omit this block do not instantiate manifest agents (today's default).",
3088
+ "description": "RFC 0070. Agent-manifest runtime floor — the minimal tier that makes a published agent pack (RFC 0003) runnable. When this facet is present, the host implements RFC 0003 `installAgents`: it loads each installed pack's `agents[]` into an in-process AgentRegistry, resolves `systemPromptRef` + `handoff.*SchemaRef` from the tarball at install (RFC 0003 §C/§D), and can DISPATCH a manifest agent on the existing `core.dispatch`/orchestrator loop (RFC 0007/0037/0061). Does NOT imply swarm/consensus (`host.agentRuntime`), long-term memory (`agents.memoryBackends`), or crews beyond `agents.dispatch`. A host advertising `agentRuntime` is treated as also satisfying this flag (RFC 0070 §B). Hosts that omit this block do not instantiate manifest agents (today's default).",
3021
3089
  "additionalProperties": false,
3022
3090
  "properties": {
3023
3091
  "handoffValidation": {
@@ -3038,7 +3106,7 @@
3038
3106
  },
3039
3107
  "liveRuntime": {
3040
3108
  "type": "object",
3041
- "description": "RFC 0077. The host executes manifest agents against LIVE models and tools (not the deterministic RFC 0070 sample floor) per the normative AgentManifest→live-run mapping (`multi-agent-execution.md` §\"Live manifest dispatch\"), and emits the `agent.invocation.started`/`agent.invocation.completed` content-free bracket around the existing `agent.*` family. REQUIRES `agents.manifestRuntime.supported: true` — `liveRuntime` is a strict superset of the floor. The floor's mandatory safety guarantees (toolAllowlist enforcement, handoff inbound validation, tenant scoping, untrusted-model-output handling, fail-closed per-tool authorization) stay unconditional under `liveRuntime`. Hosts that omit this block run the floor only; the behavioral conformance scenarios skip cleanly.",
3109
+ "description": "RFC 0077. The host executes manifest agents against LIVE models and tools (not the deterministic RFC 0070 sample floor) per the normative AgentManifest→live-run mapping (`multi-agent-execution.md` §\"Live manifest dispatch\"), and emits the `agent.invocation.started`/`agent.invocation.completed` content-free bracket around the existing `agent.*` family. REQUIRES `agents.manifestRuntime` — `liveRuntime` is a strict superset of the floor. The floor's mandatory safety guarantees (toolAllowlist enforcement, handoff inbound validation, tenant scoping, untrusted-model-output handling, fail-closed per-tool authorization) stay unconditional under `liveRuntime`. Hosts that omit this block run the floor only; the behavioral conformance scenarios skip cleanly.",
3042
3110
  "additionalProperties": false,
3043
3111
  "properties": {
3044
3112
  "structuredOutput": {
@@ -3082,7 +3150,7 @@
3082
3150
  "live-shadow"
3083
3151
  ]
3084
3152
  },
3085
- "description": "Which eval modes the host actually implements (RFC 0081 §D closed vocabulary). Truthful advertisement (RFC 0031): a host advertises ONLY the modes it gates on; a suite requesting an unadvertised mode is rejected at run-create with `400 validation_error`. Absent ⇒ no modes (the host advertises `supported` but gates nothing — effectively shape-only)."
3153
+ "description": "Which eval modes the host actually implements (RFC 0081 §D closed vocabulary). Truthful advertisement (RFC 0031): a host advertises ONLY the modes it gates on; a suite requesting an unadvertised mode is rejected at run-create with `400 validation_error`. Absent ⇒ no modes (the host advertises the family but gates nothing — effectively shape-only)."
3086
3154
  },
3087
3155
  "maxTasksPerSuite": {
3088
3156
  "type": "integer",
@@ -3139,7 +3207,7 @@
3139
3207
  },
3140
3208
  "roster": {
3141
3209
  "type": "object",
3142
- "description": "RFC 0086. The host maintains a standing agent roster: named, tenant-scoped agent INSTANCES (the 'digital-twin employee') that reference a manifest/deployment and own a workflow portfolio, discoverable via GET /agents/roster, with trigger-fired portfolio runs attributed to the member via the content-free `roster.run.initiated` event. REQUIRES `agents.manifestRuntime.supported: true` (a roster entry instantiates a manifest agent). Triggers compose RFC 0052 (schedule) + RFC 0083 (durable work-item bridge) — no new WorkflowTrigger.type; the concrete work surface (a Kanban board) stays a host/vendor extension (§E). Hosts that omit this block do not maintain a roster (the roster reads 501). The roster-management endpoints + behavioral attribution scenario + reference-host store land at Active → Accepted.",
3210
+ "description": "RFC 0086. The host maintains a standing agent roster: named, tenant-scoped agent INSTANCES (the 'digital-twin employee') that reference a manifest/deployment and own a workflow portfolio, discoverable via GET /agents/roster, with trigger-fired portfolio runs attributed to the member via the content-free `roster.run.initiated` event. REQUIRES `agents.manifestRuntime` (a roster entry instantiates a manifest agent). Triggers compose RFC 0052 (schedule) + RFC 0083 (durable work-item bridge) — no new WorkflowTrigger.type; the concrete work surface (a Kanban board) stays a host/vendor extension (§E). Hosts that omit this block do not maintain a roster (the roster reads 501). The roster-management endpoints + behavioral attribution scenario + reference-host store land at Active → Accepted.",
3143
3211
  "additionalProperties": false,
3144
3212
  "properties": {
3145
3213
  "installScope": {
@@ -3163,7 +3231,7 @@
3163
3231
  },
3164
3232
  "orgChart": {
3165
3233
  "type": "object",
3166
- "description": "RFC 0087. The host maintains a tenant-scoped, DESCRIPTIVE org-chart over RFC 0086 roster members: departments + roles with acyclic `reportsTo` edges + a derived responsibility roll-up, discoverable via GET /agents/org-chart. The load-bearing guarantee (§B `org-position-no-authority-escalation`): an org edge confers NO authority — it MUST NOT widen `toolAllowlist` (RFC 0002 §A14), grant an RBAC scope (RFC 0049), or bypass an approval gate (RFC 0051); org position MUST NOT be an authorization input. The schema carries no authority-bearing field, and a conformant host MUST NOT derive authority from position out-of-band. REQUIRES `agents.roster.supported: true` (the chart's members are roster entries). Hosts that omit this block have no org-chart surface (the read 501s). The org-chart-management endpoints + behavioral non-authority scenario + reference-host store land at Active → Accepted.",
3234
+ "description": "RFC 0087. The host maintains a tenant-scoped, DESCRIPTIVE org-chart over RFC 0086 roster members: departments + roles with acyclic `reportsTo` edges + a derived responsibility roll-up, discoverable via GET /agents/org-chart. The load-bearing guarantee (§B `org-position-no-authority-escalation`): an org edge confers NO authority — it MUST NOT widen `toolAllowlist` (RFC 0002 §A14), grant an RBAC scope (RFC 0049), or bypass an approval gate (RFC 0051); org position MUST NOT be an authorization input. The schema carries no authority-bearing field, and a conformant host MUST NOT derive authority from position out-of-band. REQUIRES `agents.roster` (the chart's members are roster entries). Hosts that omit this block have no org-chart surface (the read 501s). The org-chart-management endpoints + behavioral non-authority scenario + reference-host store land at Active → Accepted.",
3167
3235
  "additionalProperties": false,
3168
3236
  "properties": {
3169
3237
  "installScope": {
@@ -3389,7 +3457,7 @@
3389
3457
  "client-requested",
3390
3458
  "both"
3391
3459
  ],
3392
- "description": "REQUIRED when `supported: true` per RFC 0012 §A (enforced via the `if/then` clause). `host-managed` runs on a host-internal schedule clients do not control. `client-requested` and `both` are reserved enum values; v1.x normates only `host-managed`."
3460
+ "description": "REQUIRED when this facet is present, per RFC 0012 §A (enforced by this facet's `required`). `host-managed` runs on a host-internal schedule clients do not control. `client-requested` and `both` are reserved enum values; v1.x normates only `host-managed`."
3393
3461
  },
3394
3462
  "maxInputEntries": {
3395
3463
  "type": "integer",
@@ -3402,7 +3470,10 @@
3402
3470
  "description": "Informational ceiling on the distilled entry size. SHOULD be ≤ `memory.maxEntrySizeBytes`."
3403
3471
  }
3404
3472
  },
3405
- "additionalProperties": false
3473
+ "additionalProperties": false,
3474
+ "required": [
3475
+ "trigger"
3476
+ ]
3406
3477
  },
3407
3478
  "distillation": {
3408
3479
  "type": "object",
@@ -3445,7 +3516,7 @@
3445
3516
  },
3446
3517
  "writable": {
3447
3518
  "type": "boolean",
3448
- "description": "RFC 0080 §A (`write` dimension). Absent ⇒ the host implements the full RFC 0004 four-operation MemoryAdapter (`put`/`delete` available — i.e. writable), the back-compatible default. A read-only host (`get`/`list` only) MUST set `writable: false` so a consumer can distinguish a read-only store from a read/write one. Only meaningful when `supported: true`."
3519
+ "description": "RFC 0080 §A (`write` dimension). Absent ⇒ the host implements the full RFC 0004 four-operation MemoryAdapter (`put`/`delete` available — i.e. writable), the back-compatible default. A read-only host (`get`/`list` only) MUST set `writable: false` so a consumer can distinguish a read-only store from a read/write one. Only meaningful when the family record is present."
3449
3520
  },
3450
3521
  "search": {
3451
3522
  "type": "object",
@@ -3494,9 +3565,12 @@
3494
3565
  "chars",
3495
3566
  "host-defined"
3496
3567
  ],
3497
- "description": "The unit `tokenBudget` is denominated in. REQUIRED when `injectionBudget.supported` (enforced via the `if/then` clause). `o200k_base`/`cl100k_base` are tokenizer encodings; `chars` counts UTF-8/Unicode characters of the entry `content` (a tokenizer-free unit a client can reason about directly — preferred over opaque `host-defined`); `host-defined` is an opaque host unit. The over-budget-single-entry-omitted rule applies regardless of unit. RFC 0111 aligns to these same values when it lands (0113 lands first); no shared `$ref` (decoupled)."
3568
+ "description": "The unit `tokenBudget` is denominated in. REQUIRED when `injectionBudget` is advertised (enforced by that facet's `required`). `o200k_base`/`cl100k_base` are tokenizer encodings; `chars` counts UTF-8/Unicode characters of the entry `content` (a tokenizer-free unit a client can reason about directly — preferred over opaque `host-defined`); `host-defined` is an opaque host unit. The over-budget-single-entry-omitted rule applies regardless of unit. RFC 0111 aligns to these same values when it lands (0113 lands first); no shared `$ref` (decoupled)."
3498
3569
  }
3499
- }
3570
+ },
3571
+ "required": [
3572
+ "tokenCounter"
3573
+ ]
3500
3574
  }
3501
3575
  },
3502
3576
  "allOf": [
@@ -3694,7 +3768,8 @@
3694
3768
  "required": [
3695
3769
  "status",
3696
3770
  "since",
3697
- "witness"
3771
+ "witness",
3772
+ "sandboxRoot"
3698
3773
  ],
3699
3774
  "properties": {
3700
3775
  "status": {
@@ -3724,7 +3799,7 @@
3724
3799
  },
3725
3800
  "sandboxRoot": {
3726
3801
  "type": "string",
3727
- "description": "Absolute path. Every fs operation is resolved relative to this root. MUST be set when `supported: true`."
3802
+ "description": "Absolute path. Every fs operation is resolved relative to this root. MUST be set when this facet is present."
3728
3803
  },
3729
3804
  "maxFileSizeBytes": {
3730
3805
  "type": "integer",
@@ -4484,7 +4559,7 @@
4484
4559
  },
4485
4560
  "ssrfGuard": {
4486
4561
  "type": "boolean",
4487
- "description": "Host rejects egress to loopback / RFC 1918 / link-local / cloud-metadata addresses (resolve→pin→connect). MUST be `true` when `supported` (the `http-client-ssrf-guard` invariant)."
4562
+ "description": "Host rejects egress to loopback / RFC 1918 / link-local / cloud-metadata addresses (resolve→pin→connect). MUST be `true` when this facet is present (the `http-client-ssrf-guard` invariant)."
4488
4563
  },
4489
4564
  "maxResponseBodyBytes": {
4490
4565
  "type": "integer",
@@ -5616,7 +5691,8 @@
5616
5691
  "required": [
5617
5692
  "status",
5618
5693
  "since",
5619
- "witness"
5694
+ "witness",
5695
+ "declared"
5620
5696
  ],
5621
5697
  "properties": {
5622
5698
  "status": {
@@ -5815,6 +5891,20 @@
5815
5891
  },
5816
5892
  "isolation": {
5817
5893
  "type": "string",
5894
+ "anyOf": [
5895
+ {
5896
+ "enum": [
5897
+ "cross-origin-iframe",
5898
+ "wasm",
5899
+ "process",
5900
+ "container",
5901
+ "vm"
5902
+ ]
5903
+ },
5904
+ {
5905
+ "pattern": "^x-host-[a-z0-9-]+-[a-z0-9-]+$"
5906
+ }
5907
+ ],
5818
5908
  "default": "cross-origin-iframe",
5819
5909
  "description": "RFC 0117 (amended by RFC 0119). The categorical isolation model the host enforces for plugin bytes. `cross-origin-iframe` = a distinct-origin sandboxed browser frame (the browser default; §Isolation). `wasm`/`process`/`container`/`vm` mirror `sandbox.isolationModel` (RFC 0035) for non-browser hosts that enforce the SAME isolation property. Vendor-specific models advertise `^x-host-<host>-<key>$` per `host-extensions.md`. ALL values denote the SAME mandatory property (`frontend-plugin-isolation`): plugin bytes execute in a boundary with no access to the host's execution context / DOM / origin-storage / credentials, deny-egress by default, and all host interaction mediated by the closed `ui-plugin/1` RPC. The field names the MECHANISM, never relaxes the property. In-process / same-origin / module-federation loading is a protocol-tier MUST NOT regardless of the advertised value."
5820
5910
  },
@@ -6462,7 +6552,7 @@
6462
6552
  },
6463
6553
  "subChains": {
6464
6554
  "type": "object",
6465
- "description": "RFC 0133 (workflow-chain composition, `Accepted`). OPTIONAL. When `supported: true`, the host's `POST …/workflows/from-chain` implements RUNTIME sub-chain composition per `workflow-chain-packs.md` §\"Sub-chain composition (RFC 0133)\": for each `config.subChainRef` reachable from a parent chain, it resolves the referenced chain (sibling or external), recursively expands + co-registers it as its own owned workflow (deterministic TENANT-SCOPED id from `(tenantId, childChainId, version)` — two tenants never collide on the global registry, a shared child registers once across parents in a tenant, a repeat instantiation converges), rewrites the referencing node's `subChainRef` → the minted child `config.workflowId`, and dispatches the child as a child run (`core.subWorkflow` / `core.dispatch` child-run); the `from-chain` response carries `{ workflowId, subChainWorkflowIds[], nodeCount }`. Bounded by a cycle check (`sub_chain_cycle`) + a depth cap (`sub_chain_max_depth_exceeded`). A host that does NOT advertise this block MUST refuse a `subChains`-bearing chain at author/instantiate time with `sub_chain_unsupported` (422) — it never silently flattens. `producedVariables` (RFC 0133 §2) needs NO flag: it is pure variable emission under the base `workflowChainPacks.supported`. Conformance scenarios `chain-subchain-fanout.test.ts` + `chain-subchain-unsupported-refused.test.ts` gate on this flag; the server-free `chain-subchain-sibling` / `chain-subchain-cycle-rejected` / `chain-produced-var-roundtrip` legs run unconditionally against the reference library.",
6555
+ "description": "RFC 0133 (workflow-chain composition, `Accepted`). OPTIONAL. When this facet is present, the host's `POST …/workflows/from-chain` implements RUNTIME sub-chain composition per `workflow-chain-packs.md` §\"Sub-chain composition (RFC 0133)\": for each `config.subChainRef` reachable from a parent chain, it resolves the referenced chain (sibling or external), recursively expands + co-registers it as its own owned workflow (deterministic TENANT-SCOPED id from `(tenantId, childChainId, version)` — two tenants never collide on the global registry, a shared child registers once across parents in a tenant, a repeat instantiation converges), rewrites the referencing node's `subChainRef` → the minted child `config.workflowId`, and dispatches the child as a child run (`core.subWorkflow` / `core.dispatch` child-run); the `from-chain` response carries `{ workflowId, subChainWorkflowIds[], nodeCount }`. Bounded by a cycle check (`sub_chain_cycle`) + a depth cap (`sub_chain_max_depth_exceeded`). A host that does NOT advertise this block MUST refuse a `subChains`-bearing chain at author/instantiate time with `sub_chain_unsupported` (422) — it never silently flattens. `producedVariables` (RFC 0133 §2) needs NO flag: it is pure variable emission under the base `workflowChainPacks` record. Conformance scenarios `chain-subchain-fanout.test.ts` + `chain-subchain-unsupported-refused.test.ts` gate on this flag; the server-free `chain-subchain-sibling` / `chain-subchain-cycle-rejected` / `chain-produced-var-roundtrip` legs run unconditionally against the reference library.",
6466
6556
  "properties": {
6467
6557
  "maxDepth": {
6468
6558
  "type": "integer",
@@ -6552,7 +6642,7 @@
6552
6642
  "properties": {
6553
6643
  "isolated": {
6554
6644
  "type": "boolean",
6555
- "description": "RFC 0025 §C point 1. MUST be `true` when `supported` is `true` — guarantees the test catalog is persisted distinctly from the production catalog and that a pack PUT'd via `/v1/packs-test/*` MUST NOT appear in `/v1/packs/*` listings."
6645
+ "description": "RFC 0025 §C point 1. MUST be `true` when this facet is present — guarantees the test catalog is persisted distinctly from the production catalog and that a pack PUT'd via `/v1/packs-test/*` MUST NOT appear in `/v1/packs/*` listings."
6556
6646
  },
6557
6647
  "catalogResetEndpoint": {
6558
6648
  "type": "string",
@@ -7003,6 +7093,16 @@
7003
7093
  },
7004
7094
  "partitionRecoveryStrategy": {
7005
7095
  "type": "string",
7096
+ "anyOf": [
7097
+ {
7098
+ "enum": [
7099
+ "lexicographic-min-run-id"
7100
+ ]
7101
+ },
7102
+ {
7103
+ "pattern": "^x-host-[a-z][a-z0-9-]*-[a-z][a-z0-9-]*$"
7104
+ }
7105
+ ],
7006
7106
  "description": "RFC 0150 §D — deterministic resolution rule for conflicting idempotency-key records after a partition heals. `lexicographic-min-run-id` is the rule spec/v1/idempotency.md §'Guarantees under partition' MUSTs: the lower runId wins, deterministic without coordination. Vendor strategies use `^x-host-<host>-<key>$` and MUST still satisfy the reproducible-survivor requirement. The time-ordered `last-writer-wins` / `first-writer-wins` values were REMOVED as a safety-fix: under a partition there is no shared clock, so both regions believe they wrote last, which cannot satisfy the annex MUST that re-running the same conflict input produces the same survivor — and both select a different survivor than the lex-min rule the same document requires. Resolving a RECORD never authorizes an EFFECT; see `crossRegion`."
7007
7107
  }
7008
7108
  }
@@ -7202,7 +7302,7 @@
7202
7302
  "minWindowSeconds": {
7203
7303
  "type": "integer",
7204
7304
  "minimum": 604800,
7205
- "description": "Documented minimum retention window in seconds. Per production-profile.md §\"Event retention\", MUST be ≥ 604800 (7 days) for public hosts; development-only hosts MAY advertise a smaller window but MUST NOT claim `supported: true` while doing so."
7305
+ "description": "Documented minimum retention window in seconds. Per production-profile.md §\"Event retention\", MUST be ≥ 604800 (7 days) for public hosts; development-only hosts MAY advertise a smaller window but MUST NOT advertise this facet while doing so."
7206
7306
  },
7207
7307
  "testForceExpire": {
7208
7308
  "type": "boolean",
@@ -7213,7 +7313,7 @@
7213
7313
  },
7214
7314
  "debugBundle": {
7215
7315
  "type": "object",
7216
- "description": "Debug-bundle truncation advertisement (production-profile.md §\"Debug bundle behavior\"). Stricter than the existing `capabilities.debugBundle.supported` advertised per debug-bundle.md — this block adds the production-profile MUSTs (truncation metadata, redaction).",
7316
+ "description": "Debug-bundle truncation advertisement (production-profile.md §\"Debug bundle behavior\"). Stricter than the existing `capabilities.debugBundle` advertised per debug-bundle.md — this block adds the production-profile MUSTs (truncation metadata, redaction).",
7217
7317
  "properties": {
7218
7318
  "truncationMetadata": {
7219
7319
  "type": "boolean",
@@ -7512,7 +7612,9 @@
7512
7612
  "required": [
7513
7613
  "status",
7514
7614
  "since",
7515
- "witness"
7615
+ "witness",
7616
+ "baseLocale",
7617
+ "supportedLocales"
7516
7618
  ],
7517
7619
  "properties": {
7518
7620
  "status": {
@@ -7693,6 +7795,28 @@
7693
7795
  "until"
7694
7796
  ]
7695
7797
  }
7798
+ },
7799
+ {
7800
+ "if": {
7801
+ "properties": {
7802
+ "import": {
7803
+ "const": true
7804
+ }
7805
+ },
7806
+ "required": [
7807
+ "import"
7808
+ ]
7809
+ },
7810
+ "then": {
7811
+ "properties": {
7812
+ "dryRun": {
7813
+ "const": true
7814
+ }
7815
+ },
7816
+ "required": [
7817
+ "dryRun"
7818
+ ]
7819
+ }
7696
7820
  }
7697
7821
  ],
7698
7822
  "description": "core/capabilities.md#portability — witness: witnessable-gated; maturity experimental/none; RFC 0098",
@@ -4,7 +4,7 @@
4
4
  "provenance": {
5
5
  "suite": {
6
6
  "package": "@openwop/openwop-conformance",
7
- "version": "2.15.0"
7
+ "version": "2.16.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": "4ff5b4a569f1ff03c71f0aec32ce5cb443cb4129a8d8cf5753c7808bd48afe58"
422
+ "digest": "c0f1590f583e543666dbff52208450cee734e7d602f72832f65dcd6a7feda0c2"
423
423
  }
package/spec/v1/gaps.json CHANGED
@@ -10467,6 +10467,57 @@
10467
10467
  }
10468
10468
  ]
10469
10469
  },
10470
+ {
10471
+ "id": "openwop.gap.0192.1",
10472
+ "rfc": "0192",
10473
+ "local": "G1",
10474
+ "section": "§A",
10475
+ "surface": "A host has no way to advertise a facet NEGATIVELY — \"I know about this and do not offer it\". Presence-semantics makes omission the only spelling, which cannot distinguish *unsupported* from *not yet considered*. MyndHyve expresses exactly this today as `extensions.myndhyve.runs.pauseResume.supported = false`, fleeing to the vendor namespace because the core root cannot say it. That is a production host routing around a missing surface, which is evidence the gap is real rather than theoretical.",
10476
+ "witness": "unclassified",
10477
+ "requirementId": null,
10478
+ "disposition": "carried",
10479
+ "target": "openwop.gap.0192.1",
10480
+ "sources": [
10481
+ {
10482
+ "file": "RFCS/registers/0192-facet-advertisement.gaps.md",
10483
+ "token": "G1"
10484
+ }
10485
+ ]
10486
+ },
10487
+ {
10488
+ "id": "openwop.gap.0192.2",
10489
+ "rfc": "0192",
10490
+ "local": "G2",
10491
+ "section": "§B",
10492
+ "surface": "The rewrite table is keyed on the exact v1 sentence, so a reworded v1 seed silently stops matching and the ghost returns — caught by §C's gate, but as a new failure rather than as a diff on the table.",
10493
+ "witness": "unclassified",
10494
+ "requirementId": null,
10495
+ "disposition": "carried",
10496
+ "target": "openwop.gap.0192.2",
10497
+ "sources": [
10498
+ {
10499
+ "file": "RFCS/registers/0192-facet-advertisement.gaps.md",
10500
+ "token": "G2"
10501
+ }
10502
+ ]
10503
+ },
10504
+ {
10505
+ "id": "openwop.gap.0192.3",
10506
+ "rfc": "0192",
10507
+ "local": "G3",
10508
+ "section": "§A",
10509
+ "surface": "Eight core families carry zero facets, so the facet rule is vacuous for them, and `facetsUncovered` gives them no backstop either (RFC 0190 §B). Nothing in the corpus distinguishes \"this family genuinely has no sub-capabilities\" from \"its facets were never modelled\".",
10510
+ "witness": "unclassified",
10511
+ "requirementId": null,
10512
+ "disposition": "carried",
10513
+ "target": "openwop.gap.0192.3",
10514
+ "sources": [
10515
+ {
10516
+ "file": "RFCS/registers/0192-facet-advertisement.gaps.md",
10517
+ "token": "G3"
10518
+ }
10519
+ ]
10520
+ },
10470
10521
  {
10471
10522
  "id": "openwop.gap.spec.a2a-integration.g1",
10472
10523
  "rfc": "0152",
@@ -37,7 +37,7 @@ Every family at the v2 root is one object:
37
37
  | `until` in the past | non-conformant; a validator MUST answer `400` `until_in_past` |
38
38
  | `witness` | MUST be one of the five wire-legal classes; `unwitnessable` MUST NOT appear on a wire record — such a family lives in `spec/v2/ext/` and is not advertised |
39
39
  | `supported` | does not exist; presence of the record is the claim, and a host that does not support a family MUST omit it |
40
- | facets | the named per-family fields; `aiProviders.providers[]` carries the v1 `supported` list |
40
+ | facets | the named per-family fields; a facet is advertised by the presence of its key, and a host MUST omit the key for a facet it does not offer, except where the facet's own schema states a meaning for its absence; `aiProviders.providers[]` carries the v1 `supported` list |
41
41
 
42
42
  `until` absorbs v1 `tier` / `experimentalUntil`. A family's facets are hand-decided where `spec/v2/facets/<key>.schema.json` exists and otherwise generated from the declaration row.
43
43
 
@@ -7,7 +7,7 @@
7
7
  "properties": {
8
8
  "isolated": {
9
9
  "type": "boolean",
10
- "description": "RFC 0025 §C point 1. MUST be `true` when `supported` is `true` — guarantees the test catalog is persisted distinctly from the production catalog and that a pack PUT'd via `/v1/packs-test/*` MUST NOT appear in `/v1/packs/*` listings."
10
+ "description": "RFC 0025 §C point 1. MUST be `true` when this facet is present — guarantees the test catalog is persisted distinctly from the production catalog and that a pack PUT'd via `/v1/packs-test/*` MUST NOT appear in `/v1/packs/*` listings."
11
11
  },
12
12
  "catalogResetEndpoint": {
13
13
  "type": "string",
@@ -1,15 +1,15 @@
1
1
  {
2
- "$comment": "RFC 0013 \u00a7Composition depth \u2014 the v2 facet set for workflowChainPacks. Two v1-seeded facets are NOT carried into v2: `deferredParameters` (RFC 0124, still `Active`; spec/v2/core/workflow-chain-packs.md \u00a7Parameter substitution states the portable per-run deferral \"is a named v2.x additive RFC and is not part of v2.0\", so binding it as an advertisable v2 facet let a host truthfully advertise a capability v2.0 does not define) and `hostExpansionSeam` (a self-described conformance-only test seam on POST /v1/host/sample/workflow-chain:expand \u2014 spec/v2/core/conformance.md \u00a7The seams profile forbids a test-seam capability flag: seams are the profile openwop-conformance-seams-v2 in the /conformance/seams/ path space, and the v1 path is removeIn 2.0 per spec/v1/deprecations.json). No v2 host bundle advertises either.",
2
+ "$comment": "RFC 0013 §Composition depth — the v2 facet set for workflowChainPacks. Two v1-seeded facets are NOT carried into v2: `deferredParameters` (RFC 0124, still `Active`; spec/v2/core/workflow-chain-packs.md §Parameter substitution states the portable per-run deferral \"is a named v2.x additive RFC and is not part of v2.0\", so binding it as an advertisable v2 facet let a host truthfully advertise a capability v2.0 does not define) and `hostExpansionSeam` (a self-described conformance-only test seam on POST /v1/host/sample/workflow-chain:expand — spec/v2/core/conformance.md §The seams profile forbids a test-seam capability flag: seams are the profile openwop-conformance-seams-v2 in the /conformance/seams/ path space, and the v1 path is removeIn 2.0 per spec/v1/deprecations.json). No v2 host bundle advertises either.",
3
3
  "properties": {
4
4
  "subChains": {
5
5
  "type": "object",
6
- "description": "RFC 0133 (workflow-chain composition, `Accepted`). OPTIONAL. When `supported: true`, the host's `POST \u2026/workflows/from-chain` implements RUNTIME sub-chain composition per `workflow-chain-packs.md` \u00a7\"Sub-chain composition (RFC 0133)\": for each `config.subChainRef` reachable from a parent chain, it resolves the referenced chain (sibling or external), recursively expands + co-registers it as its own owned workflow (deterministic TENANT-SCOPED id from `(tenantId, childChainId, version)` \u2014 two tenants never collide on the global registry, a shared child registers once across parents in a tenant, a repeat instantiation converges), rewrites the referencing node's `subChainRef` \u2192 the minted child `config.workflowId`, and dispatches the child as a child run (`core.subWorkflow` / `core.dispatch` child-run); the `from-chain` response carries `{ workflowId, subChainWorkflowIds[], nodeCount }`. Bounded by a cycle check (`sub_chain_cycle`) + a depth cap (`sub_chain_max_depth_exceeded`). A host that does NOT advertise this block MUST refuse a `subChains`-bearing chain at author/instantiate time with `sub_chain_unsupported` (422) \u2014 it never silently flattens. `producedVariables` (RFC 0133 \u00a72) needs NO flag: it is pure variable emission under the base `workflowChainPacks.supported`. Conformance scenarios `chain-subchain-fanout.test.ts` + `chain-subchain-unsupported-refused.test.ts` gate on this flag; the server-free `chain-subchain-sibling` / `chain-subchain-cycle-rejected` / `chain-produced-var-roundtrip` legs run unconditionally against the reference library.",
6
+ "description": "RFC 0133 (workflow-chain composition, `Accepted`). OPTIONAL. When this facet is present, the host's `POST …/workflows/from-chain` implements RUNTIME sub-chain composition per `workflow-chain-packs.md` §\"Sub-chain composition (RFC 0133)\": for each `config.subChainRef` reachable from a parent chain, it resolves the referenced chain (sibling or external), recursively expands + co-registers it as its own owned workflow (deterministic TENANT-SCOPED id from `(tenantId, childChainId, version)` — two tenants never collide on the global registry, a shared child registers once across parents in a tenant, a repeat instantiation converges), rewrites the referencing node's `subChainRef` → the minted child `config.workflowId`, and dispatches the child as a child run (`core.subWorkflow` / `core.dispatch` child-run); the `from-chain` response carries `{ workflowId, subChainWorkflowIds[], nodeCount }`. Bounded by a cycle check (`sub_chain_cycle`) + a depth cap (`sub_chain_max_depth_exceeded`). A host that does NOT advertise this block MUST refuse a `subChains`-bearing chain at author/instantiate time with `sub_chain_unsupported` (422) — it never silently flattens. `producedVariables` (RFC 0133 §2) needs NO flag: it is pure variable emission under the base `workflowChainPacks` record. Conformance scenarios `chain-subchain-fanout.test.ts` + `chain-subchain-unsupported-refused.test.ts` gate on this flag; the server-free `chain-subchain-sibling` / `chain-subchain-cycle-rejected` / `chain-produced-var-roundtrip` legs run unconditionally against the reference library.",
7
7
  "properties": {
8
8
  "maxDepth": {
9
9
  "type": "integer",
10
10
  "minimum": 1,
11
11
  "default": 8,
12
- "description": "RFC 0133 \u00a71.3 (resolves UQ3). RECOMMENDED default 8. The maximum sub-chain nesting depth the host co-expands; exceeding it fails closed with the DISTINCT code `sub_chain_max_depth_exceeded` (the DoS depth backstop, alongside the `sub_chain_cycle` self-composition check \u2014 SECURITY `sub-chain-expansion-bounded`)."
12
+ "description": "RFC 0133 §1.3 (resolves UQ3). RECOMMENDED default 8. The maximum sub-chain nesting depth the host co-expands; exceeding it fails closed with the DISTINCT code `sub_chain_max_depth_exceeded` (the DoS depth backstop, alongside the `sub_chain_cycle` self-composition check — SECURITY `sub-chain-expansion-bounded`)."
13
13
  }
14
14
  },
15
15
  "additionalProperties": false
@@ -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.15.0",
4
- "corpusTag": "v2.15.0",
3
+ "version": "2.16.0",
4
+ "corpusTag": "v2.16.0",
5
5
  "updated": "2026-09-18"
6
6
  }