@openwop/openwop-conformance 1.163.0 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (611) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.js +262 -14
  3. package/dist/lib/certification-bundle-v3.js +142 -0
  4. package/dist/lib/paths.js +25 -3
  5. package/dist/lib/requirement-ids.js +57 -4
  6. package/dist/lib/requirement-ledger.js +1 -0
  7. package/dist/lib/scenario-disposition.js +6 -1
  8. package/dist/lib/spec-coherence.js +13 -32
  9. package/dist/spec-artifacts.lock.json +5 -0
  10. package/package.json +11 -33
  11. package/requirements.json +22892 -11701
  12. package/scenario-majors.json +1493 -0
  13. package/schemas/CORPUS-STAMP.json +137 -5
  14. package/src/cli.ts +236 -19
  15. package/src/global-setup.ts +3 -2
  16. package/src/lib/certification-bundle-v3.ts +175 -0
  17. package/src/lib/corpus-stamp.ts +29 -1
  18. package/src/lib/driver.ts +9 -1
  19. package/src/lib/era2-seed.ts +197 -0
  20. package/src/lib/paths.ts +25 -3
  21. package/src/lib/requirement-ids.ts +54 -4
  22. package/src/lib/requirement-ledger.ts +7 -1
  23. package/src/lib/scenario-disposition.ts +6 -1
  24. package/src/lib/seams.ts +45 -0
  25. package/src/lib/spec-coherence.ts +15 -32
  26. package/src/lib/v2.ts +62 -0
  27. package/src/scenarios/a2a-1-0-agent-card.test.ts +17 -16
  28. package/src/scenarios/a2a-1-0-task-roundtrip.test.ts +11 -10
  29. package/src/scenarios/a2a-card-runtime-consistency.test.ts +18 -17
  30. package/src/scenarios/a2a-peer-authority.test.ts +7 -6
  31. package/src/scenarios/a2a-task-roundtrip.test.ts +30 -29
  32. package/src/scenarios/a2a-version-negotiation.test.ts +16 -14
  33. package/src/scenarios/a2ui-surface-degrades.test.ts +5 -3
  34. package/src/scenarios/a2ui-surface-delta-transport.test.ts +35 -33
  35. package/src/scenarios/a2ui-surface-replay.test.ts +6 -4
  36. package/src/scenarios/a2ui-surface-shape.test.ts +11 -10
  37. package/src/scenarios/a2ui-surface-version-refusal.test.ts +6 -4
  38. package/src/scenarios/a2ui-untrusted-blocks-approval.test.ts +5 -3
  39. package/src/scenarios/agent-capability-degraded-projection.test.ts +12 -11
  40. package/src/scenarios/agent-channel-dispatch.test.ts +18 -16
  41. package/src/scenarios/agent-deployment-lifecycle.test.ts +20 -19
  42. package/src/scenarios/agent-deployment-shape.test.ts +22 -24
  43. package/src/scenarios/agent-eval-run.test.ts +19 -18
  44. package/src/scenarios/agent-eval-suite-shape.test.ts +20 -22
  45. package/src/scenarios/agent-live-allowlist-enforced.test.ts +6 -5
  46. package/src/scenarios/agent-live-invocation-bracket.test.ts +13 -12
  47. package/src/scenarios/agent-live-runtime-shape.test.ts +10 -12
  48. package/src/scenarios/agent-live-structured-output.test.ts +7 -6
  49. package/src/scenarios/agent-loop-iteration-monotonic.test.ts +3 -3
  50. package/src/scenarios/agent-loop-stateful-resume.test.ts +2 -2
  51. package/src/scenarios/agent-loop-version5-shape.test.ts +4 -4
  52. package/src/scenarios/agent-loop-workspace-snapshot.test.ts +3 -3
  53. package/src/scenarios/agent-manifest-role-profile.test.ts +9 -9
  54. package/src/scenarios/agent-manifest-runtime.test.ts +13 -12
  55. package/src/scenarios/agent-org-chart-scoping.test.ts +14 -13
  56. package/src/scenarios/agent-org-chart-shape.test.ts +11 -13
  57. package/src/scenarios/agent-platform-aggregate-evidence.test.ts +5 -4
  58. package/src/scenarios/agent-platform-profile.test.ts +18 -19
  59. package/src/scenarios/agent-requires-capabilities-shape.test.ts +4 -4
  60. package/src/scenarios/agent-roster-attribution.test.ts +18 -17
  61. package/src/scenarios/agent-roster-shape.test.ts +17 -19
  62. package/src/scenarios/agent-verifier-shape.test.ts +11 -11
  63. package/src/scenarios/agentConfidenceEscalation.test.ts +2 -1
  64. package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +6 -5
  65. package/src/scenarios/agentMemoryRedactionContract.test.ts +2 -1
  66. package/src/scenarios/agentMemoryRoundTrip.test.ts +2 -1
  67. package/src/scenarios/agentMemoryTtlExpiry.test.ts +4 -3
  68. package/src/scenarios/agentMessageReducer.test.ts +2 -1
  69. package/src/scenarios/agentMetadata.test.ts +2 -1
  70. package/src/scenarios/agentPackCatalog.test.ts +23 -21
  71. package/src/scenarios/agentPackExport.test.ts +4 -2
  72. package/src/scenarios/agentPackHandoffSchemaValidation.test.ts +5 -4
  73. package/src/scenarios/agentPackInstall.test.ts +4 -2
  74. package/src/scenarios/agentPackProvenance.test.ts +2 -1
  75. package/src/scenarios/agentReasoningEvents.test.ts +3 -2
  76. package/src/scenarios/agentReasoningStreaming.test.ts +11 -10
  77. package/src/scenarios/agents-run-tool-allowlist.test.ts +14 -12
  78. package/src/scenarios/ai-envelope-shape.test.ts +31 -29
  79. package/src/scenarios/aiEnvelope.capBreached.test.ts +26 -24
  80. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +36 -34
  81. package/src/scenarios/aiEnvelope.correlationReplay.test.ts +17 -15
  82. package/src/scenarios/aiEnvelope.redaction.test.ts +22 -20
  83. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +18 -16
  84. package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +38 -36
  85. package/src/scenarios/aiEnvelope.universalKinds.test.ts +31 -29
  86. package/src/scenarios/aiproviders-input-shape.test.ts +5 -5
  87. package/src/scenarios/aiproviders-realtimevoice-shape.test.ts +14 -16
  88. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +6 -4
  89. package/src/scenarios/aiproviders-selfhosted-shape.test.ts +15 -17
  90. package/src/scenarios/aiproviders-speechsynth-shape.test.ts +6 -8
  91. package/src/scenarios/aiproviders-subscription-scope.test.ts +7 -8
  92. package/src/scenarios/anonymous-actor-audit-opaque.test.ts +9 -8
  93. package/src/scenarios/anonymous-actor-default-deny.test.ts +10 -9
  94. package/src/scenarios/anonymous-actor-egress-guarded.test.ts +6 -5
  95. package/src/scenarios/anonymous-actor-no-secret-reach.test.ts +7 -6
  96. package/src/scenarios/anonymous-actor-shape.test.ts +17 -19
  97. package/src/scenarios/anonymous-actor-write-gated.test.ts +9 -8
  98. package/src/scenarios/append-ordering.test.ts +7 -5
  99. package/src/scenarios/approval-gate-events.test.ts +4 -3
  100. package/src/scenarios/approval-gate-flow.test.ts +4 -3
  101. package/src/scenarios/approval-payload.test.ts +5 -4
  102. package/src/scenarios/artifact-auth.test.ts +7 -6
  103. package/src/scenarios/artifact-type-pack-install.test.ts +6 -6
  104. package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +9 -8
  105. package/src/scenarios/artifact-type-registration-source.test.ts +20 -20
  106. package/src/scenarios/artifact-type-store-emission.test.ts +15 -18
  107. package/src/scenarios/artifact-type-store-without-render.test.ts +4 -4
  108. package/src/scenarios/audit-log-integrity.test.ts +8 -6
  109. package/src/scenarios/auth-api-key-rotation.test.ts +11 -9
  110. package/src/scenarios/auth-mtls.test.ts +22 -20
  111. package/src/scenarios/auth-oauth2-client-credentials.test.ts +16 -14
  112. package/src/scenarios/auth-oidc-user-bearer.test.ts +26 -24
  113. package/src/scenarios/auth-saml-profile.test.ts +14 -12
  114. package/src/scenarios/auth-scim-profile.test.ts +3 -2
  115. package/src/scenarios/auth-subject-link-key-class.test.ts +8 -7
  116. package/src/scenarios/auth-subject-link.test.ts +11 -10
  117. package/src/scenarios/auth.test.ts +5 -4
  118. package/src/scenarios/authorization-fail-closed.test.ts +3 -2
  119. package/src/scenarios/authorization-roles-shape.test.ts +9 -7
  120. package/src/scenarios/blob-cross-tenant-isolation.test.ts +8 -6
  121. package/src/scenarios/blob-presign-expiry.test.ts +12 -10
  122. package/src/scenarios/blob-roundtrip.test.ts +0 -0
  123. package/src/scenarios/budget-enforcement.test.ts +15 -14
  124. package/src/scenarios/budget-policy-shape.test.ts +18 -19
  125. package/src/scenarios/bulk-cancel.test.ts +9 -8
  126. package/src/scenarios/byok-auth-modes.test.ts +13 -14
  127. package/src/scenarios/byok-roundtrip.test.ts +12 -10
  128. package/src/scenarios/cache-cross-tenant-isolation.test.ts +8 -6
  129. package/src/scenarios/cache-ttl-expiry.test.ts +7 -5
  130. package/src/scenarios/callai-multimodal.test.ts +5 -3
  131. package/src/scenarios/cancellation.test.ts +6 -5
  132. package/src/scenarios/cap-breach.test.ts +15 -14
  133. package/src/scenarios/capability-arm-witness.test.ts +5 -3
  134. package/src/scenarios/certification-bundle-non-vacuous.test.ts +20 -19
  135. package/src/scenarios/certification-bundle-redaction.test.ts +11 -10
  136. package/src/scenarios/certification-bundle-v2.test.ts +11 -10
  137. package/src/scenarios/chain-compensation-expansion.test.ts +14 -13
  138. package/src/scenarios/chain-produced-var-roundtrip.test.ts +13 -14
  139. package/src/scenarios/chain-subchain-cycle-rejected.test.ts +9 -10
  140. package/src/scenarios/chain-subchain-fanout.test.ts +8 -9
  141. package/src/scenarios/chain-subchain-sibling.test.ts +14 -16
  142. package/src/scenarios/channel-presence-behavioral.test.ts +9 -7
  143. package/src/scenarios/channel-presence-shape.test.ts +11 -12
  144. package/src/scenarios/channel-ttl.test.ts +6 -5
  145. package/src/scenarios/chat-card-pack-execution.test.ts +4 -4
  146. package/src/scenarios/chat-card-pack-manifest-validation.test.ts +9 -8
  147. package/src/scenarios/commitment-fired.test.ts +6 -5
  148. package/src/scenarios/compensation-behavior.test.ts +24 -23
  149. package/src/scenarios/compensation-recovery.test.ts +28 -27
  150. package/src/scenarios/configurable-schema.test.ts +8 -6
  151. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -5
  152. package/src/scenarios/conformance-execution-witness.test.ts +9 -8
  153. package/src/scenarios/connection-pack-apihosts.test.ts +19 -17
  154. package/src/scenarios/connection-pack-manifest-valid.test.ts +12 -11
  155. package/src/scenarios/connection-pack-no-credential-material.test.ts +8 -6
  156. package/src/scenarios/connection-pack-reach-exclusive.test.ts +5 -4
  157. package/src/scenarios/connection-pack-write-reconsent.test.ts +6 -4
  158. package/src/scenarios/connection-provider-resolution.test.ts +18 -16
  159. package/src/scenarios/connector-manifest-validity.test.ts +8 -7
  160. package/src/scenarios/context-budget-transcript-bound.test.ts +17 -15
  161. package/src/scenarios/context-summarization-replay.test.ts +14 -12
  162. package/src/scenarios/contract-provenance.test.ts +18 -18
  163. package/src/scenarios/conversation-turn-model-provenance-shape.test.ts +14 -15
  164. package/src/scenarios/conversationCapabilityNegotiation.test.ts +2 -1
  165. package/src/scenarios/conversationLifecycle.test.ts +2 -1
  166. package/src/scenarios/conversationReplayDeterminism.test.ts +4 -2
  167. package/src/scenarios/conversationVsLegacySuspend.test.ts +2 -1
  168. package/src/scenarios/core-standard-profile.test.ts +8 -9
  169. package/src/scenarios/cost-attribution.test.ts +23 -21
  170. package/src/scenarios/credential-payload-redaction.test.ts +4 -3
  171. package/src/scenarios/credentials-capability-shape.test.ts +5 -4
  172. package/src/scenarios/cross-engine-append-behavior.test.ts +11 -10
  173. package/src/scenarios/cross-engine-append-ordering.test.ts +4 -3
  174. package/src/scenarios/cross-host-ancestry-endpoint.test.ts +11 -10
  175. package/src/scenarios/cross-host-causation-shape.test.ts +7 -6
  176. package/src/scenarios/cross-workspace-isolation.test.ts +4 -3
  177. package/src/scenarios/data-residency-admission.test.ts +15 -14
  178. package/src/scenarios/deadletter-capability-shape.test.ts +6 -4
  179. package/src/scenarios/deadletter-retry-exhaustion.test.ts +4 -3
  180. package/src/scenarios/debug-bundle-truncation.test.ts +9 -7
  181. package/src/scenarios/debugBundle.test.ts +25 -23
  182. package/src/scenarios/discovery-families-view.test.ts +5 -4
  183. package/src/scenarios/discovery.test.ts +30 -29
  184. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +10 -8
  185. package/src/scenarios/dispatch-fanout-parallel.test.ts +24 -22
  186. package/src/scenarios/dispatch-input-mapping.test.ts +12 -10
  187. package/src/scenarios/dispatch-output-mapping.test.ts +9 -7
  188. package/src/scenarios/dispatch-per-item-input.test.ts +22 -20
  189. package/src/scenarios/dispatchLoop.test.ts +3 -2
  190. package/src/scenarios/distillation-index-roundtrip.test.ts +3 -3
  191. package/src/scenarios/distillation-secret-carryforward.test.ts +2 -2
  192. package/src/scenarios/distillation-shape.test.ts +4 -4
  193. package/src/scenarios/distillation-stable-archive.test.ts +6 -6
  194. package/src/scenarios/distillation-token-budget.test.ts +5 -5
  195. package/src/scenarios/durability-poison-exhaustion.test.ts +7 -6
  196. package/src/scenarios/egress-audience-binding.test.ts +11 -10
  197. package/src/scenarios/egress-decision-content-free.test.ts +6 -5
  198. package/src/scenarios/egress-provenance-shape.test.ts +17 -18
  199. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +27 -25
  200. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +19 -17
  201. package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +28 -26
  202. package/src/scenarios/envelope-reasoning-shape.test.ts +19 -17
  203. package/src/scenarios/envelope-recovery-applied.test.ts +24 -22
  204. package/src/scenarios/envelope-refusal-shape.test.ts +31 -29
  205. package/src/scenarios/envelope-rendering-hint.test.ts +5 -4
  206. package/src/scenarios/envelope-retry-attempted.test.ts +33 -31
  207. package/src/scenarios/envelope-retry-exhausted.test.ts +22 -20
  208. package/src/scenarios/envelope-tier-one-subset-static.test.ts +9 -7
  209. package/src/scenarios/envelope-truncated.test.ts +19 -17
  210. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +19 -17
  211. package/src/scenarios/envelope-variant-discriminator-static.test.ts +4 -3
  212. package/src/scenarios/errors.test.ts +20 -19
  213. package/src/scenarios/eventOrdering.test.ts +16 -14
  214. package/src/scenarios/exec-not-protocol-tier.test.ts +5 -7
  215. package/src/scenarios/experimental-tier-shape.test.ts +17 -15
  216. package/src/scenarios/export-bundle-portability.test.ts +17 -17
  217. package/src/scenarios/failure-path.test.ts +7 -6
  218. package/src/scenarios/feedback-capability-shape.test.ts +4 -3
  219. package/src/scenarios/feedback-correction-redaction.test.ts +2 -1
  220. package/src/scenarios/feedback-cross-tenant-isolation.test.ts +2 -1
  221. package/src/scenarios/feedback-fork-not-copied.test.ts +3 -2
  222. package/src/scenarios/feedback-on-terminal-run.test.ts +3 -2
  223. package/src/scenarios/feedback-record-and-list.test.ts +2 -1
  224. package/src/scenarios/feedback-unsupported-501.test.ts +2 -1
  225. package/src/scenarios/fixtures-gating.test.ts +29 -28
  226. package/src/scenarios/fixtures-valid.test.ts +16 -15
  227. package/src/scenarios/form-content-instantiation.test.ts +15 -14
  228. package/src/scenarios/frontend-plugin-packs.test.ts +29 -27
  229. package/src/scenarios/fs-path-traversal.test.ts +14 -12
  230. package/src/scenarios/goal-standing-continuation.test.ts +21 -21
  231. package/src/scenarios/grpc-transport.test.ts +9 -7
  232. package/src/scenarios/heartbeat-capability-shape.test.ts +3 -3
  233. package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +2 -2
  234. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +3 -3
  235. package/src/scenarios/heartbeat-runtime-bound.test.ts +2 -2
  236. package/src/scenarios/highConcurrency.test.ts +14 -13
  237. package/src/scenarios/host-callback-declaration.test.ts +8 -7
  238. package/src/scenarios/http-client-ssrf.test.ts +7 -5
  239. package/src/scenarios/i18n-negotiation.test.ts +14 -12
  240. package/src/scenarios/idempotency-concurrent-claim.test.ts +14 -13
  241. package/src/scenarios/idempotency-key-determinism.test.ts +20 -18
  242. package/src/scenarios/idempotency.test.ts +8 -7
  243. package/src/scenarios/idempotencyRetry.test.ts +13 -11
  244. package/src/scenarios/identity-owner-shape.test.ts +6 -5
  245. package/src/scenarios/identity-passthrough.test.ts +4 -3
  246. package/src/scenarios/interrupt-approval.test.ts +6 -5
  247. package/src/scenarios/interrupt-approver-routing.test.ts +15 -15
  248. package/src/scenarios/interrupt-auth-required-resume.test.ts +5 -3
  249. package/src/scenarios/interrupt-clarification.test.ts +4 -3
  250. package/src/scenarios/interrupt-external-event-correlation.test.ts +6 -5
  251. package/src/scenarios/interrupt-parent-child-cascade.test.ts +4 -3
  252. package/src/scenarios/interrupt-quorum-resolution.test.ts +5 -4
  253. package/src/scenarios/interrupt-token-matrix.test.ts +8 -6
  254. package/src/scenarios/interruptRace.test.ts +12 -10
  255. package/src/scenarios/kv-atomic-increment.test.ts +11 -9
  256. package/src/scenarios/kv-cas.test.ts +14 -12
  257. package/src/scenarios/kv-cross-tenant-isolation.test.ts +12 -10
  258. package/src/scenarios/kv-ttl-expiry.test.ts +7 -5
  259. package/src/scenarios/localized-content-delivery.test.ts +24 -26
  260. package/src/scenarios/maliciousManifest.test.ts +10 -8
  261. package/src/scenarios/mcp-2026-07-28-discover.test.ts +15 -14
  262. package/src/scenarios/mcp-cache-tenant-scope.test.ts +6 -5
  263. package/src/scenarios/mcp-current-auth-boundary.test.ts +7 -6
  264. package/src/scenarios/mcp-discoverability.test.ts +9 -7
  265. package/src/scenarios/mcp-extension-opacity.test.ts +7 -6
  266. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +18 -17
  267. package/src/scenarios/mcp-server-elicitation-bridge.test.ts +13 -12
  268. package/src/scenarios/mcp-server-prompt-roundtrip.test.ts +11 -10
  269. package/src/scenarios/mcp-server-resource-roundtrip.test.ts +11 -10
  270. package/src/scenarios/mcp-server-sampling-bridge.test.ts +12 -11
  271. package/src/scenarios/mcp-server-tool-roundtrip.test.ts +14 -13
  272. package/src/scenarios/mcp-server-untrusted-args.test.ts +14 -13
  273. package/src/scenarios/mcp-stateless-request.test.ts +11 -10
  274. package/src/scenarios/mcp-tool-roundtrip.test.ts +4 -3
  275. package/src/scenarios/mcp-toolcall-redaction.test.ts +4 -3
  276. package/src/scenarios/mcp-version-negotiation.test.ts +15 -14
  277. package/src/scenarios/media-url-inline-cap.test.ts +21 -19
  278. package/src/scenarios/memory-attribution-emits-on-write.test.ts +5 -5
  279. package/src/scenarios/memory-attribution-no-content.test.ts +4 -4
  280. package/src/scenarios/memory-attribution-replay-stable.test.ts +4 -3
  281. package/src/scenarios/memory-attribution-shape.test.ts +4 -3
  282. package/src/scenarios/memory-attribution-tenant-scoped.test.ts +3 -3
  283. package/src/scenarios/memory-capability-model-shape.test.ts +14 -15
  284. package/src/scenarios/memory-compaction-event-emitted.test.ts +7 -6
  285. package/src/scenarios/memory-compaction-provenance-tag.test.ts +3 -2
  286. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +7 -6
  287. package/src/scenarios/memory-consolidation-idempotent.test.ts +5 -4
  288. package/src/scenarios/memory-consolidation-shape.test.ts +9 -11
  289. package/src/scenarios/memory-degraded-projection.test.ts +10 -9
  290. package/src/scenarios/memory-injection-budget.test.ts +15 -14
  291. package/src/scenarios/metric-emission.test.ts +4 -3
  292. package/src/scenarios/model-capability-insufficient.test.ts +19 -17
  293. package/src/scenarios/model-capability-substituted.test.ts +20 -18
  294. package/src/scenarios/multi-agent-confidence-escalation.test.ts +12 -11
  295. package/src/scenarios/multi-agent-handoff-state-machine.test.ts +10 -9
  296. package/src/scenarios/multi-agent-memory-lifecycle.test.ts +11 -10
  297. package/src/scenarios/multi-node-ordering.test.ts +4 -3
  298. package/src/scenarios/multi-party-conversation-behavioral.test.ts +6 -6
  299. package/src/scenarios/multi-party-conversation-shape.test.ts +21 -23
  300. package/src/scenarios/multi-region-idempotency-behavior.test.ts +16 -15
  301. package/src/scenarios/multi-region-idempotency.test.ts +6 -5
  302. package/src/scenarios/node-failed-payload-shape.test.ts +5 -4
  303. package/src/scenarios/node-module-required-capabilities-shape.test.ts +10 -8
  304. package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +5 -4
  305. package/src/scenarios/oauth-capability-shape.test.ts +5 -4
  306. package/src/scenarios/oauth-connector-redaction.test.ts +4 -3
  307. package/src/scenarios/openapi-resolved-paths.test.ts +6 -5
  308. package/src/scenarios/orchestratorConservativePath.test.ts +2 -1
  309. package/src/scenarios/orchestratorDispatch.test.ts +2 -1
  310. package/src/scenarios/orchestratorTermination.test.ts +2 -1
  311. package/src/scenarios/org-position-no-authority-escalation.test.ts +2 -2
  312. package/src/scenarios/otel-collector-canary-inspection.test.ts +8 -7
  313. package/src/scenarios/otel-emission-grpc.test.ts +3 -2
  314. package/src/scenarios/otel-emission.test.ts +6 -5
  315. package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +7 -6
  316. package/src/scenarios/otel-trace-propagation.test.ts +2 -1
  317. package/src/scenarios/owner-subject-echo.test.ts +13 -12
  318. package/src/scenarios/owner-subject-shape.test.ts +11 -10
  319. package/src/scenarios/pack-manifest-extension-opacity.test.ts +8 -8
  320. package/src/scenarios/pack-registry-isolation.test.ts +4 -3
  321. package/src/scenarios/pack-registry-publish.test.ts +65 -63
  322. package/src/scenarios/pack-registry.test.ts +38 -36
  323. package/src/scenarios/pause-resume.test.ts +18 -16
  324. package/src/scenarios/policies.test.ts +20 -18
  325. package/src/scenarios/production-backpressure.test.ts +18 -16
  326. package/src/scenarios/production-retention-expiry.test.ts +8 -6
  327. package/src/scenarios/profile-discovery-core-alias.test.ts +13 -11
  328. package/src/scenarios/profileDerivation.test.ts +34 -33
  329. package/src/scenarios/prompt-all-four-kinds-events.test.ts +11 -9
  330. package/src/scenarios/prompt-composed-secret-redaction.test.ts +11 -9
  331. package/src/scenarios/prompt-composed-trust-marker.test.ts +10 -8
  332. package/src/scenarios/prompt-end-to-end-events.test.ts +17 -15
  333. package/src/scenarios/prompt-list-and-fetch.test.ts +16 -14
  334. package/src/scenarios/prompt-mutable-lifecycle.test.ts +13 -11
  335. package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +6 -4
  336. package/src/scenarios/prompt-pack-install.test.ts +14 -12
  337. package/src/scenarios/prompt-prefix-cache.test.ts +19 -17
  338. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +11 -9
  339. package/src/scenarios/prompt-render-deterministic.test.ts +19 -17
  340. package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +7 -5
  341. package/src/scenarios/prompt-resolution-chain-event.test.ts +12 -10
  342. package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +10 -8
  343. package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +8 -6
  344. package/src/scenarios/prompt-template-shape.test.ts +30 -28
  345. package/src/scenarios/proposal-reviewable-learning.test.ts +19 -19
  346. package/src/scenarios/protocol-versions-array.test.ts +10 -9
  347. package/src/scenarios/provider-usage.test.ts +17 -15
  348. package/src/scenarios/providerPolicyEnforcement.test.ts +16 -14
  349. package/src/scenarios/purpose-propagation.test.ts +23 -21
  350. package/src/scenarios/queue-ack-nack-dlq.test.ts +12 -10
  351. package/src/scenarios/queue-cross-tenant-isolation.test.ts +8 -6
  352. package/src/scenarios/queue-publish-consume-roundtrip.test.ts +10 -8
  353. package/src/scenarios/rate-limit-envelope.test.ts +6 -5
  354. package/src/scenarios/redaction.test.ts +13 -11
  355. package/src/scenarios/redactionAdversarial.test.ts +11 -9
  356. package/src/scenarios/registry-public.test.ts +12 -11
  357. package/src/scenarios/replay-divergence-at-refusal.test.ts +16 -15
  358. package/src/scenarios/replay-fanout-suppression.test.ts +16 -15
  359. package/src/scenarios/replay-fork-arbitrary.test.ts +24 -23
  360. package/src/scenarios/replay-fork.test.ts +20 -19
  361. package/src/scenarios/replay-llm-cache-key-portable.test.ts +11 -9
  362. package/src/scenarios/replay-llm-cache-key.test.ts +22 -21
  363. package/src/scenarios/replay-observable-sequence-determinism.test.ts +4 -3
  364. package/src/scenarios/replay-retention-expiry.test.ts +11 -9
  365. package/src/scenarios/replay-side-effect-suppression.test.ts +21 -19
  366. package/src/scenarios/replayDeterminism.test.ts +13 -12
  367. package/src/scenarios/requirement-ledger.test.ts +15 -14
  368. package/src/scenarios/restart-during-run.test.ts +3 -2
  369. package/src/scenarios/route-coverage.test.ts +20 -19
  370. package/src/scenarios/run-diff.test.ts +22 -20
  371. package/src/scenarios/run-execution-bounds-shape.test.ts +14 -12
  372. package/src/scenarios/run-transport-economy.test.ts +13 -11
  373. package/src/scenarios/runner-ledger.test.ts +17 -16
  374. package/src/scenarios/runs-lifecycle.test.ts +7 -6
  375. package/src/scenarios/runtime-capabilities.test.ts +12 -10
  376. package/src/scenarios/runtime-requires-install-gate.test.ts +8 -8
  377. package/src/scenarios/runtime-requires-shape.test.ts +7 -6
  378. package/src/scenarios/safefetch-behavior.test.ts +22 -21
  379. package/src/scenarios/safefetch-live-audit.test.ts +14 -13
  380. package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
  381. package/src/scenarios/sandbox-mvp-behavior.test.ts +24 -23
  382. package/src/scenarios/sandbox-no-host-fs-escape.test.ts +3 -2
  383. package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
  384. package/src/scenarios/sandbox-wasm-isolation.test.ts +14 -15
  385. package/src/scenarios/sandbox-wasm-timeout.test.ts +5 -6
  386. package/src/scenarios/scheduling-capability-shape.test.ts +8 -6
  387. package/src/scenarios/scheduling-cron-fires-once.test.ts +8 -6
  388. package/src/scenarios/search-bm25-roundtrip.test.ts +8 -6
  389. package/src/scenarios/secret-leakage-otel-attribute.test.ts +22 -20
  390. package/src/scenarios/self-hosted-runner.test.ts +26 -24
  391. package/src/scenarios/semantic-digest-vectors.test.ts +8 -7
  392. package/src/scenarios/speech-synthesis-roundtrip.test.ts +9 -7
  393. package/src/scenarios/speech-synthesis-unadvertised.test.ts +5 -3
  394. package/src/scenarios/sql-injection-rejection.test.ts +8 -6
  395. package/src/scenarios/sql-transaction-atomicity.test.ts +10 -8
  396. package/src/scenarios/staleClaim.test.ts +5 -4
  397. package/src/scenarios/stream-modes-buffer.test.ts +8 -7
  398. package/src/scenarios/stream-modes-mixed.test.ts +10 -9
  399. package/src/scenarios/stream-modes.test.ts +12 -11
  400. package/src/scenarios/stream-subscribe-from-beginning.test.ts +11 -9
  401. package/src/scenarios/stream-text-fixture.test.ts +14 -13
  402. package/src/scenarios/streamReconnect.test.ts +13 -11
  403. package/src/scenarios/strict-behavior-gate.test.ts +9 -8
  404. package/src/scenarios/subrun-approval-fail-closed.test.ts +2 -2
  405. package/src/scenarios/subrun-approval-gate.test.ts +3 -3
  406. package/src/scenarios/subrun-attestation-shape.test.ts +2 -2
  407. package/src/scenarios/subrun-checksum-stable.test.ts +4 -4
  408. package/src/scenarios/subworkflow-input-mapping.test.ts +16 -14
  409. package/src/scenarios/subworkflow.test.ts +10 -9
  410. package/src/scenarios/table-cross-tenant-isolation.test.ts +8 -6
  411. package/src/scenarios/table-cursor-pagination.test.ts +8 -6
  412. package/src/scenarios/table-schema-enforcement.test.ts +7 -5
  413. package/src/scenarios/test-seam-unauthenticated.test.ts +2 -2
  414. package/src/scenarios/tool-catalog-compact-projection.test.ts +10 -8
  415. package/src/scenarios/tool-catalog-projection.test.ts +11 -9
  416. package/src/scenarios/tool-descriptor-shape.test.ts +14 -15
  417. package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +3 -3
  418. package/src/scenarios/tool-hooks-content-free.test.ts +4 -4
  419. package/src/scenarios/tool-hooks-failure-honesty.test.ts +4 -4
  420. package/src/scenarios/tool-hooks-rate-limit.test.ts +2 -2
  421. package/src/scenarios/tool-hooks-secret-redaction.test.ts +2 -2
  422. package/src/scenarios/tool-hooks-shape.test.ts +3 -3
  423. package/src/scenarios/tool-session-lifecycle.test.ts +14 -13
  424. package/src/scenarios/trigger-bridge-delivery.test.ts +14 -14
  425. package/src/scenarios/trigger-bridge-shape.test.ts +19 -20
  426. package/src/scenarios/trigger-ingestion.test.ts +19 -17
  427. package/src/scenarios/trigger-stream-cdc-sources.test.ts +16 -14
  428. package/src/scenarios/v2-approver-enforced.test.ts +97 -0
  429. package/src/scenarios/v2-assurance-downgrade-audited.test.ts +75 -0
  430. package/src/scenarios/v2-bundle-v3-signed.test.ts +96 -0
  431. package/src/scenarios/v2-capabilities-root-closed.test.ts +63 -0
  432. package/src/scenarios/v2-capability-record-shape.test.ts +104 -0
  433. package/src/scenarios/v2-chain-pin-exact.test.ts +118 -0
  434. package/src/scenarios/v2-coherence-not-in-bundle.test.ts +98 -0
  435. package/src/scenarios/v2-compensation-read-projection.test.ts +85 -0
  436. package/src/scenarios/v2-configurable-closed.test.ts +67 -0
  437. package/src/scenarios/v2-dual-stack-negotiation.test.ts +118 -0
  438. package/src/scenarios/v2-effect-identity-business-key.test.ts +132 -0
  439. package/src/scenarios/v2-effect-seam-manifest.test.ts +163 -0
  440. package/src/scenarios/v2-enum-growth-rule.test.ts +69 -0
  441. package/src/scenarios/v2-era-key.test.ts +86 -0
  442. package/src/scenarios/v2-error-registry.test.ts +89 -0
  443. package/src/scenarios/v2-event-type-closed.test.ts +97 -0
  444. package/src/scenarios/v2-fork-a-v1-run.test.ts +109 -0
  445. package/src/scenarios/v2-form-when-reuses-edge-conditions.test.ts +70 -0
  446. package/src/scenarios/v2-header-scheme.test.ts +67 -0
  447. package/src/scenarios/v2-id-grammar.test.ts +77 -0
  448. package/src/scenarios/v2-idempotency-key-grammar.test.ts +65 -0
  449. package/src/scenarios/v2-interrupt-token-scheme.test.ts +55 -0
  450. package/src/scenarios/v2-lane-issuer-advertised.test.ts +62 -0
  451. package/src/scenarios/v2-legacy-profiles-absent.test.ts +78 -0
  452. package/src/scenarios/v2-manifest-ceiling-refused.test.ts +130 -0
  453. package/src/scenarios/v2-manifest-hatch-carried.test.ts +120 -0
  454. package/src/scenarios/v2-min-client-version.test.ts +48 -0
  455. package/src/scenarios/v2-minimum-version-refused.test.ts +141 -0
  456. package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +95 -0
  457. package/src/scenarios/v2-negotiation-authenticated.test.ts +125 -0
  458. package/src/scenarios/v2-negotiation-decided-emitted.test.ts +149 -0
  459. package/src/scenarios/v2-no-transport-advertisement.test.ts +57 -0
  460. package/src/scenarios/v2-owner-subject-required.test.ts +72 -0
  461. package/src/scenarios/v2-pack-isolation.test.ts +147 -0
  462. package/src/scenarios/v2-payload-registry-closed.test.ts +110 -0
  463. package/src/scenarios/v2-peer-dependency-declared.test.ts +132 -0
  464. package/src/scenarios/v2-pinned-run-disposition.test.ts +124 -0
  465. package/src/scenarios/v2-poll-cursor-v2.test.ts +114 -0
  466. package/src/scenarios/v2-preferred-version-default.test.ts +83 -0
  467. package/src/scenarios/v2-profiles-derived-only.test.ts +70 -0
  468. package/src/scenarios/v2-provider-conflict.test.ts +115 -0
  469. package/src/scenarios/v2-refresh-sla.test.ts +78 -0
  470. package/src/scenarios/v2-relaxation-recorded.test.ts +134 -0
  471. package/src/scenarios/v2-revocation-honored.test.ts +66 -0
  472. package/src/scenarios/v2-subject-link-record.test.ts +102 -0
  473. package/src/scenarios/v2-unmapped-type-refused.test.ts +95 -0
  474. package/src/scenarios/v2-v1-events-translated.test.ts +105 -0
  475. package/src/scenarios/v2-v1-signed-webhook-accepted.test.ts +109 -0
  476. package/src/scenarios/v2-webhook-durable-delivery.test.ts +238 -0
  477. package/src/scenarios/v2-well-known-one-resource.test.ts +129 -0
  478. package/src/scenarios/vector-knn-roundtrip.test.ts +9 -7
  479. package/src/scenarios/verifier-gating.test.ts +8 -6
  480. package/src/scenarios/version-fold.test.ts +9 -8
  481. package/src/scenarios/version-negotiation.test.ts +12 -11
  482. package/src/scenarios/voice-bargein-no-partial-leak.test.ts +8 -6
  483. package/src/scenarios/voice-event-payloads-shape.test.ts +10 -11
  484. package/src/scenarios/voice-interim-not-durable.test.ts +7 -5
  485. package/src/scenarios/voice-streamref-tenant-bound.test.ts +5 -3
  486. package/src/scenarios/voice-synthesis-streaming.test.ts +11 -9
  487. package/src/scenarios/voice-transcription-streaming.test.ts +8 -6
  488. package/src/scenarios/voice-transcription-unadvertised.test.ts +5 -3
  489. package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -2
  490. package/src/scenarios/wasm-pack-invoke-completed.test.ts +3 -2
  491. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +3 -2
  492. package/src/scenarios/wasm-pack-load.test.ts +4 -3
  493. package/src/scenarios/wasm-pack-memory-cap.test.ts +5 -4
  494. package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -1
  495. package/src/scenarios/webhook-negative.test.ts +11 -9
  496. package/src/scenarios/webhook-receiver-adversarial.test.ts +8 -7
  497. package/src/scenarios/webhook-sig-algorithm.test.ts +5 -3
  498. package/src/scenarios/webhook-signed-delivery.test.ts +16 -15
  499. package/src/scenarios/webhook-tenant-isolation.test.ts +16 -14
  500. package/src/scenarios/workflow-chain-deferred-parameters.test.ts +28 -30
  501. package/src/scenarios/workflow-chain-expansion.test.ts +21 -20
  502. package/src/scenarios/workflow-chain-host-expansion.test.ts +21 -20
  503. package/src/scenarios/workflow-chain-pack-manifest-validation.test.ts +14 -12
  504. package/src/scenarios/workflow-chain-pack-signature-verification.test.ts +5 -4
  505. package/src/scenarios/workflow-chain-unresolvable-typeid.test.ts +9 -8
  506. package/src/scenarios/workflow-primary-output-annotation.test.ts +7 -6
  507. package/src/scenarios/workflow-variable-format.test.ts +24 -24
  508. package/src/scenarios/workload-identity-behavior.test.ts +15 -13
  509. package/src/scenarios/workload-identity-chain-bounds.test.ts +18 -17
  510. package/src/scenarios/workspace-behavior.test.ts +19 -18
  511. package/src/scenarios/workspace-capability-shape.test.ts +3 -2
  512. package/src/scenarios/workspace-cross-tenant-isolation-blackbox.test.ts +6 -5
  513. package/src/scenarios/workspace-cross-tenant-isolation.test.ts +7 -6
  514. package/src/scenarios/x-openwop-form-pack-manifest.test.ts +8 -7
  515. package/src/setup.ts +44 -6
  516. package/vitest.config.ts +5 -1
  517. package/api/.redocly.lint-ignore.yaml +0 -22
  518. package/api/asyncapi.yaml +0 -834
  519. package/api/grpc/openwop.proto +0 -251
  520. package/api/openapi.yaml +0 -2693
  521. package/api/redocly.yaml +0 -23
  522. package/schemas/README.md +0 -144
  523. package/schemas/a2a-task-state.schema.json +0 -78
  524. package/schemas/a2ui-surface-delta-frame.schema.json +0 -48
  525. package/schemas/agent-deployment-transition.schema.json +0 -49
  526. package/schemas/agent-deployment.schema.json +0 -54
  527. package/schemas/agent-eval-suite.schema.json +0 -140
  528. package/schemas/agent-inventory-response.schema.json +0 -115
  529. package/schemas/agent-manifest.schema.json +0 -156
  530. package/schemas/agent-org-chart.schema.json +0 -82
  531. package/schemas/agent-ref.schema.json +0 -63
  532. package/schemas/agent-roster-entry.schema.json +0 -81
  533. package/schemas/agent-roster-response.schema.json +0 -21
  534. package/schemas/ai-envelope.schema.json +0 -134
  535. package/schemas/annotation-create.schema.json +0 -37
  536. package/schemas/annotation.schema.json +0 -56
  537. package/schemas/artifact-type-pack-manifest.schema.json +0 -244
  538. package/schemas/audit-verify-result.schema.json +0 -90
  539. package/schemas/budget-policy.schema.json +0 -18
  540. package/schemas/capabilities.schema.json +0 -4160
  541. package/schemas/certification-bundle-v2.schema.json +0 -118
  542. package/schemas/channel-presence-payload.schema.json +0 -41
  543. package/schemas/channel-written-payload.schema.json +0 -55
  544. package/schemas/chat-card-pack-manifest.schema.json +0 -253
  545. package/schemas/compact-tool-descriptor.schema.json +0 -51
  546. package/schemas/compensation-policy.schema.json +0 -64
  547. package/schemas/conformance-certification-bundle.schema.json +0 -86
  548. package/schemas/connection-pack-manifest.schema.json +0 -353
  549. package/schemas/conversation-event.schema.json +0 -168
  550. package/schemas/conversation-turn.schema.json +0 -117
  551. package/schemas/core-conformance-mock-agent-config.schema.json +0 -152
  552. package/schemas/credential-provenance.schema.json +0 -18
  553. package/schemas/credential-reference.schema.json +0 -21
  554. package/schemas/debug-bundle.schema.json +0 -196
  555. package/schemas/dispatch-config.schema.json +0 -112
  556. package/schemas/envelopes/clarification.request.schema.json +0 -52
  557. package/schemas/envelopes/error.schema.json +0 -30
  558. package/schemas/envelopes/media.audio.schema.json +0 -38
  559. package/schemas/envelopes/media.file.schema.json +0 -37
  560. package/schemas/envelopes/media.image.schema.json +0 -33
  561. package/schemas/envelopes/schema.request.schema.json +0 -26
  562. package/schemas/envelopes/schema.response.schema.json +0 -22
  563. package/schemas/envelopes/ui.a2ui-surface.schema.json +0 -154
  564. package/schemas/error-envelope.schema.json +0 -25
  565. package/schemas/eval-summary.schema.json +0 -92
  566. package/schemas/export-bundle.schema.json +0 -66
  567. package/schemas/form-content-pack-manifest.schema.json +0 -243
  568. package/schemas/frontend-plugin-manifest.schema.json +0 -109
  569. package/schemas/goal.schema.json +0 -104
  570. package/schemas/heartbeat-evaluated.schema.json +0 -14
  571. package/schemas/heartbeat-state-changed.schema.json +0 -14
  572. package/schemas/localized-content-language-settings.schema.json +0 -26
  573. package/schemas/localized-content-page-response.schema.json +0 -60
  574. package/schemas/localized-content-page.schema.json +0 -62
  575. package/schemas/localized-content-section.schema.json +0 -51
  576. package/schemas/memory-entry.schema.json +0 -36
  577. package/schemas/memory-list-options.schema.json +0 -37
  578. package/schemas/node-pack-manifest.schema.json +0 -654
  579. package/schemas/orchestrator-decision.schema.json +0 -90
  580. package/schemas/org-chart-responsibility-view.schema.json +0 -26
  581. package/schemas/pack-lockfile.schema.json +0 -108
  582. package/schemas/prompt-kind.schema.json +0 -8
  583. package/schemas/prompt-pack-manifest.schema.json +0 -117
  584. package/schemas/prompt-ref.schema.json +0 -40
  585. package/schemas/prompt-template.schema.json +0 -149
  586. package/schemas/proposal.schema.json +0 -84
  587. package/schemas/registry-version-manifest.schema.json +0 -208
  588. package/schemas/residency.schema.json +0 -16
  589. package/schemas/run-ancestry-response.schema.json +0 -54
  590. package/schemas/run-diff-response.schema.json +0 -64
  591. package/schemas/run-event-payloads.schema.json +0 -4452
  592. package/schemas/run-event.schema.json +0 -211
  593. package/schemas/run-options.schema.json +0 -80
  594. package/schemas/run-orchestrator-decided-event.schema.json +0 -20
  595. package/schemas/run-snapshot.schema.json +0 -148
  596. package/schemas/security-advisory.schema.json +0 -109
  597. package/schemas/self-hosted-runner-dispatch-frame.schema.json +0 -79
  598. package/schemas/self-hosted-runner-registration.schema.json +0 -53
  599. package/schemas/self-hosted-runner-result-frame.schema.json +0 -38
  600. package/schemas/subject.schema.json +0 -56
  601. package/schemas/suspend-request.schema.json +0 -207
  602. package/schemas/tool-descriptor.schema.json +0 -63
  603. package/schemas/trigger-event.schema.json +0 -222
  604. package/schemas/trigger-subscription-registration.schema.json +0 -67
  605. package/schemas/trigger-subscription.schema.json +0 -26
  606. package/schemas/ui-plugin-message.schema.json +0 -90
  607. package/schemas/workflow-chain-pack-manifest.schema.json +0 -615
  608. package/schemas/workflow-definition.schema.json +0 -850
  609. package/schemas/workload-identity.schema.json +0 -79
  610. package/schemas/workspace-file-create.schema.json +0 -20
  611. package/schemas/workspace-file.schema.json +0 -39
@@ -30,9 +30,8 @@ import Ajv2020 from 'ajv/dist/2020.js';
30
30
  import addFormats from 'ajv-formats';
31
31
  import { driver } from '../lib/driver.js';
32
32
  import { SCHEMAS_DIR } from '../lib/paths.js';
33
-
34
- /** Server-free assertion-message helper (mirrors driver.describe's "spec — requirement" shape without requiring OPENWOP_BASE_URL — used in the always-on shape group). */
35
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
33
+ import { req } from '../lib/requirement-ids.js';
34
+ import { softSkip } from '../lib/soft-skip.js';
36
35
 
37
36
  interface AuthModeCapabilities {
38
37
  aiProviders?: {
@@ -70,9 +69,9 @@ describe('byok-auth-modes: schema shape (RFC 0067, server-free)', () => {
70
69
  | undefined;
71
70
  expect(
72
71
  authModes,
73
- why('capabilities.md §aiProviders.authModes', 'the schema MUST declare aiProviders.authModes'),
72
+ req('openwop.it.byok-auth-modes.the-capabilities-schema-declares-aiproviders-authmodes-with-the-five-mode-enum', 'capabilities.md §aiProviders.authModes', 'the schema MUST declare aiProviders.authModes'),
74
73
  ).toBeDefined();
75
- expect(authModes?.additionalProperties?.items?.enum).toEqual([
74
+ expect(authModes?.additionalProperties?.items?.enum, req('openwop.it.byok-auth-modes.the-capabilities-schema-declares-aiproviders-authmodes-with-the-five-mode-enum', 'RFC 0067', 'the capabilities schema declares aiProviders.authModes with the five-mode enum')).toEqual([
76
75
  'apiKey',
77
76
  'oauth-pkce',
78
77
  'oauth-device',
@@ -85,10 +84,10 @@ describe('byok-auth-modes: schema shape (RFC 0067, server-free)', () => {
85
84
  const validate = authModesValidator();
86
85
  expect(
87
86
  validate({ anthropic: ['apiKey'], vertex: ['oauth-pkce'], ollama: ['none'] }),
88
- why('RFC 0067 §A', 'a conforming authModes map MUST validate'),
87
+ req('openwop.it.byok-auth-modes.a-conforming-authmodes-map-validates-malformed-maps-are-rejected', 'RFC 0067 §A', 'a conforming authModes map MUST validate'),
89
88
  ).toBe(true);
90
89
  // Negative: empty array fails minItems.
91
- expect(validate({ anthropic: [] })).toBe(false);
90
+ expect(validate({ anthropic: [] }), req('openwop.it.byok-auth-modes.a-conforming-authmodes-map-validates-malformed-maps-are-rejected', 'RFC 0067', 'a conforming authModes map validates; malformed maps are rejected')).toBe(false);
92
91
  // Negative: unknown mode (`device` — canonical is `oauth-device`) fails the enum.
93
92
  expect(validate({ anthropic: ['device'] })).toBe(false);
94
93
  });
@@ -97,10 +96,10 @@ describe('byok-auth-modes: schema shape (RFC 0067, server-free)', () => {
97
96
  describe('byok-auth-modes: cross-field consistency (gated on advertisement)', () => {
98
97
  it('a host advertising authModes MUST satisfy the §B contract', async () => {
99
98
  const res = await driver.get('/.well-known/openwop', { authenticated: false });
100
- if (res.status !== 200) return; // discovery unavailable — skip cleanly
99
+ if (res.status !== 200) return softSkip('blocked', 'precondition not met — `res.status !== 200` returned early (discovery unavailable — skip cleanly) (seam, prior step, or fixture unavailable)'); // discovery unavailable — skip cleanly
101
100
  const caps = res.json as AuthModeCapabilities;
102
101
  const authModes = caps.aiProviders?.authModes;
103
- if (!authModes) return; // host does not advertise authModes — gated skip
102
+ if (!authModes) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!authModes` returned early (host does not advertise authModes — gated skip)'); // host does not advertise authModes — gated skip
104
103
 
105
104
  const supported = new Set(caps.aiProviders?.supported ?? []);
106
105
  const byok = new Set(caps.aiProviders?.byok ?? []);
@@ -110,14 +109,14 @@ describe('byok-auth-modes: cross-field consistency (gated on advertisement)', ()
110
109
  // §B.1 — every key is in `supported`.
111
110
  expect(
112
111
  supported.has(provider),
113
- driver.describe('RFC 0067 §B.1', `authModes key '${provider}' MUST appear in aiProviders.supported`),
112
+ req('openwop.it.byok-auth-modes.a-host-advertising-authmodes-must-satisfy-the-b-contract', 'RFC 0067 §B.1', `authModes key '${provider}' MUST appear in aiProviders.supported`),
114
113
  ).toBe(true);
115
114
 
116
115
  // §B.2 — an `apiKey` provider is in `byok`.
117
116
  if (modes.includes('apiKey')) {
118
117
  expect(
119
118
  byok.has(provider),
120
- driver.describe('RFC 0067 §B.2', `provider '${provider}' with apiKey MUST appear in aiProviders.byok`),
119
+ req('openwop.it.byok-auth-modes.a-host-advertising-authmodes-must-satisfy-the-b-contract', 'RFC 0067 §B.2', `provider '${provider}' with apiKey MUST appear in aiProviders.byok`),
121
120
  ).toBe(true);
122
121
  }
123
122
 
@@ -125,7 +124,7 @@ describe('byok-auth-modes: cross-field consistency (gated on advertisement)', ()
125
124
  if (modes.includes('subscription')) {
126
125
  expect(
127
126
  byok.has(provider),
128
- driver.describe('RFC 0121 §B.7', `provider '${provider}' with subscription MUST appear in aiProviders.byok`),
127
+ req('openwop.it.byok-auth-modes.a-host-advertising-authmodes-must-satisfy-the-b-contract', 'RFC 0121 §B.7', `provider '${provider}' with subscription MUST appear in aiProviders.byok`),
129
128
  ).toBe(true);
130
129
  }
131
130
 
@@ -133,7 +132,7 @@ describe('byok-auth-modes: cross-field consistency (gated on advertisement)', ()
133
132
  if (modes.length === 1 && modes[0] === 'none') {
134
133
  expect(
135
134
  byok.has(provider),
136
- driver.describe('RFC 0067 §B.3', `provider '${provider}' with modes ["none"] MUST NOT appear in aiProviders.byok`),
135
+ req('openwop.it.byok-auth-modes.a-host-advertising-authmodes-must-satisfy-the-b-contract', 'RFC 0067 §B.3', `provider '${provider}' with modes ["none"] MUST NOT appear in aiProviders.byok`),
137
136
  ).toBe(false);
138
137
  }
139
138
 
@@ -142,7 +141,7 @@ describe('byok-auth-modes: cross-field consistency (gated on advertisement)', ()
142
141
  if ((modes.includes('oauth-pkce') || modes.includes('oauth-device')) && oauthIds.size > 0) {
143
142
  expect(
144
143
  oauthIds.has(provider),
145
- driver.describe('RFC 0067 §B.4', `oauth provider '${provider}' SHOULD have a matching capabilities.oauth.providers[].id`),
144
+ req('openwop.it.byok-auth-modes.a-host-advertising-authmodes-must-satisfy-the-b-contract', 'RFC 0067 §B.4', `oauth provider '${provider}' SHOULD have a matching capabilities.oauth.providers[].id`),
146
145
  ).toBe(true);
147
146
  }
148
147
  }
@@ -26,6 +26,8 @@ import { describe, it, expect } from 'vitest';
26
26
  import { driver } from '../lib/driver.js';
27
27
  import { pollUntilTerminal } from '../lib/polling.js';
28
28
  import { isFixtureAdvertised } from '../lib/fixtures.js';
29
+ import { req } from '../lib/requirement-ids.js';
30
+ import { softSkip } from '../lib/soft-skip.js';
29
31
 
30
32
  /** SHA-256 hex regex — 64 lowercase hex chars exactly. */
31
33
  const SHA256_HEX_RE = /^[0-9a-f]{64}$/;
@@ -42,17 +44,17 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
42
44
  // Fixture absent OR canary not provisioned — host doesn't opt in.
43
45
  // Scenario passes trivially.
44
46
  if (create.status === 404 || create.status === 422) {
45
- return;
47
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `create.status === 404 || create.status === 422` returned early (Fixture absent OR canary not provisioned — host doesn\'t opt in. Scenario passes trivially.)');
46
48
  }
47
49
 
48
- expect(create.status, driver.describe(
50
+ expect(create.status, req('openwop.it.byok-roundtrip.the-canary-fixture-run-must-resolve-a-host-provisioned-secret-and-emit-sha-256-h',
49
51
  'rest-endpoints.md POST /v1/runs',
50
52
  'starting openwop-smoke-byok-roundtrip MUST succeed when OPENWOP_CONFORMANCE_FIXTURES=1 is advertised AND openwop-conformance-canary-secret is provisioned',
51
53
  )).toBe(201);
52
54
  const runId = (create.json as { runId: string }).runId;
53
55
 
54
56
  const terminal = await pollUntilTerminal(runId);
55
- expect(terminal.status, driver.describe(
57
+ expect(terminal.status, req('openwop.it.byok-roundtrip.the-canary-fixture-run-must-resolve-a-host-provisioned-secret-and-emit-sha-256-h',
56
58
  'auth.md §"Secret resolution"',
57
59
  'BYOK fixture run MUST reach terminal completed when canary is provisioned',
58
60
  )).toBe('completed');
@@ -79,17 +81,17 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
79
81
  // Host doesn't expose node outputs in variables/outputs map —
80
82
  // some hosts only expose them on the events stream. Skip the
81
83
  // shape check; the run-completed assertion above is sufficient.
82
- return;
84
+ return softSkip('blocked', 'precondition not met — `!candidate || typeof candidate !== \'object\'` returned early (Host doesn\'t expose node outputs in variables/outputs map — some hosts only expose them on the events stream. Skip the shape check; …');
83
85
  }
84
86
 
85
87
  if ('secretSha256' in candidate && typeof candidate.secretSha256 === 'string') {
86
- expect(candidate.secretSha256, driver.describe(
88
+ expect(candidate.secretSha256, req('openwop.it.byok-roundtrip.the-canary-fixture-run-must-resolve-a-host-provisioned-secret-and-emit-sha-256-h',
87
89
  'auth.md §"Secret resolution"',
88
90
  'fixture-emitted SHA-256 hex MUST be 64 lowercase hex chars',
89
91
  )).toMatch(SHA256_HEX_RE);
90
92
  }
91
93
  if ('secretLength' in candidate && typeof candidate.secretLength === 'number') {
92
- expect(candidate.secretLength, driver.describe(
94
+ expect(candidate.secretLength, req('openwop.it.byok-roundtrip.the-canary-fixture-run-must-resolve-a-host-provisioned-secret-and-emit-sha-256-h',
93
95
  'auth.md §"Secret resolution"',
94
96
  'resolved canary length MUST be > 0 (non-empty)',
95
97
  )).toBeGreaterThan(0);
@@ -101,7 +103,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
101
103
  workflowId: 'openwop-smoke-byok-roundtrip',
102
104
  });
103
105
  if (create.status === 404 || create.status === 422) {
104
- return;
106
+ return softSkip('blocked', 'precondition not met — `create.status === 404 || create.status === 422` returned early (seam, prior step, or fixture unavailable)');
105
107
  }
106
108
  expect(create.status).toBe(201);
107
109
  const runId = (create.json as { runId: string }).runId;
@@ -116,7 +118,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
116
118
  const completed = events.filter(
117
119
  (e) => e.type === 'node.completed' && e.nodeId === 'resolve-secret',
118
120
  );
119
- expect(completed.length, driver.describe(
121
+ expect(completed.length, req('openwop.it.byok-roundtrip.byok-fixture-run-must-emit-a-node-completed-event-for-the-resolve-step',
120
122
  'event-log.md §node.completed',
121
123
  'BYOK fixture node MUST emit exactly one node.completed event when secrets.resolve succeeds',
122
124
  )).toBe(1);
@@ -127,7 +129,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
127
129
  workflowId: 'openwop-smoke-byok-roundtrip',
128
130
  });
129
131
  if (create.status === 404 || create.status === 422) {
130
- return;
132
+ return softSkip('blocked', 'precondition not met — `create.status === 404 || create.status === 422` returned early (seam, prior step, or fixture unavailable)');
131
133
  }
132
134
  expect(create.status).toBe(201);
133
135
  const runId = (create.json as { runId: string }).runId;
@@ -157,7 +159,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('byok: end-to-end credentialRef resolution roun
157
159
  /"raw_secret"\s*:\s*"[^"]{8,}"/,
158
160
  ];
159
161
  for (const pat of suspiciousPatterns) {
160
- expect(dump, driver.describe(
162
+ expect(dump, req('openwop.it.byok-roundtrip.byok-fixture-run-event-log-must-not-echo-the-resolved-secret-value-redaction',
161
163
  'observability.md §"Redaction"',
162
164
  `event log MUST NOT contain a payload matching ${pat} — secret.echo fixture only emits hash + length`,
163
165
  )).not.toMatch(pat);
@@ -10,6 +10,8 @@
10
10
  import { describe, it, expect } from 'vitest';
11
11
  import { driver } from '../lib/driver.js';
12
12
  import { discoveryFamilies } from '../lib/discovery-capabilities.js';
13
+ import { req } from '../lib/requirement-ids.js';
14
+ import { softSkip } from '../lib/soft-skip.js';
13
15
 
14
16
  interface DiscoveryDoc {
15
17
  capabilities?: Record<string, unknown>;
@@ -30,10 +32,10 @@ async function call(tenantId: string, op: string, args: Record<string, unknown>)
30
32
  describe('cache-cross-tenant-isolation: advertisement shape (RFC 0019)', () => {
31
33
  it('capabilities.cache is either absent or a well-formed object', async () => {
32
34
  const cap = await readCap();
33
- if (cap === null) return;
35
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early');
34
36
  expect(
35
37
  typeof cap.supported,
36
- driver.describe(
38
+ req('openwop.it.cache-cross-tenant-isolation.capabilities-cache-is-either-absent-or-a-well-formed-object',
37
39
  'capabilities.schema.json §cache',
38
40
  'capabilities.cache.supported MUST be a boolean when present',
39
41
  ),
@@ -44,19 +46,19 @@ describe('cache-cross-tenant-isolation: advertisement shape (RFC 0019)', () => {
44
46
  describe('cache-cross-tenant-isolation: behavioral (RFC 0019 §B point 2)', () => {
45
47
  it('put under tenant A → get under tenant B returns miss', async () => {
46
48
  const cap = await readCap();
47
- if (!cap || cap.supported !== true) return;
49
+ if (!cap || cap.supported !== true) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!cap || cap.supported !== true` returned early');
48
50
  const key = `xtenant-cache-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
49
51
 
50
52
  const putRes = await call('tenant-a', 'put', { key, value: 'from-A', ttlSeconds: 60 });
51
- if (putRes.status === 404) return;
52
- expect(putRes.status, 'put MUST succeed').toBe(200);
53
+ if (putRes.status === 404) return softSkip('blocked', 'precondition not met — `putRes.status === 404` returned early (seam, prior step, or fixture unavailable)');
54
+ expect(putRes.status, req('openwop.it.cache-cross-tenant-isolation.put-under-tenant-a-get-under-tenant-b-returns-miss', 'RFC 0019 §B point 2', 'put MUST succeed')).toBe(200);
53
55
 
54
56
  const getRes = await call('tenant-b', 'get', { key });
55
57
  expect(getRes.status).toBe(200);
56
58
  const body = getRes.json as { hit?: boolean };
57
59
  expect(
58
60
  body.hit,
59
- driver.describe('RFC 0019 §B point 2', 'tenant B MUST NOT hit tenant A cache entry at same key'),
61
+ req('openwop.it.cache-cross-tenant-isolation.put-under-tenant-a-get-under-tenant-b-returns-miss', 'RFC 0019 §B point 2', 'tenant B MUST NOT hit tenant A cache entry at same key'),
60
62
  ).toBe(false);
61
63
  });
62
64
  });
@@ -16,6 +16,8 @@
16
16
  import { describe, it, expect } from 'vitest';
17
17
  import { driver } from '../lib/driver.js';
18
18
  import { discoveryFamilies } from '../lib/discovery-capabilities.js';
19
+ import { req } from '../lib/requirement-ids.js';
20
+ import { softSkip } from '../lib/soft-skip.js';
19
21
 
20
22
  interface DiscoveryDoc {
21
23
  capabilities?: Record<string, unknown>;
@@ -32,10 +34,10 @@ async function readCap(): Promise<Record<string, unknown> | null> {
32
34
  describe('cache-ttl-expiry: advertisement shape (RFC 0019)', () => {
33
35
  it('capabilities.cache is either absent or a well-formed object', async () => {
34
36
  const cap = await readCap();
35
- if (cap === null) return; // host doesn't advertise — skip
37
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early (host doesn\'t advertise — skip)'); // host doesn't advertise — skip
36
38
  expect(
37
39
  typeof cap.supported,
38
- driver.describe(
40
+ req('openwop.it.cache-ttl-expiry.capabilities-cache-is-either-absent-or-a-well-formed-object',
39
41
  'capabilities.schema.json §cache',
40
42
  'capabilities.cache.supported MUST be a boolean when present',
41
43
  ),
@@ -50,7 +52,7 @@ async function call(op: string, args: Record<string, unknown>) {
50
52
  describe('cache-ttl-expiry: behavioral (RFC 0019 §B point 2 — 1s TTL drift)', () => {
51
53
  it('put with ttlSeconds=2 → hit within window; miss after expiry', async () => {
52
54
  const probe = await call('get', { key: '__cache-probe__' });
53
- if (probe.status === 404) return;
55
+ if (probe.status === 404) return softSkip('blocked', 'precondition not met — `probe.status === 404` returned early (seam, prior step, or fixture unavailable)');
54
56
  const key = `c-ttl-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
55
57
  const putRes = await call('put', { key, value: 'evicts-soon', ttlSeconds: 2 });
56
58
  expect(putRes.status).toBe(200);
@@ -59,7 +61,7 @@ describe('cache-ttl-expiry: behavioral (RFC 0019 §B point 2 — 1s TTL drift)',
59
61
  const withinBody = within.json as { value?: unknown; found?: boolean };
60
62
  expect(
61
63
  withinBody.value,
62
- driver.describe('RFC 0019 §B point 2', 'cache get within TTL MUST return the stored value'),
64
+ req('openwop.it.cache-ttl-expiry.put-with-ttlseconds-2-hit-within-window-miss-after-expiry', 'RFC 0019 §B point 2', 'cache get within TTL MUST return the stored value'),
63
65
  ).toBe('evicts-soon');
64
66
 
65
67
  await new Promise((r) => setTimeout(r, 3000));
@@ -68,7 +70,7 @@ describe('cache-ttl-expiry: behavioral (RFC 0019 §B point 2 — 1s TTL drift)',
68
70
  const afterBody = after.json as { value?: unknown; found?: boolean };
69
71
  expect(
70
72
  afterBody.found,
71
- driver.describe('RFC 0019 §B point 2', 'cache get after TTL expiry MUST surface as found:false (≤1s drift)'),
73
+ req('openwop.it.cache-ttl-expiry.put-with-ttlseconds-2-hit-within-window-miss-after-expiry', 'RFC 0019 §B point 2', 'cache get after TTL expiry MUST surface as found:false (≤1s drift)'),
72
74
  ).toBe(false);
73
75
  });
74
76
  });
@@ -22,6 +22,8 @@ import { describe, it, expect } from 'vitest';
22
22
  import { driver } from '../lib/driver.js';
23
23
  import { behaviorGate } from '../lib/behavior-gate.js';
24
24
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
25
+ import { req } from '../lib/requirement-ids.js';
26
+ import { softSkip } from '../lib/soft-skip.js';
25
27
 
26
28
  const ALL_MODALITIES = ['text', 'image', 'audio', 'document'];
27
29
 
@@ -60,10 +62,10 @@ describe('callai-multimodal (RFC 0091 §A/§B)', () => {
60
62
  const okRes = await driver.post(SEAM, {
61
63
  messages: [{ role: 'user', content: [{ type: 'text', text: 'describe this' }, okPart] }],
62
64
  });
63
- if (okRes.status === 404) return; // seam unwired — soft-skip the whole behavioral suite
65
+ if (okRes.status === 404) return softSkip('blocked', 'precondition not met — `okRes.status === 404` returned early (seam unwired — soft-skip the whole behavioral suite) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip the whole behavioral suite
64
66
  expect(
65
67
  errCode(okRes.json) !== 'unsupported_modality',
66
- driver.describe('RFC 0091 §B', `an advertised modality (${accepted}) MUST NOT be rejected as unsupported_modality`),
68
+ req('openwop.it.callai-multimodal.accepts-an-advertised-non-text-modality-and-rejects-an-unadvertised-one-with-uns', 'RFC 0091 §B', `an advertised modality (${accepted}) MUST NOT be rejected as unsupported_modality`),
67
69
  ).toBe(true);
68
70
 
69
71
  // 2) An unadvertised modality MUST be rejected with unsupported_modality.
@@ -79,7 +81,7 @@ describe('callai-multimodal (RFC 0091 §A/§B)', () => {
79
81
  });
80
82
  expect(
81
83
  errCode(badRes.json) === 'unsupported_modality',
82
- driver.describe('RFC 0091 §A', `an unadvertised modality (${unadvertised}) MUST be rejected with unsupported_modality (never silently dropped)`),
84
+ req('openwop.it.callai-multimodal.accepts-an-advertised-non-text-modality-and-rejects-an-unadvertised-one-with-uns', 'RFC 0091 §A', `an unadvertised modality (${unadvertised}) MUST be rejected with unsupported_modality (never silently dropped)`),
83
85
  ).toBe(true);
84
86
  }
85
87
  });
@@ -11,6 +11,7 @@ import { describe, it, expect } from 'vitest';
11
11
  import { driver } from '../lib/driver.js';
12
12
  import { pollUntilStatus } from '../lib/polling.js';
13
13
  import { isFixtureAdvertised } from '../lib/fixtures.js';
14
+ import { req } from '../lib/requirement-ids.js';
14
15
 
15
16
  const WORKFLOW_ID = 'conformance-cancellable';
16
17
  const SKIP_NO_FIXTURE = !isFixtureAdvertised(WORKFLOW_ID);
@@ -21,7 +22,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('cancellation: in-flight :cancel reaches termin
21
22
  workflowId: WORKFLOW_ID,
22
23
  inputs: { delayMs: 10_000 },
23
24
  });
24
- expect(create.status, driver.describe(
25
+ expect(create.status, req('openwop.it.cancellation.post-v1-runs-runid-cancel-returns-200-and-run-terminates-as-cancelled',
25
26
  'rest-endpoints.md',
26
27
  'POST /v1/runs MUST return 201 on accepted run',
27
28
  )).toBe(201);
@@ -35,7 +36,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('cancellation: in-flight :cancel reaches termin
35
36
  `/v1/runs/${encodeURIComponent(runId)}/cancel`,
36
37
  { reason: 'conformance-cancellation-test' },
37
38
  );
38
- expect(cancel.status, driver.describe(
39
+ expect(cancel.status, req('openwop.it.cancellation.post-v1-runs-runid-cancel-returns-200-and-run-terminates-as-cancelled',
39
40
  'rest-endpoints.md POST /v1/runs/{runId}/cancel',
40
41
  'cancel MUST return 200 on accepted cancellation',
41
42
  )).toBe(200);
@@ -43,14 +44,14 @@ describe.skipIf(SKIP_NO_FIXTURE)('cancellation: in-flight :cancel reaches termin
43
44
  const cancelBody = cancel.json as { status?: string };
44
45
  expect(
45
46
  ['cancelled', 'cancelling'].includes(cancelBody.status ?? ''),
46
- driver.describe(
47
+ req('openwop.it.cancellation.post-v1-runs-runid-cancel-returns-200-and-run-terminates-as-cancelled',
47
48
  'rest-endpoints.md POST /v1/runs/{runId}/cancel',
48
49
  'cancel response status MUST be one of `cancelled` or `cancelling`',
49
50
  ),
50
51
  ).toBe(true);
51
52
 
52
53
  const terminal = await pollUntilStatus(runId, 'cancelled', { timeoutMs: 5_000 });
53
- expect(terminal.status, driver.describe(
54
+ expect(terminal.status, req('openwop.it.cancellation.post-v1-runs-runid-cancel-returns-200-and-run-terminates-as-cancelled',
54
55
  'fixtures.md conformance-cancellable §Terminal status',
55
56
  'fixture MUST reach terminal `cancelled` within 5s of cancel',
56
57
  )).toBe('cancelled');
@@ -62,7 +63,7 @@ describe('cancellation: cancelling an unknown run returns 404', () => {
62
63
  const res = await driver.post('/v1/runs/openwop-conformance-no-such-run/cancel', {});
63
64
  expect(
64
65
  [403, 404].includes(res.status),
65
- driver.describe('rest-endpoints.md', 'cancel on unknown run MUST return 404 or 403'),
66
+ req('openwop.it.cancellation.post-v1-runs-nonexistentid-cancel-returns-404', 'rest-endpoints.md', 'cancel on unknown run MUST return 404 or 403'),
66
67
  ).toBe(true);
67
68
  });
68
69
  });
@@ -22,6 +22,7 @@ import { describe, it, expect } from 'vitest';
22
22
  import { driver } from '../lib/driver.js';
23
23
  import { pollUntilTerminal } from '../lib/polling.js';
24
24
  import { isFixtureAdvertised } from '../lib/fixtures.js';
25
+ import { req } from '../lib/requirement-ids.js';
25
26
 
26
27
  const WORKFLOW_ID = 'conformance-cap-breach';
27
28
  const RECURSION_LIMIT = 3;
@@ -42,7 +43,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
42
43
  workflowId: WORKFLOW_ID,
43
44
  configurable: { recursionLimit: RECURSION_LIMIT },
44
45
  });
45
- expect(create.status, driver.describe(
46
+ expect(create.status, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
46
47
  'rest-endpoints.md POST /v1/runs',
47
48
  'run creation MUST accept the request even when configurable.recursionLimit is below the workflow size',
48
49
  )).toBe(201);
@@ -50,17 +51,17 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
50
51
 
51
52
  const terminal = await pollUntilTerminal(runId);
52
53
 
53
- expect(terminal.status, driver.describe(
54
+ expect(terminal.status, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
54
55
  'fixtures.md conformance-cap-breach §Terminal status',
55
56
  'fixture MUST reach terminal `failed` when recursion limit is exceeded',
56
57
  )).toBe('failed');
57
58
 
58
- expect(terminal.error?.code, driver.describe(
59
+ expect(terminal.error?.code, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
59
60
  'run-options.md §recursionLimit',
60
61
  'RunSnapshot.error.code MUST equal "recursion_limit_exceeded"',
61
62
  )).toBe('recursion_limit_exceeded');
62
63
 
63
- expect(typeof terminal.error?.message, driver.describe(
64
+ expect(typeof terminal.error?.message, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
64
65
  'rest-endpoints.md RunSnapshot.error.message',
65
66
  'RunSnapshot.error.message MUST be a string',
66
67
  )).toBe('string');
@@ -72,7 +73,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
72
73
  const events = (eventsRes.json as { events?: RunEvent[] } | undefined)?.events ?? [];
73
74
 
74
75
  const capBreachEvents = events.filter((e) => e.type === 'cap.breached');
75
- expect(capBreachEvents.length, driver.describe(
76
+ expect(capBreachEvents.length, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
76
77
  'observability.md §cap.breached',
77
78
  'exactly one cap.breached event MUST be emitted on recursion-limit exceedance',
78
79
  )).toBe(1);
@@ -82,23 +83,23 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
82
83
  | { kind?: string; limit?: number; observed?: number; nodeId?: string }
83
84
  | undefined;
84
85
 
85
- expect(payload?.kind, driver.describe(
86
+ expect(payload?.kind, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
86
87
  'run-event-payloads.schema.json §capBreached.kind',
87
88
  'cap.breached payload MUST carry kind="node-executions"',
88
89
  )).toBe('node-executions');
89
90
 
90
- expect(payload?.limit, driver.describe(
91
+ expect(payload?.limit, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
91
92
  'run-event-payloads.schema.json §capBreached.limit',
92
93
  'cap.breached payload MUST carry the resolved limit (3 from configurable.recursionLimit)',
93
94
  )).toBe(RECURSION_LIMIT);
94
95
 
95
- expect(typeof payload?.observed, driver.describe(
96
+ expect(typeof payload?.observed, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
96
97
  'run-event-payloads.schema.json §capBreached.observed',
97
98
  'cap.breached payload MUST carry the observed count as a number',
98
99
  )).toBe('number');
99
100
  expect(payload?.observed).toBeGreaterThan(RECURSION_LIMIT);
100
101
 
101
- expect(typeof payload?.nodeId, driver.describe(
102
+ expect(typeof payload?.nodeId, req('openwop.it.cap-breach.emits-cap-breached-transitions-to-terminal-failed-when-configurable-recursionlim',
102
103
  'run-event-payloads.schema.json §capBreached.nodeId',
103
104
  'cap.breached payload MUST carry the offending nodeId for node-executions kind',
104
105
  )).toBe('string');
@@ -121,10 +122,10 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
121
122
  const capBreach = events.find((e) => e.type === 'cap.breached');
122
123
  const runFailed = events.find((e) => e.type === 'run.failed');
123
124
 
124
- expect(capBreach, 'cap.breached MUST be emitted').toBeDefined();
125
- expect(runFailed, 'run.failed MUST be emitted').toBeDefined();
125
+ expect(capBreach, req('openwop.it.cap-breach.cap-breached-precedes-run-failed-in-the-event-sequence-breach-detected-before-ov', 'observability.md §event ordering', 'cap.breached MUST be emitted')).toBeDefined();
126
+ expect(runFailed, req('openwop.it.cap-breach.cap-breached-precedes-run-failed-in-the-event-sequence-breach-detected-before-ov', 'observability.md §event ordering', 'run.failed MUST be emitted')).toBeDefined();
126
127
 
127
- expect(capBreach!.sequence, driver.describe(
128
+ expect(capBreach!.sequence, req('openwop.it.cap-breach.cap-breached-precedes-run-failed-in-the-event-sequence-breach-detected-before-ov',
128
129
  'observability.md §event ordering',
129
130
  'cap.breached MUST precede run.failed in sequence (breach detected BEFORE over-limit node fires)',
130
131
  )).toBeLessThan(runFailed!.sequence);
@@ -137,11 +138,11 @@ describe.skipIf(SKIP_NO_FIXTURE)('cap-breach: conformance-cap-breach fixture fai
137
138
  // short) — those would emit fewer than `RECURSION_LIMIT` started
138
139
  // events while still satisfying the invariant.
139
140
  const nodeStarted = events.filter((e) => e.type === 'node.started');
140
- expect(nodeStarted.length, driver.describe(
141
+ expect(nodeStarted.length, req('openwop.it.cap-breach.cap-breached-precedes-run-failed-in-the-event-sequence-breach-detected-before-ov',
141
142
  'run-options.md §recursionLimit',
142
143
  'at most `limit` node.started events MUST be emitted; the over-limit node MUST NOT receive node.started',
143
144
  )).toBeLessThanOrEqual(RECURSION_LIMIT);
144
- expect(nodeStarted.length, driver.describe(
145
+ expect(nodeStarted.length, req('openwop.it.cap-breach.cap-breached-precedes-run-failed-in-the-event-sequence-breach-detected-before-ov',
145
146
  'run-options.md §recursionLimit',
146
147
  'at least one node MUST start before the breach (otherwise the workflow never executed)',
147
148
  )).toBeGreaterThan(0);
@@ -45,6 +45,8 @@ import { readFileSync } from 'node:fs';
45
45
  import { join } from 'node:path';
46
46
  import { driver } from '../lib/driver.js';
47
47
  import { SCHEMAS_DIR } from '../lib/paths.js';
48
+ import { req } from '../lib/requirement-ids.js';
49
+ import { softSkip } from '../lib/soft-skip.js';
48
50
 
49
51
  type Arm = 'root-plain' | 'root-dotted' | 'wrapper-plain' | 'wrapper-dotted';
50
52
 
@@ -84,11 +86,11 @@ describe('capability-arm-witness: which resolver arm the host lands on (RFC 0144
84
86
  const res = await driver.get('/.well-known/openwop');
85
87
  // No discovery document ⇒ inapplicable. Other scenarios own that failure; this leg is
86
88
  // about WHERE families sit, not whether the host has any.
87
- if (res.status !== 200 || res.json === undefined || res.json === null) return;
89
+ if (res.status !== 200 || res.json === undefined || res.json === null) return softSkip('blocked', 'precondition not met — `res.status !== 200 || res.json === undefined || res.json === null` returned early (No discovery document ⇒ inapplicable. Other scenarios own that failure; this leg is about WHERE families sit, …');
88
90
 
89
91
  const doc = res.json as Record<string, unknown>;
90
92
  const placements = classify(doc, declaredFamilies());
91
- if (placements.length === 0) return; // advertises no declared family — inapplicable
93
+ if (placements.length === 0) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `placements.length === 0` returned early (advertises no declared family — inapplicable)'); // advertises no declared family — inapplicable
92
94
 
93
95
  const canonical = placements.filter((p) => p.arms.includes('root-plain'));
94
96
  const rootDotted = placements.filter(
@@ -110,7 +112,7 @@ describe('capability-arm-witness: which resolver arm the host lands on (RFC 0144
110
112
  // ASSERT — the existing MUST, not a new one.
111
113
  expect(
112
114
  wrapperOnly.map((p) => p.family),
113
- driver.describe(
115
+ req('openwop.it.capability-arm-witness.no-capability-family-is-reachable-only-under-the-deprecated-capabilities-wrapper',
114
116
  'capabilities.md §"Document-root layout (normative — RFC 0073)"',
115
117
  'every family MUST appear at the document root; a host that serves families EXCLUSIVELY under the deprecated `capabilities` wrapper is non-conformant and is graded as such. The suite\'s helpers fall back to the wrapper, so without this leg such a host reads exactly like a migrated one — which is RFC 0144 G1',
116
118
  ),