@openwop/openwop-conformance 1.162.0 → 2.0.0-rc.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.
Files changed (553) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.js +54 -1
  3. package/dist/lib/paths.js +25 -3
  4. package/dist/lib/requirement-ids.js +34 -4
  5. package/dist/lib/scenario-disposition.js +1 -0
  6. package/dist/lib/spec-coherence.js +13 -32
  7. package/dist/spec-artifacts.lock.json +5 -0
  8. package/package.json +11 -33
  9. package/requirements.json +20303 -11809
  10. package/scenario-majors.json +1343 -0
  11. package/schemas/CORPUS-STAMP.json +138 -6
  12. package/src/cli.ts +47 -1
  13. package/src/global-setup.ts +3 -2
  14. package/src/lib/corpus-stamp.ts +29 -1
  15. package/src/lib/paths.ts +25 -3
  16. package/src/lib/requirement-ids.ts +33 -4
  17. package/src/lib/scenario-disposition.ts +1 -0
  18. package/src/lib/spec-coherence.ts +15 -32
  19. package/src/scenarios/a2a-1-0-agent-card.test.ts +17 -16
  20. package/src/scenarios/a2a-1-0-task-roundtrip.test.ts +11 -10
  21. package/src/scenarios/a2a-card-runtime-consistency.test.ts +18 -17
  22. package/src/scenarios/a2a-peer-authority.test.ts +7 -6
  23. package/src/scenarios/a2a-task-roundtrip.test.ts +30 -29
  24. package/src/scenarios/a2a-version-negotiation.test.ts +16 -14
  25. package/src/scenarios/a2ui-surface-degrades.test.ts +5 -3
  26. package/src/scenarios/a2ui-surface-delta-transport.test.ts +35 -33
  27. package/src/scenarios/a2ui-surface-replay.test.ts +6 -4
  28. package/src/scenarios/a2ui-surface-shape.test.ts +11 -10
  29. package/src/scenarios/a2ui-surface-version-refusal.test.ts +6 -4
  30. package/src/scenarios/a2ui-untrusted-blocks-approval.test.ts +5 -3
  31. package/src/scenarios/agent-capability-degraded-projection.test.ts +12 -11
  32. package/src/scenarios/agent-channel-dispatch.test.ts +18 -16
  33. package/src/scenarios/agent-deployment-lifecycle.test.ts +20 -19
  34. package/src/scenarios/agent-deployment-shape.test.ts +22 -24
  35. package/src/scenarios/agent-eval-run.test.ts +19 -18
  36. package/src/scenarios/agent-eval-suite-shape.test.ts +20 -22
  37. package/src/scenarios/agent-live-allowlist-enforced.test.ts +6 -5
  38. package/src/scenarios/agent-live-invocation-bracket.test.ts +13 -12
  39. package/src/scenarios/agent-live-runtime-shape.test.ts +10 -12
  40. package/src/scenarios/agent-live-structured-output.test.ts +7 -6
  41. package/src/scenarios/agent-loop-iteration-monotonic.test.ts +3 -3
  42. package/src/scenarios/agent-loop-stateful-resume.test.ts +2 -2
  43. package/src/scenarios/agent-loop-version5-shape.test.ts +4 -4
  44. package/src/scenarios/agent-loop-workspace-snapshot.test.ts +3 -3
  45. package/src/scenarios/agent-manifest-role-profile.test.ts +9 -9
  46. package/src/scenarios/agent-manifest-runtime.test.ts +13 -12
  47. package/src/scenarios/agent-org-chart-scoping.test.ts +14 -13
  48. package/src/scenarios/agent-org-chart-shape.test.ts +11 -13
  49. package/src/scenarios/agent-platform-aggregate-evidence.test.ts +5 -4
  50. package/src/scenarios/agent-platform-profile.test.ts +18 -19
  51. package/src/scenarios/agent-requires-capabilities-shape.test.ts +4 -4
  52. package/src/scenarios/agent-roster-attribution.test.ts +18 -17
  53. package/src/scenarios/agent-roster-shape.test.ts +17 -19
  54. package/src/scenarios/agent-verifier-shape.test.ts +11 -11
  55. package/src/scenarios/agentConfidenceEscalation.test.ts +2 -1
  56. package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +6 -5
  57. package/src/scenarios/agentMemoryRedactionContract.test.ts +2 -1
  58. package/src/scenarios/agentMemoryRoundTrip.test.ts +2 -1
  59. package/src/scenarios/agentMemoryTtlExpiry.test.ts +4 -3
  60. package/src/scenarios/agentMessageReducer.test.ts +2 -1
  61. package/src/scenarios/agentMetadata.test.ts +2 -1
  62. package/src/scenarios/agentPackCatalog.test.ts +23 -21
  63. package/src/scenarios/agentPackExport.test.ts +4 -2
  64. package/src/scenarios/agentPackHandoffSchemaValidation.test.ts +5 -4
  65. package/src/scenarios/agentPackInstall.test.ts +4 -2
  66. package/src/scenarios/agentPackProvenance.test.ts +2 -1
  67. package/src/scenarios/agentReasoningEvents.test.ts +3 -2
  68. package/src/scenarios/agentReasoningStreaming.test.ts +11 -10
  69. package/src/scenarios/agents-run-tool-allowlist.test.ts +14 -12
  70. package/src/scenarios/ai-envelope-shape.test.ts +31 -29
  71. package/src/scenarios/aiEnvelope.capBreached.test.ts +26 -24
  72. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +36 -34
  73. package/src/scenarios/aiEnvelope.correlationReplay.test.ts +17 -15
  74. package/src/scenarios/aiEnvelope.redaction.test.ts +22 -20
  75. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +18 -16
  76. package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +38 -36
  77. package/src/scenarios/aiEnvelope.universalKinds.test.ts +31 -29
  78. package/src/scenarios/aiproviders-input-shape.test.ts +5 -5
  79. package/src/scenarios/aiproviders-realtimevoice-shape.test.ts +14 -16
  80. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +6 -4
  81. package/src/scenarios/aiproviders-selfhosted-shape.test.ts +15 -17
  82. package/src/scenarios/aiproviders-speechsynth-shape.test.ts +6 -8
  83. package/src/scenarios/aiproviders-subscription-scope.test.ts +7 -8
  84. package/src/scenarios/anonymous-actor-audit-opaque.test.ts +9 -8
  85. package/src/scenarios/anonymous-actor-default-deny.test.ts +10 -9
  86. package/src/scenarios/anonymous-actor-egress-guarded.test.ts +6 -5
  87. package/src/scenarios/anonymous-actor-no-secret-reach.test.ts +7 -6
  88. package/src/scenarios/anonymous-actor-shape.test.ts +17 -19
  89. package/src/scenarios/anonymous-actor-write-gated.test.ts +9 -8
  90. package/src/scenarios/append-ordering.test.ts +7 -5
  91. package/src/scenarios/approval-gate-events.test.ts +4 -3
  92. package/src/scenarios/approval-gate-flow.test.ts +4 -3
  93. package/src/scenarios/approval-payload.test.ts +5 -4
  94. package/src/scenarios/artifact-auth.test.ts +7 -6
  95. package/src/scenarios/artifact-type-pack-install.test.ts +6 -6
  96. package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +9 -8
  97. package/src/scenarios/artifact-type-registration-source.test.ts +20 -20
  98. package/src/scenarios/artifact-type-store-emission.test.ts +15 -18
  99. package/src/scenarios/artifact-type-store-without-render.test.ts +4 -4
  100. package/src/scenarios/audit-log-integrity.test.ts +8 -6
  101. package/src/scenarios/auth-api-key-rotation.test.ts +11 -9
  102. package/src/scenarios/auth-mtls.test.ts +22 -20
  103. package/src/scenarios/auth-oauth2-client-credentials.test.ts +16 -14
  104. package/src/scenarios/auth-oidc-user-bearer.test.ts +26 -24
  105. package/src/scenarios/auth-saml-profile.test.ts +14 -12
  106. package/src/scenarios/auth-scim-profile.test.ts +3 -2
  107. package/src/scenarios/auth-subject-link-key-class.test.ts +8 -7
  108. package/src/scenarios/auth-subject-link.test.ts +11 -10
  109. package/src/scenarios/auth.test.ts +5 -4
  110. package/src/scenarios/authorization-fail-closed.test.ts +3 -2
  111. package/src/scenarios/authorization-roles-shape.test.ts +9 -7
  112. package/src/scenarios/blob-cross-tenant-isolation.test.ts +8 -6
  113. package/src/scenarios/blob-presign-expiry.test.ts +12 -10
  114. package/src/scenarios/blob-roundtrip.test.ts +0 -0
  115. package/src/scenarios/budget-enforcement.test.ts +15 -14
  116. package/src/scenarios/budget-policy-shape.test.ts +18 -19
  117. package/src/scenarios/bulk-cancel.test.ts +9 -8
  118. package/src/scenarios/byok-auth-modes.test.ts +13 -14
  119. package/src/scenarios/byok-roundtrip.test.ts +12 -10
  120. package/src/scenarios/cache-cross-tenant-isolation.test.ts +8 -6
  121. package/src/scenarios/cache-ttl-expiry.test.ts +7 -5
  122. package/src/scenarios/callai-multimodal.test.ts +5 -3
  123. package/src/scenarios/cancellation.test.ts +6 -5
  124. package/src/scenarios/cap-breach.test.ts +15 -14
  125. package/src/scenarios/capability-arm-witness.test.ts +5 -3
  126. package/src/scenarios/certification-bundle-non-vacuous.test.ts +20 -19
  127. package/src/scenarios/certification-bundle-redaction.test.ts +11 -10
  128. package/src/scenarios/certification-bundle-v2.test.ts +11 -10
  129. package/src/scenarios/chain-compensation-expansion.test.ts +14 -13
  130. package/src/scenarios/chain-produced-var-roundtrip.test.ts +13 -14
  131. package/src/scenarios/chain-subchain-cycle-rejected.test.ts +9 -10
  132. package/src/scenarios/chain-subchain-fanout.test.ts +8 -9
  133. package/src/scenarios/chain-subchain-sibling.test.ts +14 -16
  134. package/src/scenarios/channel-presence-behavioral.test.ts +9 -7
  135. package/src/scenarios/channel-presence-shape.test.ts +11 -12
  136. package/src/scenarios/channel-ttl.test.ts +6 -5
  137. package/src/scenarios/chat-card-pack-execution.test.ts +4 -4
  138. package/src/scenarios/chat-card-pack-manifest-validation.test.ts +9 -8
  139. package/src/scenarios/commitment-fired.test.ts +6 -5
  140. package/src/scenarios/compensation-behavior.test.ts +24 -23
  141. package/src/scenarios/compensation-recovery.test.ts +28 -27
  142. package/src/scenarios/configurable-schema.test.ts +8 -6
  143. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -5
  144. package/src/scenarios/conformance-execution-witness.test.ts +9 -8
  145. package/src/scenarios/connection-pack-apihosts.test.ts +19 -17
  146. package/src/scenarios/connection-pack-manifest-valid.test.ts +12 -11
  147. package/src/scenarios/connection-pack-no-credential-material.test.ts +8 -6
  148. package/src/scenarios/connection-pack-reach-exclusive.test.ts +5 -4
  149. package/src/scenarios/connection-pack-write-reconsent.test.ts +6 -4
  150. package/src/scenarios/connection-provider-resolution.test.ts +18 -16
  151. package/src/scenarios/connector-manifest-validity.test.ts +8 -7
  152. package/src/scenarios/context-budget-transcript-bound.test.ts +17 -15
  153. package/src/scenarios/context-summarization-replay.test.ts +14 -12
  154. package/src/scenarios/contract-provenance.test.ts +18 -18
  155. package/src/scenarios/conversation-turn-model-provenance-shape.test.ts +14 -15
  156. package/src/scenarios/conversationCapabilityNegotiation.test.ts +2 -1
  157. package/src/scenarios/conversationLifecycle.test.ts +2 -1
  158. package/src/scenarios/conversationReplayDeterminism.test.ts +4 -2
  159. package/src/scenarios/conversationVsLegacySuspend.test.ts +2 -1
  160. package/src/scenarios/core-standard-profile.test.ts +8 -9
  161. package/src/scenarios/cost-attribution.test.ts +23 -21
  162. package/src/scenarios/credential-payload-redaction.test.ts +4 -3
  163. package/src/scenarios/credentials-capability-shape.test.ts +5 -4
  164. package/src/scenarios/cross-engine-append-behavior.test.ts +11 -10
  165. package/src/scenarios/cross-engine-append-ordering.test.ts +4 -3
  166. package/src/scenarios/cross-host-ancestry-endpoint.test.ts +11 -10
  167. package/src/scenarios/cross-host-causation-shape.test.ts +7 -6
  168. package/src/scenarios/cross-workspace-isolation.test.ts +4 -3
  169. package/src/scenarios/data-residency-admission.test.ts +15 -14
  170. package/src/scenarios/deadletter-capability-shape.test.ts +6 -4
  171. package/src/scenarios/deadletter-retry-exhaustion.test.ts +4 -3
  172. package/src/scenarios/debug-bundle-truncation.test.ts +9 -7
  173. package/src/scenarios/debugBundle.test.ts +25 -23
  174. package/src/scenarios/discovery-families-view.test.ts +5 -4
  175. package/src/scenarios/discovery.test.ts +30 -29
  176. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +10 -8
  177. package/src/scenarios/dispatch-fanout-parallel.test.ts +24 -22
  178. package/src/scenarios/dispatch-input-mapping.test.ts +12 -10
  179. package/src/scenarios/dispatch-output-mapping.test.ts +9 -7
  180. package/src/scenarios/dispatch-per-item-input.test.ts +22 -20
  181. package/src/scenarios/dispatchLoop.test.ts +3 -2
  182. package/src/scenarios/distillation-index-roundtrip.test.ts +3 -3
  183. package/src/scenarios/distillation-secret-carryforward.test.ts +2 -2
  184. package/src/scenarios/distillation-shape.test.ts +4 -4
  185. package/src/scenarios/distillation-stable-archive.test.ts +6 -6
  186. package/src/scenarios/distillation-token-budget.test.ts +5 -5
  187. package/src/scenarios/durability-poison-exhaustion.test.ts +7 -6
  188. package/src/scenarios/egress-audience-binding.test.ts +11 -10
  189. package/src/scenarios/egress-decision-content-free.test.ts +6 -5
  190. package/src/scenarios/egress-provenance-shape.test.ts +17 -18
  191. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +27 -25
  192. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +19 -17
  193. package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +28 -26
  194. package/src/scenarios/envelope-reasoning-shape.test.ts +19 -17
  195. package/src/scenarios/envelope-recovery-applied.test.ts +24 -22
  196. package/src/scenarios/envelope-refusal-shape.test.ts +31 -29
  197. package/src/scenarios/envelope-rendering-hint.test.ts +5 -4
  198. package/src/scenarios/envelope-retry-attempted.test.ts +33 -31
  199. package/src/scenarios/envelope-retry-exhausted.test.ts +22 -20
  200. package/src/scenarios/envelope-tier-one-subset-static.test.ts +9 -7
  201. package/src/scenarios/envelope-truncated.test.ts +19 -17
  202. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +19 -17
  203. package/src/scenarios/envelope-variant-discriminator-static.test.ts +4 -3
  204. package/src/scenarios/errors.test.ts +20 -19
  205. package/src/scenarios/eventOrdering.test.ts +16 -14
  206. package/src/scenarios/exec-not-protocol-tier.test.ts +5 -7
  207. package/src/scenarios/experimental-tier-shape.test.ts +17 -15
  208. package/src/scenarios/export-bundle-portability.test.ts +17 -17
  209. package/src/scenarios/failure-path.test.ts +7 -6
  210. package/src/scenarios/feedback-capability-shape.test.ts +4 -3
  211. package/src/scenarios/feedback-correction-redaction.test.ts +2 -1
  212. package/src/scenarios/feedback-cross-tenant-isolation.test.ts +2 -1
  213. package/src/scenarios/feedback-fork-not-copied.test.ts +3 -2
  214. package/src/scenarios/feedback-on-terminal-run.test.ts +3 -2
  215. package/src/scenarios/feedback-record-and-list.test.ts +2 -1
  216. package/src/scenarios/feedback-unsupported-501.test.ts +2 -1
  217. package/src/scenarios/fixtures-gating.test.ts +29 -28
  218. package/src/scenarios/fixtures-valid.test.ts +16 -15
  219. package/src/scenarios/form-content-instantiation.test.ts +15 -14
  220. package/src/scenarios/frontend-plugin-packs.test.ts +29 -27
  221. package/src/scenarios/fs-path-traversal.test.ts +14 -12
  222. package/src/scenarios/goal-standing-continuation.test.ts +21 -21
  223. package/src/scenarios/grpc-transport.test.ts +9 -7
  224. package/src/scenarios/heartbeat-capability-shape.test.ts +3 -3
  225. package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +2 -2
  226. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +3 -3
  227. package/src/scenarios/heartbeat-runtime-bound.test.ts +2 -2
  228. package/src/scenarios/highConcurrency.test.ts +14 -13
  229. package/src/scenarios/host-callback-declaration.test.ts +8 -7
  230. package/src/scenarios/http-client-ssrf.test.ts +7 -5
  231. package/src/scenarios/i18n-negotiation.test.ts +14 -12
  232. package/src/scenarios/idempotency-concurrent-claim.test.ts +14 -13
  233. package/src/scenarios/idempotency-key-determinism.test.ts +20 -18
  234. package/src/scenarios/idempotency.test.ts +8 -7
  235. package/src/scenarios/idempotencyRetry.test.ts +13 -11
  236. package/src/scenarios/identity-owner-shape.test.ts +6 -5
  237. package/src/scenarios/identity-passthrough.test.ts +4 -3
  238. package/src/scenarios/interrupt-approval.test.ts +6 -5
  239. package/src/scenarios/interrupt-approver-routing.test.ts +15 -15
  240. package/src/scenarios/interrupt-auth-required-resume.test.ts +5 -3
  241. package/src/scenarios/interrupt-clarification.test.ts +4 -3
  242. package/src/scenarios/interrupt-external-event-correlation.test.ts +6 -5
  243. package/src/scenarios/interrupt-parent-child-cascade.test.ts +4 -3
  244. package/src/scenarios/interrupt-quorum-resolution.test.ts +5 -4
  245. package/src/scenarios/interrupt-token-matrix.test.ts +8 -6
  246. package/src/scenarios/interruptRace.test.ts +12 -10
  247. package/src/scenarios/kv-atomic-increment.test.ts +11 -9
  248. package/src/scenarios/kv-cas.test.ts +14 -12
  249. package/src/scenarios/kv-cross-tenant-isolation.test.ts +12 -10
  250. package/src/scenarios/kv-ttl-expiry.test.ts +7 -5
  251. package/src/scenarios/localized-content-delivery.test.ts +24 -26
  252. package/src/scenarios/maliciousManifest.test.ts +10 -8
  253. package/src/scenarios/mcp-2026-07-28-discover.test.ts +15 -14
  254. package/src/scenarios/mcp-cache-tenant-scope.test.ts +6 -5
  255. package/src/scenarios/mcp-current-auth-boundary.test.ts +7 -6
  256. package/src/scenarios/mcp-discoverability.test.ts +9 -7
  257. package/src/scenarios/mcp-extension-opacity.test.ts +7 -6
  258. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +18 -17
  259. package/src/scenarios/mcp-server-elicitation-bridge.test.ts +13 -12
  260. package/src/scenarios/mcp-server-prompt-roundtrip.test.ts +11 -10
  261. package/src/scenarios/mcp-server-resource-roundtrip.test.ts +11 -10
  262. package/src/scenarios/mcp-server-sampling-bridge.test.ts +12 -11
  263. package/src/scenarios/mcp-server-tool-roundtrip.test.ts +14 -13
  264. package/src/scenarios/mcp-server-untrusted-args.test.ts +14 -13
  265. package/src/scenarios/mcp-stateless-request.test.ts +11 -10
  266. package/src/scenarios/mcp-tool-roundtrip.test.ts +4 -3
  267. package/src/scenarios/mcp-toolcall-redaction.test.ts +4 -3
  268. package/src/scenarios/mcp-version-negotiation.test.ts +15 -14
  269. package/src/scenarios/media-url-inline-cap.test.ts +21 -19
  270. package/src/scenarios/memory-attribution-emits-on-write.test.ts +5 -5
  271. package/src/scenarios/memory-attribution-no-content.test.ts +4 -4
  272. package/src/scenarios/memory-attribution-replay-stable.test.ts +4 -3
  273. package/src/scenarios/memory-attribution-shape.test.ts +4 -3
  274. package/src/scenarios/memory-attribution-tenant-scoped.test.ts +3 -3
  275. package/src/scenarios/memory-capability-model-shape.test.ts +14 -15
  276. package/src/scenarios/memory-compaction-event-emitted.test.ts +7 -6
  277. package/src/scenarios/memory-compaction-provenance-tag.test.ts +3 -2
  278. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +7 -6
  279. package/src/scenarios/memory-consolidation-idempotent.test.ts +5 -4
  280. package/src/scenarios/memory-consolidation-shape.test.ts +9 -11
  281. package/src/scenarios/memory-degraded-projection.test.ts +10 -9
  282. package/src/scenarios/memory-injection-budget.test.ts +15 -14
  283. package/src/scenarios/metric-emission.test.ts +4 -3
  284. package/src/scenarios/model-capability-insufficient.test.ts +19 -17
  285. package/src/scenarios/model-capability-substituted.test.ts +20 -18
  286. package/src/scenarios/multi-agent-confidence-escalation.test.ts +12 -11
  287. package/src/scenarios/multi-agent-handoff-state-machine.test.ts +10 -9
  288. package/src/scenarios/multi-agent-memory-lifecycle.test.ts +11 -10
  289. package/src/scenarios/multi-node-ordering.test.ts +4 -3
  290. package/src/scenarios/multi-party-conversation-behavioral.test.ts +6 -6
  291. package/src/scenarios/multi-party-conversation-shape.test.ts +21 -23
  292. package/src/scenarios/multi-region-idempotency-behavior.test.ts +16 -15
  293. package/src/scenarios/multi-region-idempotency.test.ts +6 -5
  294. package/src/scenarios/node-failed-payload-shape.test.ts +5 -4
  295. package/src/scenarios/node-module-required-capabilities-shape.test.ts +10 -8
  296. package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +5 -4
  297. package/src/scenarios/oauth-capability-shape.test.ts +5 -4
  298. package/src/scenarios/oauth-connector-redaction.test.ts +4 -3
  299. package/src/scenarios/openapi-resolved-paths.test.ts +6 -5
  300. package/src/scenarios/orchestratorConservativePath.test.ts +2 -1
  301. package/src/scenarios/orchestratorDispatch.test.ts +2 -1
  302. package/src/scenarios/orchestratorTermination.test.ts +2 -1
  303. package/src/scenarios/org-position-no-authority-escalation.test.ts +2 -2
  304. package/src/scenarios/otel-collector-canary-inspection.test.ts +8 -7
  305. package/src/scenarios/otel-emission-grpc.test.ts +3 -2
  306. package/src/scenarios/otel-emission.test.ts +6 -5
  307. package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +7 -6
  308. package/src/scenarios/otel-trace-propagation.test.ts +2 -1
  309. package/src/scenarios/owner-subject-echo.test.ts +13 -12
  310. package/src/scenarios/owner-subject-shape.test.ts +11 -10
  311. package/src/scenarios/pack-manifest-extension-opacity.test.ts +8 -8
  312. package/src/scenarios/pack-registry-isolation.test.ts +4 -3
  313. package/src/scenarios/pack-registry-publish.test.ts +65 -63
  314. package/src/scenarios/pack-registry.test.ts +38 -36
  315. package/src/scenarios/pause-resume.test.ts +18 -16
  316. package/src/scenarios/policies.test.ts +20 -18
  317. package/src/scenarios/production-backpressure.test.ts +18 -16
  318. package/src/scenarios/production-retention-expiry.test.ts +8 -6
  319. package/src/scenarios/profile-discovery-core-alias.test.ts +13 -11
  320. package/src/scenarios/profileDerivation.test.ts +34 -33
  321. package/src/scenarios/prompt-all-four-kinds-events.test.ts +11 -9
  322. package/src/scenarios/prompt-composed-secret-redaction.test.ts +11 -9
  323. package/src/scenarios/prompt-composed-trust-marker.test.ts +10 -8
  324. package/src/scenarios/prompt-end-to-end-events.test.ts +17 -15
  325. package/src/scenarios/prompt-list-and-fetch.test.ts +16 -14
  326. package/src/scenarios/prompt-mutable-lifecycle.test.ts +13 -11
  327. package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +6 -4
  328. package/src/scenarios/prompt-pack-install.test.ts +14 -12
  329. package/src/scenarios/prompt-prefix-cache.test.ts +19 -17
  330. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +11 -9
  331. package/src/scenarios/prompt-render-deterministic.test.ts +19 -17
  332. package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +7 -5
  333. package/src/scenarios/prompt-resolution-chain-event.test.ts +12 -10
  334. package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +10 -8
  335. package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +8 -6
  336. package/src/scenarios/prompt-template-shape.test.ts +30 -28
  337. package/src/scenarios/proposal-reviewable-learning.test.ts +19 -19
  338. package/src/scenarios/protocol-versions-array.test.ts +10 -9
  339. package/src/scenarios/provider-usage.test.ts +17 -15
  340. package/src/scenarios/providerPolicyEnforcement.test.ts +16 -14
  341. package/src/scenarios/purpose-propagation.test.ts +23 -21
  342. package/src/scenarios/queue-ack-nack-dlq.test.ts +12 -10
  343. package/src/scenarios/queue-cross-tenant-isolation.test.ts +8 -6
  344. package/src/scenarios/queue-publish-consume-roundtrip.test.ts +10 -8
  345. package/src/scenarios/rate-limit-envelope.test.ts +6 -5
  346. package/src/scenarios/redaction.test.ts +13 -11
  347. package/src/scenarios/redactionAdversarial.test.ts +11 -9
  348. package/src/scenarios/registry-public.test.ts +12 -11
  349. package/src/scenarios/replay-divergence-at-refusal.test.ts +16 -15
  350. package/src/scenarios/replay-fanout-suppression.test.ts +16 -15
  351. package/src/scenarios/replay-fork-arbitrary.test.ts +24 -23
  352. package/src/scenarios/replay-fork.test.ts +20 -19
  353. package/src/scenarios/replay-llm-cache-key-portable.test.ts +11 -9
  354. package/src/scenarios/replay-llm-cache-key.test.ts +22 -21
  355. package/src/scenarios/replay-observable-sequence-determinism.test.ts +4 -3
  356. package/src/scenarios/replay-retention-expiry.test.ts +11 -9
  357. package/src/scenarios/replay-side-effect-suppression.test.ts +21 -19
  358. package/src/scenarios/replayDeterminism.test.ts +13 -12
  359. package/src/scenarios/requirement-ledger.test.ts +15 -14
  360. package/src/scenarios/restart-during-run.test.ts +3 -2
  361. package/src/scenarios/route-coverage.test.ts +20 -19
  362. package/src/scenarios/run-diff.test.ts +22 -20
  363. package/src/scenarios/run-execution-bounds-shape.test.ts +14 -12
  364. package/src/scenarios/run-transport-economy.test.ts +13 -11
  365. package/src/scenarios/runner-ledger.test.ts +17 -16
  366. package/src/scenarios/runs-lifecycle.test.ts +7 -6
  367. package/src/scenarios/runtime-capabilities.test.ts +12 -10
  368. package/src/scenarios/runtime-requires-install-gate.test.ts +8 -8
  369. package/src/scenarios/runtime-requires-shape.test.ts +7 -6
  370. package/src/scenarios/safefetch-behavior.test.ts +22 -21
  371. package/src/scenarios/safefetch-live-audit.test.ts +14 -13
  372. package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
  373. package/src/scenarios/sandbox-mvp-behavior.test.ts +24 -23
  374. package/src/scenarios/sandbox-no-host-fs-escape.test.ts +3 -2
  375. package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
  376. package/src/scenarios/sandbox-wasm-isolation.test.ts +14 -15
  377. package/src/scenarios/sandbox-wasm-timeout.test.ts +5 -6
  378. package/src/scenarios/scheduling-capability-shape.test.ts +8 -6
  379. package/src/scenarios/scheduling-cron-fires-once.test.ts +8 -6
  380. package/src/scenarios/search-bm25-roundtrip.test.ts +8 -6
  381. package/src/scenarios/secret-leakage-otel-attribute.test.ts +22 -20
  382. package/src/scenarios/self-hosted-runner.test.ts +26 -24
  383. package/src/scenarios/semantic-digest-vectors.test.ts +8 -7
  384. package/src/scenarios/speech-synthesis-roundtrip.test.ts +9 -7
  385. package/src/scenarios/speech-synthesis-unadvertised.test.ts +5 -3
  386. package/src/scenarios/sql-injection-rejection.test.ts +8 -6
  387. package/src/scenarios/sql-transaction-atomicity.test.ts +10 -8
  388. package/src/scenarios/staleClaim.test.ts +5 -4
  389. package/src/scenarios/stream-modes-buffer.test.ts +8 -7
  390. package/src/scenarios/stream-modes-mixed.test.ts +10 -9
  391. package/src/scenarios/stream-modes.test.ts +12 -11
  392. package/src/scenarios/stream-subscribe-from-beginning.test.ts +11 -9
  393. package/src/scenarios/stream-text-fixture.test.ts +14 -13
  394. package/src/scenarios/streamReconnect.test.ts +13 -11
  395. package/src/scenarios/strict-behavior-gate.test.ts +9 -8
  396. package/src/scenarios/subrun-approval-fail-closed.test.ts +2 -2
  397. package/src/scenarios/subrun-approval-gate.test.ts +3 -3
  398. package/src/scenarios/subrun-attestation-shape.test.ts +2 -2
  399. package/src/scenarios/subrun-checksum-stable.test.ts +4 -4
  400. package/src/scenarios/subworkflow-input-mapping.test.ts +16 -14
  401. package/src/scenarios/subworkflow.test.ts +10 -9
  402. package/src/scenarios/table-cross-tenant-isolation.test.ts +8 -6
  403. package/src/scenarios/table-cursor-pagination.test.ts +8 -6
  404. package/src/scenarios/table-schema-enforcement.test.ts +7 -5
  405. package/src/scenarios/test-seam-unauthenticated.test.ts +2 -2
  406. package/src/scenarios/tool-catalog-compact-projection.test.ts +10 -8
  407. package/src/scenarios/tool-catalog-projection.test.ts +11 -9
  408. package/src/scenarios/tool-descriptor-shape.test.ts +14 -15
  409. package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +3 -3
  410. package/src/scenarios/tool-hooks-content-free.test.ts +4 -4
  411. package/src/scenarios/tool-hooks-failure-honesty.test.ts +4 -4
  412. package/src/scenarios/tool-hooks-rate-limit.test.ts +2 -2
  413. package/src/scenarios/tool-hooks-secret-redaction.test.ts +2 -2
  414. package/src/scenarios/tool-hooks-shape.test.ts +3 -3
  415. package/src/scenarios/tool-session-lifecycle.test.ts +14 -13
  416. package/src/scenarios/trigger-bridge-delivery.test.ts +14 -14
  417. package/src/scenarios/trigger-bridge-shape.test.ts +19 -20
  418. package/src/scenarios/trigger-ingestion.test.ts +19 -17
  419. package/src/scenarios/trigger-stream-cdc-sources.test.ts +16 -14
  420. package/src/scenarios/vector-knn-roundtrip.test.ts +9 -7
  421. package/src/scenarios/verifier-gating.test.ts +8 -6
  422. package/src/scenarios/version-fold.test.ts +9 -8
  423. package/src/scenarios/version-negotiation.test.ts +12 -11
  424. package/src/scenarios/voice-bargein-no-partial-leak.test.ts +8 -6
  425. package/src/scenarios/voice-event-payloads-shape.test.ts +10 -11
  426. package/src/scenarios/voice-interim-not-durable.test.ts +7 -5
  427. package/src/scenarios/voice-streamref-tenant-bound.test.ts +5 -3
  428. package/src/scenarios/voice-synthesis-streaming.test.ts +11 -9
  429. package/src/scenarios/voice-transcription-streaming.test.ts +8 -6
  430. package/src/scenarios/voice-transcription-unadvertised.test.ts +5 -3
  431. package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -2
  432. package/src/scenarios/wasm-pack-invoke-completed.test.ts +3 -2
  433. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +3 -2
  434. package/src/scenarios/wasm-pack-load.test.ts +4 -3
  435. package/src/scenarios/wasm-pack-memory-cap.test.ts +5 -4
  436. package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -1
  437. package/src/scenarios/webhook-negative.test.ts +11 -9
  438. package/src/scenarios/webhook-receiver-adversarial.test.ts +8 -7
  439. package/src/scenarios/webhook-sig-algorithm.test.ts +5 -3
  440. package/src/scenarios/webhook-signed-delivery.test.ts +16 -15
  441. package/src/scenarios/webhook-tenant-isolation.test.ts +16 -14
  442. package/src/scenarios/workflow-chain-deferred-parameters.test.ts +28 -30
  443. package/src/scenarios/workflow-chain-expansion.test.ts +21 -20
  444. package/src/scenarios/workflow-chain-host-expansion.test.ts +21 -20
  445. package/src/scenarios/workflow-chain-pack-manifest-validation.test.ts +14 -12
  446. package/src/scenarios/workflow-chain-pack-signature-verification.test.ts +5 -4
  447. package/src/scenarios/workflow-chain-unresolvable-typeid.test.ts +9 -8
  448. package/src/scenarios/workflow-primary-output-annotation.test.ts +7 -6
  449. package/src/scenarios/workflow-variable-format.test.ts +24 -24
  450. package/src/scenarios/workload-identity-behavior.test.ts +15 -13
  451. package/src/scenarios/workload-identity-chain-bounds.test.ts +18 -17
  452. package/src/scenarios/workspace-behavior.test.ts +19 -18
  453. package/src/scenarios/workspace-capability-shape.test.ts +3 -2
  454. package/src/scenarios/workspace-cross-tenant-isolation-blackbox.test.ts +6 -5
  455. package/src/scenarios/workspace-cross-tenant-isolation.test.ts +7 -6
  456. package/src/scenarios/x-openwop-form-pack-manifest.test.ts +8 -7
  457. package/src/setup.ts +4 -2
  458. package/vitest.config.ts +5 -1
  459. package/api/.redocly.lint-ignore.yaml +0 -22
  460. package/api/asyncapi.yaml +0 -834
  461. package/api/grpc/openwop.proto +0 -251
  462. package/api/openapi.yaml +0 -2693
  463. package/api/redocly.yaml +0 -23
  464. package/schemas/README.md +0 -144
  465. package/schemas/a2a-task-state.schema.json +0 -78
  466. package/schemas/a2ui-surface-delta-frame.schema.json +0 -48
  467. package/schemas/agent-deployment-transition.schema.json +0 -49
  468. package/schemas/agent-deployment.schema.json +0 -54
  469. package/schemas/agent-eval-suite.schema.json +0 -140
  470. package/schemas/agent-inventory-response.schema.json +0 -115
  471. package/schemas/agent-manifest.schema.json +0 -156
  472. package/schemas/agent-org-chart.schema.json +0 -82
  473. package/schemas/agent-ref.schema.json +0 -63
  474. package/schemas/agent-roster-entry.schema.json +0 -81
  475. package/schemas/agent-roster-response.schema.json +0 -21
  476. package/schemas/ai-envelope.schema.json +0 -134
  477. package/schemas/annotation-create.schema.json +0 -37
  478. package/schemas/annotation.schema.json +0 -56
  479. package/schemas/artifact-type-pack-manifest.schema.json +0 -244
  480. package/schemas/audit-verify-result.schema.json +0 -90
  481. package/schemas/budget-policy.schema.json +0 -18
  482. package/schemas/capabilities.schema.json +0 -4124
  483. package/schemas/certification-bundle-v2.schema.json +0 -118
  484. package/schemas/channel-presence-payload.schema.json +0 -41
  485. package/schemas/channel-written-payload.schema.json +0 -55
  486. package/schemas/chat-card-pack-manifest.schema.json +0 -253
  487. package/schemas/compact-tool-descriptor.schema.json +0 -51
  488. package/schemas/compensation-policy.schema.json +0 -64
  489. package/schemas/conformance-certification-bundle.schema.json +0 -86
  490. package/schemas/connection-pack-manifest.schema.json +0 -353
  491. package/schemas/conversation-event.schema.json +0 -168
  492. package/schemas/conversation-turn.schema.json +0 -117
  493. package/schemas/core-conformance-mock-agent-config.schema.json +0 -152
  494. package/schemas/credential-provenance.schema.json +0 -18
  495. package/schemas/credential-reference.schema.json +0 -21
  496. package/schemas/debug-bundle.schema.json +0 -196
  497. package/schemas/dispatch-config.schema.json +0 -112
  498. package/schemas/envelopes/clarification.request.schema.json +0 -52
  499. package/schemas/envelopes/error.schema.json +0 -30
  500. package/schemas/envelopes/media.audio.schema.json +0 -38
  501. package/schemas/envelopes/media.file.schema.json +0 -37
  502. package/schemas/envelopes/media.image.schema.json +0 -33
  503. package/schemas/envelopes/schema.request.schema.json +0 -26
  504. package/schemas/envelopes/schema.response.schema.json +0 -22
  505. package/schemas/envelopes/ui.a2ui-surface.schema.json +0 -154
  506. package/schemas/error-envelope.schema.json +0 -25
  507. package/schemas/eval-summary.schema.json +0 -92
  508. package/schemas/export-bundle.schema.json +0 -66
  509. package/schemas/form-content-pack-manifest.schema.json +0 -243
  510. package/schemas/frontend-plugin-manifest.schema.json +0 -109
  511. package/schemas/goal.schema.json +0 -104
  512. package/schemas/heartbeat-evaluated.schema.json +0 -14
  513. package/schemas/heartbeat-state-changed.schema.json +0 -14
  514. package/schemas/localized-content-language-settings.schema.json +0 -26
  515. package/schemas/localized-content-page-response.schema.json +0 -60
  516. package/schemas/localized-content-page.schema.json +0 -62
  517. package/schemas/localized-content-section.schema.json +0 -51
  518. package/schemas/memory-entry.schema.json +0 -36
  519. package/schemas/memory-list-options.schema.json +0 -37
  520. package/schemas/node-pack-manifest.schema.json +0 -654
  521. package/schemas/orchestrator-decision.schema.json +0 -90
  522. package/schemas/org-chart-responsibility-view.schema.json +0 -26
  523. package/schemas/pack-lockfile.schema.json +0 -108
  524. package/schemas/prompt-kind.schema.json +0 -8
  525. package/schemas/prompt-pack-manifest.schema.json +0 -117
  526. package/schemas/prompt-ref.schema.json +0 -40
  527. package/schemas/prompt-template.schema.json +0 -149
  528. package/schemas/proposal.schema.json +0 -84
  529. package/schemas/registry-version-manifest.schema.json +0 -208
  530. package/schemas/residency.schema.json +0 -16
  531. package/schemas/run-ancestry-response.schema.json +0 -54
  532. package/schemas/run-diff-response.schema.json +0 -64
  533. package/schemas/run-event-payloads.schema.json +0 -4452
  534. package/schemas/run-event.schema.json +0 -211
  535. package/schemas/run-options.schema.json +0 -80
  536. package/schemas/run-orchestrator-decided-event.schema.json +0 -20
  537. package/schemas/run-snapshot.schema.json +0 -148
  538. package/schemas/security-advisory.schema.json +0 -109
  539. package/schemas/self-hosted-runner-dispatch-frame.schema.json +0 -79
  540. package/schemas/self-hosted-runner-registration.schema.json +0 -53
  541. package/schemas/self-hosted-runner-result-frame.schema.json +0 -38
  542. package/schemas/subject.schema.json +0 -56
  543. package/schemas/suspend-request.schema.json +0 -207
  544. package/schemas/tool-descriptor.schema.json +0 -63
  545. package/schemas/trigger-event.schema.json +0 -222
  546. package/schemas/trigger-subscription-registration.schema.json +0 -67
  547. package/schemas/trigger-subscription.schema.json +0 -26
  548. package/schemas/ui-plugin-message.schema.json +0 -90
  549. package/schemas/workflow-chain-pack-manifest.schema.json +0 -615
  550. package/schemas/workflow-definition.schema.json +0 -850
  551. package/schemas/workload-identity.schema.json +0 -79
  552. package/schemas/workspace-file-create.schema.json +0 -20
  553. package/schemas/workspace-file.schema.json +0 -39
@@ -30,8 +30,8 @@ import { SCHEMAS_DIR } from '../lib/paths.js';
30
30
  import { driver } from '../lib/driver.js';
31
31
  import { behaviorGate } from '../lib/behavior-gate.js';
32
32
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
33
-
34
- 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';
35
35
  function loadSchema(name: string): Record<string, unknown> {
36
36
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
37
37
  }
@@ -43,12 +43,12 @@ describe('export-bundle-portability: capability advertisement (RFC 0098 §A, ser
43
43
  const portability = (caps.properties as Record<string, { properties?: Record<string, unknown>; if?: unknown; then?: unknown }>).portability;
44
44
 
45
45
  it('capabilities schema declares portability with its sub-flags + the import⇒dryRun if/then', () => {
46
- expect(portability, why('capabilities.md §portability', 'portability MUST be declared')).toBeDefined();
46
+ expect(portability, req('openwop.it.export-bundle-portability.capabilities-schema-declares-portability-with-its-sub-flags-the-import-dryrun-if', 'capabilities.md §portability', 'portability MUST be declared')).toBeDefined();
47
47
  for (const flag of ['export', 'import', 'kinds', 'dryRun']) {
48
- expect(portability?.properties?.[flag], why('RFC 0098 §A', `portability.${flag} MUST be declared`)).toBeDefined();
48
+ expect(portability?.properties?.[flag], req('openwop.it.export-bundle-portability.capabilities-schema-declares-portability-with-its-sub-flags-the-import-dryrun-if', 'RFC 0098 §A', `portability.${flag} MUST be declared`)).toBeDefined();
49
49
  }
50
- expect(portability?.if, why('RFC 0098 §A', 'a JSON-Schema if/then MUST enforce dryRun:true when import:true')).toBeDefined();
51
- expect(portability?.then, why('RFC 0098 §A', 'the then-branch MUST require dryRun')).toBeDefined();
50
+ expect(portability?.if, req('openwop.it.export-bundle-portability.capabilities-schema-declares-portability-with-its-sub-flags-the-import-dryrun-if', 'RFC 0098 §A', 'a JSON-Schema if/then MUST enforce dryRun:true when import:true')).toBeDefined();
51
+ expect(portability?.then, req('openwop.it.export-bundle-portability.capabilities-schema-declares-portability-with-its-sub-flags-the-import-dryrun-if', 'RFC 0098 §A', 'the then-branch MUST require dryRun')).toBeDefined();
52
52
  });
53
53
  });
54
54
 
@@ -67,19 +67,19 @@ describe('export-bundle-portability: ExportBundle shape (RFC 0098 §B, server-fr
67
67
  };
68
68
 
69
69
  it('validates a conforming bundle with refs only', () => {
70
- expect(validate(good), why('RFC 0098 §B', `a conforming bundle MUST validate. Errors: ${JSON.stringify(validate.errors)}`)).toBe(true);
70
+ expect(validate(good), req('openwop.it.export-bundle-portability.validates-a-conforming-bundle-with-refs-only', 'RFC 0098 §B', `a conforming bundle MUST validate. Errors: ${JSON.stringify(validate.errors)}`)).toBe(true);
71
71
  });
72
72
 
73
73
  it('rejects a wrong bundleVersion, an unknown kind, and a missing item ref', () => {
74
- expect(validate({ ...good, bundleVersion: '2' }), why('RFC 0098 §B', 'an unsupported bundleVersion MUST be rejected')).toBe(false);
75
- expect(validate({ ...good, items: [{ kind: 'mystery', ref: 'x', payload: {} }] }), why('RFC 0098 §B', 'an unknown item kind MUST be rejected')).toBe(false);
76
- expect(validate({ ...good, items: [{ kind: 'agent', payload: {} }] }), why('RFC 0098 §B', 'an item without a ref MUST be rejected')).toBe(false);
74
+ expect(validate({ ...good, bundleVersion: '2' }), req('openwop.it.export-bundle-portability.rejects-a-wrong-bundleversion-an-unknown-kind-and-a-missing-item-ref', 'RFC 0098 §B', 'an unsupported bundleVersion MUST be rejected')).toBe(false);
75
+ expect(validate({ ...good, items: [{ kind: 'mystery', ref: 'x', payload: {} }] }), req('openwop.it.export-bundle-portability.rejects-a-wrong-bundleversion-an-unknown-kind-and-a-missing-item-ref', 'RFC 0098 §B', 'an unknown item kind MUST be rejected')).toBe(false);
76
+ expect(validate({ ...good, items: [{ kind: 'agent', payload: {} }] }), req('openwop.it.export-bundle-portability.rejects-a-wrong-bundleversion-an-unknown-kind-and-a-missing-item-ref', 'RFC 0098 §B', 'an item without a ref MUST be rejected')).toBe(false);
77
77
  });
78
78
 
79
79
  it('the bundle envelope admits no credential-named field at the root or source level (additionalProperties:false)', () => {
80
80
  for (const name of CRED_NAMES) {
81
- expect(validate({ ...good, [name]: 'xxx' }), why('SECURITY invariant export-bundle-no-credential-material', `a "${name}" field at the bundle root MUST NOT validate`)).toBe(false);
82
- expect(validate({ ...good, source: { ...good.source, [name]: 'xxx' } }), why('SECURITY invariant export-bundle-no-credential-material', `a "${name}" field under source MUST NOT validate`)).toBe(false);
81
+ expect(validate({ ...good, [name]: 'xxx' }), req('openwop.it.export-bundle-portability.the-bundle-envelope-admits-no-credential-named-field-at-the-root-or-source-level', 'SECURITY invariant export-bundle-no-credential-material', `a "${name}" field at the bundle root MUST NOT validate`)).toBe(false);
82
+ expect(validate({ ...good, source: { ...good.source, [name]: 'xxx' } }), req('openwop.it.export-bundle-portability.the-bundle-envelope-admits-no-credential-named-field-at-the-root-or-source-level', 'SECURITY invariant export-bundle-no-credential-material', `a "${name}" field under source MUST NOT validate`)).toBe(false);
83
83
  }
84
84
  });
85
85
  });
@@ -93,10 +93,10 @@ describe('export-bundle-portability: content-free event (RFC 0098 §D, server-fr
93
93
 
94
94
  it('import.applied is in the RunEventType enum and is content-free (counts + refs only)', () => {
95
95
  const en = (runEvent.$defs as Record<string, { enum?: string[] }>).RunEventType?.enum ?? [];
96
- expect(en).toContain('import.applied');
96
+ expect(en, req('openwop.it.export-bundle-portability.import-applied-is-in-the-runeventtype-enum-and-is-content-free-counts-refs-only', 'export-bundle-portability.test.ts (no spec citation in file)', 'import.applied is in the RunEventType enum and is content-free (counts + refs only)')).toContain('import.applied');
97
97
  const applied = ajv.getSchema('payloads#/$defs/importApplied')!;
98
- expect(applied({ bundleOrigin: 'https://host-a.example', counts: { created: 2, skipped: 1 }, secretsToRebind: ['anthropic'] }), why('RFC 0098 §D', 'a content-free import.applied MUST validate')).toBe(true);
99
- expect(applied({ bundleOrigin: 'h', counts: { created: 1 }, items: [{ payload: {} }] }), why('SECURITY invariant export-bundle-no-credential-material', 'import.applied MUST NOT carry item payloads')).toBe(false);
98
+ expect(applied({ bundleOrigin: 'https://host-a.example', counts: { created: 2, skipped: 1 }, secretsToRebind: ['anthropic'] }), req('openwop.it.export-bundle-portability.import-applied-is-in-the-runeventtype-enum-and-is-content-free-counts-refs-only', 'RFC 0098 §D', 'a content-free import.applied MUST validate')).toBe(true);
99
+ expect(applied({ bundleOrigin: 'h', counts: { created: 1 }, items: [{ payload: {} }] }), req('openwop.it.export-bundle-portability.import-applied-is-in-the-runeventtype-enum-and-is-content-free-counts-refs-only', 'SECURITY invariant export-bundle-no-credential-material', 'import.applied MUST NOT carry item payloads')).toBe(false);
100
100
  });
101
101
  });
102
102
 
@@ -111,10 +111,10 @@ describe('export-bundle-portability: behavioral (RFC 0098 §E, capability-gated)
111
111
  items: [{ kind: 'connection-ref', ref: 'c1', payload: { provider: 'anthropic', apiKey: 'sk-conformance-canary' } }],
112
112
  };
113
113
  const res = await driver.post('/v1/host/sample/import?dryRun=true', { bundle: leaky });
114
- if (res.status === 404 || res.status === 403) return; // seam unwired — soft-skip
114
+ if (res.status === 404 || res.status === 403) return softSkip('blocked', 'precondition not met — `res.status === 404 || res.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
115
115
  expect(
116
116
  res.status,
117
- driver.describe('portability.md §Invariants clause 1', 'a bundle carrying a literal credential value MUST be rejected (422)'),
117
+ req('openwop.it.export-bundle-portability.importing-a-bundle-with-a-literal-credential-value-is-rejected-422', 'portability.md §Invariants clause 1', 'a bundle carrying a literal credential value MUST be rejected (422)'),
118
118
  ).toBe(422);
119
119
  });
120
120
  });
@@ -8,6 +8,7 @@ import { describe, it, expect } from 'vitest';
8
8
  import { driver } from '../lib/driver.js';
9
9
  import { pollUntilTerminal } from '../lib/polling.js';
10
10
  import { isFixtureAdvertised } from '../lib/fixtures.js';
11
+ import { req } from '../lib/requirement-ids.js';
11
12
 
12
13
  const WORKFLOW_ID = 'conformance-failure';
13
14
  const SKIP_NO_FIXTURE = !isFixtureAdvertised(WORKFLOW_ID);
@@ -15,7 +16,7 @@ const SKIP_NO_FIXTURE = !isFixtureAdvertised(WORKFLOW_ID);
15
16
  describe.skipIf(SKIP_NO_FIXTURE)('failure: conformance-failure fixture reaches terminal `failed`', () => {
16
17
  it('POST /v1/runs accepts the run and run terminates as failed with structured error', async () => {
17
18
  const create = await driver.post('/v1/runs', { workflowId: WORKFLOW_ID });
18
- expect(create.status, driver.describe(
19
+ expect(create.status, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error',
19
20
  'rest-endpoints.md',
20
21
  'POST /v1/runs MUST return 201 even for fixtures that fail at runtime',
21
22
  )).toBe(201);
@@ -23,22 +24,22 @@ describe.skipIf(SKIP_NO_FIXTURE)('failure: conformance-failure fixture reaches t
23
24
 
24
25
  const terminal = await pollUntilTerminal(runId);
25
26
 
26
- expect(terminal.status, driver.describe(
27
+ expect(terminal.status, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error',
27
28
  'fixtures.md conformance-failure §Terminal status',
28
29
  'fixture MUST reach terminal `failed`',
29
30
  )).toBe('failed');
30
31
 
31
- expect(typeof terminal.error, driver.describe(
32
+ expect(typeof terminal.error, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error',
32
33
  'rest-endpoints.md RunSnapshot.error',
33
34
  'RunSnapshot.error MUST be a structured object on terminal `failed`',
34
35
  )).toBe('object');
35
- expect(terminal.error, 'RunSnapshot.error MUST be non-null').not.toBeNull();
36
+ expect(terminal.error, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error', 'rest-endpoints.md RunSnapshot.error', 'RunSnapshot.error MUST be non-null')).not.toBeNull();
36
37
 
37
- expect(typeof terminal.error?.code, driver.describe(
38
+ expect(typeof terminal.error?.code, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error',
38
39
  'rest-endpoints.md RunSnapshot.error.code',
39
40
  'RunSnapshot.error.code MUST be a string',
40
41
  )).toBe('string');
41
- expect(typeof terminal.error?.message, driver.describe(
42
+ expect(typeof terminal.error?.message, req('openwop.it.failure-path.post-v1-runs-accepts-the-run-and-run-terminates-as-failed-with-structured-error',
42
43
  'rest-endpoints.md RunSnapshot.error.message',
43
44
  'RunSnapshot.error.message MUST be a string',
44
45
  )).toBe('string');
@@ -10,16 +10,17 @@
10
10
  */
11
11
 
12
12
  import { describe, it, expect } from 'vitest';
13
- import { driver } from '../lib/driver.js';
14
13
  import { readFeedbackCap } from '../lib/feedback.js';
14
+ import { req } from '../lib/requirement-ids.js';
15
+ import { softSkip } from '../lib/soft-skip.js';
15
16
 
16
17
  describe('feedback-capability-shape: advertisement (RFC 0056 §A)', () => {
17
18
  it('capabilities.feedback is absent or a well-formed object', async () => {
18
19
  const cap = await readFeedbackCap();
19
- if (cap === null) return; // not advertised — valid
20
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early (not advertised — valid)'); // not advertised — valid
20
21
  expect(
21
22
  typeof cap.supported,
22
- driver.describe('capabilities.schema.json §feedback', 'capabilities.feedback.supported MUST be a boolean when present'),
23
+ req('openwop.it.feedback-capability-shape.capabilities-feedback-is-absent-or-a-well-formed-object', 'capabilities.schema.json §feedback', 'capabilities.feedback.supported MUST be a boolean when present'),
23
24
  ).toBe('boolean');
24
25
  if (Array.isArray(cap.targets)) {
25
26
  for (const t of cap.targets) {
@@ -12,6 +12,7 @@ import { describe, it, expect } from 'vitest';
12
12
  import { softSkip } from '../lib/soft-skip.js';
13
13
  import { driver } from '../lib/driver.js';
14
14
  import { readFeedbackCap, seedRun } from '../lib/feedback.js';
15
+ import { req } from '../lib/requirement-ids.js';
15
16
 
16
17
  const CANARY = 'sk-canary-rfc0056-do-not-leak-abc123';
17
18
 
@@ -30,7 +31,7 @@ describe('feedback-correction-redaction (RFC 0056 §E)', () => {
30
31
  const list = await driver.get(`/v1/runs/${runId}/annotations`);
31
32
  expect(
32
33
  JSON.stringify(list.json ?? {}).includes(CANARY),
33
- driver.describe('RFC 0056 §E', 'secret-shaped material MUST be redacted before persistence/listing (SR-1)'),
34
+ req('openwop.it.feedback-correction-redaction.secret-shaped-material-in-correction-note-is-redacted-in-the-annotation-list', 'RFC 0056 §E', 'secret-shaped material MUST be redacted before persistence/listing (SR-1)'),
34
35
  ).toBe(false);
35
36
  });
36
37
  });
@@ -16,6 +16,7 @@ import { describe, it, expect } from 'vitest';
16
16
  import { softSkip } from '../lib/soft-skip.js';
17
17
  import { driver } from '../lib/driver.js';
18
18
  import { readFeedbackCap, seedRun } from '../lib/feedback.js';
19
+ import { req } from '../lib/requirement-ids.js';
19
20
 
20
21
  describe('feedback-cross-tenant-isolation (RFC 0056 §E)', () => {
21
22
  it('a run\'s annotation list contains only that run\'s annotations', async () => {
@@ -31,7 +32,7 @@ describe('feedback-cross-tenant-isolation (RFC 0056 §E)', () => {
31
32
  for (const a of ann) {
32
33
  expect(
33
34
  a.target?.runId,
34
- driver.describe('RFC 0056 §E', 'an annotation list MUST contain only this run\'s annotations (CTI-1)'),
35
+ req('openwop.it.feedback-cross-tenant-isolation.a-run-s-annotation-list-contains-only-that-run-s-annotations', 'RFC 0056 §E', 'an annotation list MUST contain only this run\'s annotations (CTI-1)'),
35
36
  ).toBe(runId);
36
37
  }
37
38
  });
@@ -12,6 +12,7 @@ import { softSkip } from '../lib/soft-skip.js';
12
12
  import { driver } from '../lib/driver.js';
13
13
  import { pollUntilTerminal } from '../lib/polling.js';
14
14
  import { readFeedbackCap, seedRun } from '../lib/feedback.js';
15
+ import { req } from '../lib/requirement-ids.js';
15
16
 
16
17
  describe('feedback-fork-not-copied (RFC 0056 §D)', () => {
17
18
  it('a fork of an annotated run starts with zero annotations', async () => {
@@ -25,7 +26,7 @@ describe('feedback-fork-not-copied (RFC 0056 §D)', () => {
25
26
  try {
26
27
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
27
28
  } catch {
28
- return;
29
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
29
30
  }
30
31
  const fork = await driver.post(`/v1/runs/${runId}:fork`, { fromSeq: 0, mode: 'branch' });
31
32
  if (fork.status !== 200 && fork.status !== 201) return softSkip('inapplicable', 'fork unsupported — soft-skip (fork.status !== 200 && fork.status !== 201)');
@@ -35,7 +36,7 @@ describe('feedback-fork-not-copied (RFC 0056 §D)', () => {
35
36
  const ann = (list.json as { annotations?: unknown[] } | undefined)?.annotations ?? [];
36
37
  expect(
37
38
  ann.length,
38
- driver.describe('RFC 0056 §D', 'annotations are a side-store and MUST NOT be copied into a fork'),
39
+ req('openwop.it.feedback-fork-not-copied.a-fork-of-an-annotated-run-starts-with-zero-annotations', 'RFC 0056 §D', 'annotations are a side-store and MUST NOT be copied into a fork'),
39
40
  ).toBe(0);
40
41
  });
41
42
  });
@@ -11,6 +11,7 @@ import { softSkip } from '../lib/soft-skip.js';
11
11
  import { driver } from '../lib/driver.js';
12
12
  import { pollUntilTerminal } from '../lib/polling.js';
13
13
  import { readFeedbackCap, seedRun } from '../lib/feedback.js';
14
+ import { req } from '../lib/requirement-ids.js';
14
15
 
15
16
  describe('feedback-on-terminal-run (RFC 0056 §C)', () => {
16
17
  it('annotating a terminal run is accepted', async () => {
@@ -21,13 +22,13 @@ describe('feedback-on-terminal-run (RFC 0056 §C)', () => {
21
22
  try {
22
23
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
23
24
  } catch {
24
- return; // run didn't reach terminal in time — soft-skip
25
+ return softSkip('blocked', 'precondition not met — an earlier step threw (run didn\'t reach terminal in time — soft-skip) (seam, prior step, or fixture unavailable)'); // run didn't reach terminal in time — soft-skip
25
26
  }
26
27
  const post = await driver.post(`/v1/runs/${runId}/annotations`, { signal: { kind: 'flag' }, note: 'post-hoc review' });
27
28
  if (post.status === 501 || post.status === 404) return softSkip('blocked', 'precondition not met — `post.status === 501 || post.status === 404` returned early (seam, prior step, or fixture unavailable)');
28
29
  expect(
29
30
  post.status,
30
- driver.describe('RFC 0056 §C', 'a host MUST accept an annotation on a terminal run'),
31
+ req('openwop.it.feedback-on-terminal-run.annotating-a-terminal-run-is-accepted', 'RFC 0056 §C', 'a host MUST accept an annotation on a terminal run'),
31
32
  ).toBe(201);
32
33
  });
33
34
  });
@@ -10,6 +10,7 @@ import { describe, it, expect } from 'vitest';
10
10
  import { softSkip } from '../lib/soft-skip.js';
11
11
  import { driver } from '../lib/driver.js';
12
12
  import { readFeedbackCap, seedRun } from '../lib/feedback.js';
13
+ import { req } from '../lib/requirement-ids.js';
13
14
 
14
15
  describe('feedback-record-and-list (RFC 0056 §C)', () => {
15
16
  it('POST an annotation then GET returns it', async () => {
@@ -21,7 +22,7 @@ describe('feedback-record-and-list (RFC 0056 §C)', () => {
21
22
  if (post.status === 501 || post.status === 404) return softSkip('blocked', 'precondition not met — `post.status === 501 || post.status === 404` returned early (seam, prior step, or fixture unavailable)');
22
23
  expect(
23
24
  post.status,
24
- driver.describe('RFC 0056 §C', 'POST annotation returns 201 with the persisted annotation'),
25
+ req('openwop.it.feedback-record-and-list.post-an-annotation-then-get-returns-it', 'RFC 0056 §C', 'POST annotation returns 201 with the persisted annotation'),
25
26
  ).toBe(201);
26
27
  const created = post.json as { annotationId?: string };
27
28
  expect(typeof created.annotationId).toBe('string');
@@ -14,6 +14,7 @@ import { describe, it, expect } from 'vitest';
14
14
  import { softSkip } from '../lib/soft-skip.js';
15
15
  import { driver } from '../lib/driver.js';
16
16
  import { readFeedbackCap } from '../lib/feedback.js';
17
+ import { req } from '../lib/requirement-ids.js';
17
18
 
18
19
  describe('feedback-unsupported-501 (RFC 0056 §C)', () => {
19
20
  it('POST annotations returns 501 capability_not_provided when feedback is unadvertised', async () => {
@@ -25,7 +26,7 @@ describe('feedback-unsupported-501 (RFC 0056 §C)', () => {
25
26
  if (res.status === 404 || res.status === 405) return softSkip('blocked', 'route absent — host predates RFC 0056');
26
27
  expect(
27
28
  res.status,
28
- driver.describe('rest-endpoints.md / RFC 0056 §C', 'unadvertised feedback MUST return 501, not 404'),
29
+ req('openwop.it.feedback-unsupported-501.post-annotations-returns-501-capability-not-provided-when-feedback-is-unadvertis', 'rest-endpoints.md / RFC 0056 §C', 'unadvertised feedback MUST return 501, not 404'),
29
30
  ).toBe(501);
30
31
  const code = (res.json as { error?: string } | undefined)?.error;
31
32
  expect(code).toBe('capability_not_provided');
@@ -27,6 +27,7 @@ import {
27
27
  __resetForTests,
28
28
  } from '../lib/fixtures.js';
29
29
  import { isScenarioOptedOut } from '../lib/env.js';
30
+ import { req } from '../lib/requirement-ids.js';
30
31
 
31
32
  beforeEach(() => {
32
33
  __resetForTests();
@@ -34,54 +35,54 @@ beforeEach(() => {
34
35
 
35
36
  describe('fixtures: cache lifecycle', () => {
36
37
  it('returns false from isFixtureAdvertised before cache is populated', () => {
37
- expect(isFixtureCacheReady()).toBe(false);
38
+ expect(isFixtureCacheReady(), req('openwop.it.fixtures-gating.returns-false-from-isfixtureadvertised-before-cache-is-populated', 'RFC 0003', 'returns false from isFixtureAdvertised before cache is populated')).toBe(false);
38
39
  expect(isFixtureAdvertised('conformance-noop')).toBe(false);
39
40
  });
40
41
 
41
42
  it('returns null from getAdvertisedFixtures before cache is populated', () => {
42
- expect(getAdvertisedFixtures()).toBe(null);
43
+ expect(getAdvertisedFixtures(), req('openwop.it.fixtures-gating.returns-null-from-getadvertisedfixtures-before-cache-is-populated', 'RFC 0003', 'returns null from getAdvertisedFixtures before cache is populated')).toBe(null);
43
44
  });
44
45
 
45
46
  it('isFixtureCacheReady becomes true after setAdvertisedFixtures', () => {
46
47
  setAdvertisedFixtures({ fixtures: [] });
47
- expect(isFixtureCacheReady()).toBe(true);
48
+ expect(isFixtureCacheReady(), req('openwop.it.fixtures-gating.isfixturecacheready-becomes-true-after-setadvertisedfixtures', 'RFC 0003', 'isFixtureCacheReady becomes true after setAdvertisedFixtures')).toBe(true);
48
49
  });
49
50
 
50
51
  it('returns empty set when called with null', () => {
51
52
  setAdvertisedFixtures(null);
52
- expect(getAdvertisedFixtures()?.size).toBe(0);
53
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.returns-empty-set-when-called-with-null', 'RFC 0003', 'returns empty set when called with null')).toBe(0);
53
54
  expect(isFixtureAdvertised('conformance-noop')).toBe(false);
54
55
  });
55
56
 
56
57
  it('returns empty set when called with undefined', () => {
57
58
  setAdvertisedFixtures(undefined);
58
- expect(getAdvertisedFixtures()?.size).toBe(0);
59
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.returns-empty-set-when-called-with-undefined', 'RFC 0003', 'returns empty set when called with undefined')).toBe(0);
59
60
  });
60
61
  });
61
62
 
62
63
  describe('fixtures: discovery-payload parsing', () => {
63
64
  it('populates cache from a well-formed payload', () => {
64
65
  setAdvertisedFixtures({ fixtures: ['conformance-noop', 'conformance-delay'] });
65
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
66
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.populates-cache-from-a-well-formed-payload', 'RFC 0003', 'populates cache from a well-formed payload')).toBe(true);
66
67
  expect(isFixtureAdvertised('conformance-delay')).toBe(true);
67
68
  expect(isFixtureAdvertised('conformance-not-advertised')).toBe(false);
68
69
  });
69
70
 
70
71
  it('treats absent fixtures field as "advertises none"', () => {
71
72
  setAdvertisedFixtures({ protocolVersion: '1.0' });
72
- expect(getAdvertisedFixtures()?.size).toBe(0);
73
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.treats-absent-fixtures-field-as-advertises-none', 'RFC 0003', 'treats absent fixtures field as "advertises none"')).toBe(0);
73
74
  expect(isFixtureAdvertised('conformance-noop')).toBe(false);
74
75
  });
75
76
 
76
77
  it('treats non-array fixtures field as "advertises none"', () => {
77
78
  setAdvertisedFixtures({ fixtures: 'conformance-noop' as unknown as string[] });
78
- expect(getAdvertisedFixtures()?.size).toBe(0);
79
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.treats-non-array-fixtures-field-as-advertises-none', 'RFC 0003', 'treats non-array fixtures field as "advertises none"')).toBe(0);
79
80
  });
80
81
 
81
82
  it('filters out empty-string entries', () => {
82
83
  setAdvertisedFixtures({ fixtures: ['', 'conformance-noop', ''] });
83
84
  const set = getAdvertisedFixtures();
84
- expect(set?.size).toBe(1);
85
+ expect(set?.size, req('openwop.it.fixtures-gating.filters-out-empty-string-entries', 'RFC 0003', 'filters out empty-string entries')).toBe(1);
85
86
  expect(isFixtureAdvertised('conformance-noop')).toBe(true);
86
87
  });
87
88
 
@@ -89,7 +90,7 @@ describe('fixtures: discovery-payload parsing', () => {
89
90
  setAdvertisedFixtures({
90
91
  fixtures: ['conformance-noop', 42, null, undefined] as unknown as string[],
91
92
  });
92
- expect(getAdvertisedFixtures()?.size).toBe(1);
93
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.filters-out-non-string-entries', 'RFC 0003', 'filters out non-string entries')).toBe(1);
93
94
  expect(isFixtureAdvertised('conformance-noop')).toBe(true);
94
95
  });
95
96
 
@@ -97,7 +98,7 @@ describe('fixtures: discovery-payload parsing', () => {
97
98
  setAdvertisedFixtures({
98
99
  fixtures: ['conformance-noop', 'openwop.smoke.byok', 'acme.fixture.foo'],
99
100
  });
100
- expect(isFixtureAdvertised('openwop.smoke.byok')).toBe(true);
101
+ expect(isFixtureAdvertised('openwop.smoke.byok'), req('openwop.it.fixtures-gating.passes-vendor-prefixed-ids-through-unchanged', 'RFC 0003', 'passes vendor-prefixed ids through unchanged')).toBe(true);
101
102
  expect(isFixtureAdvertised('acme.fixture.foo')).toBe(true);
102
103
  });
103
104
 
@@ -105,14 +106,14 @@ describe('fixtures: discovery-payload parsing', () => {
105
106
  setAdvertisedFixtures({
106
107
  fixtures: ['conformance-noop', 'conformance-noop', 'conformance-noop'],
107
108
  });
108
- expect(getAdvertisedFixtures()?.size).toBe(1);
109
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.deduplicates-entries-via-set-semantics', 'RFC 0003', 'deduplicates entries via Set semantics')).toBe(1);
109
110
  });
110
111
  });
111
112
 
112
113
  describe('fixtures: cache replacement (not merge)', () => {
113
114
  it('a second setAdvertisedFixtures call replaces the cache, not merges', () => {
114
115
  setAdvertisedFixtures({ fixtures: ['conformance-noop'] });
115
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
116
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.a-second-setadvertisedfixtures-call-replaces-the-cache-not-merges', 'RFC 0003', 'a second setAdvertisedFixtures call replaces the cache, not merges')).toBe(true);
116
117
 
117
118
  setAdvertisedFixtures({ fixtures: ['conformance-delay'] });
118
119
  expect(isFixtureAdvertised('conformance-noop')).toBe(false);
@@ -122,7 +123,7 @@ describe('fixtures: cache replacement (not merge)', () => {
122
123
  it('replacing with empty array means no fixtures advertised', () => {
123
124
  setAdvertisedFixtures({ fixtures: ['conformance-noop'] });
124
125
  setAdvertisedFixtures({ fixtures: [] });
125
- expect(getAdvertisedFixtures()?.size).toBe(0);
126
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.replacing-with-empty-array-means-no-fixtures-advertised', 'RFC 0003', 'replacing with empty array means no fixtures advertised')).toBe(0);
126
127
  expect(isFixtureAdvertised('conformance-noop')).toBe(false);
127
128
  });
128
129
  });
@@ -130,7 +131,7 @@ describe('fixtures: cache replacement (not merge)', () => {
130
131
  describe('fixtures: __resetForTests', () => {
131
132
  it('returns the cache to the pre-populated state', () => {
132
133
  setAdvertisedFixtures({ fixtures: ['conformance-noop'] });
133
- expect(isFixtureCacheReady()).toBe(true);
134
+ expect(isFixtureCacheReady(), req('openwop.it.fixtures-gating.returns-the-cache-to-the-pre-populated-state', 'RFC 0003', 'returns the cache to the pre-populated state')).toBe(true);
134
135
  __resetForTests();
135
136
  expect(isFixtureCacheReady()).toBe(false);
136
137
  expect(getAdvertisedFixtures()).toBe(null);
@@ -153,7 +154,7 @@ describe('fixtures: OPENWOP_OPTED_OUT_FIXTURES env filtering', () => {
153
154
  setAdvertisedFixtures({
154
155
  fixtures: ['conformance-noop', 'conformance-dispatch-input-mapping'],
155
156
  });
156
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
157
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.exact-id-is-filtered-out-of-the-advertised-set', 'RFC 0003', 'exact id is filtered out of the advertised set')).toBe(true);
157
158
  expect(isFixtureAdvertised('conformance-dispatch-input-mapping')).toBe(false);
158
159
  });
159
160
 
@@ -167,7 +168,7 @@ describe('fixtures: OPENWOP_OPTED_OUT_FIXTURES env filtering', () => {
167
168
  'conformance-dispatch-cross-worker-handoff',
168
169
  ],
169
170
  });
170
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
171
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.trailing-glob-filters-every-matching-id', 'RFC 0003', 'trailing-* glob filters every matching id')).toBe(true);
171
172
  expect(isFixtureAdvertised('conformance-dispatch-input-mapping')).toBe(false);
172
173
  expect(isFixtureAdvertised('conformance-dispatch-output-mapping')).toBe(false);
173
174
  expect(isFixtureAdvertised('conformance-dispatch-cross-worker-handoff')).toBe(false);
@@ -184,7 +185,7 @@ describe('fixtures: OPENWOP_OPTED_OUT_FIXTURES env filtering', () => {
184
185
  'conformance-subworkflow-parent',
185
186
  ],
186
187
  });
187
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
188
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.exact-glob-entries-mix-in-one-env-value', 'RFC 0003', 'exact + glob entries mix in one env value')).toBe(true);
188
189
  expect(isFixtureAdvertised('conformance-dispatch-input-mapping')).toBe(false);
189
190
  expect(isFixtureAdvertised('conformance-subworkflow-input-mapping')).toBe(false);
190
191
  // subworkflow-parent is NOT subworkflow-input-mapping — exact match required.
@@ -194,33 +195,33 @@ describe('fixtures: OPENWOP_OPTED_OUT_FIXTURES env filtering', () => {
194
195
  it('non-matching opt-out entries leave the advertised set intact', () => {
195
196
  process.env.OPENWOP_OPTED_OUT_FIXTURES = 'conformance-nonexistent';
196
197
  setAdvertisedFixtures({ fixtures: ['conformance-noop'] });
197
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
198
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.non-matching-opt-out-entries-leave-the-advertised-set-intact', 'RFC 0003', 'non-matching opt-out entries leave the advertised set intact')).toBe(true);
198
199
  expect(getAdvertisedFixtures()?.size).toBe(1);
199
200
  });
200
201
 
201
202
  it('empty / whitespace-only entries are ignored', () => {
202
203
  process.env.OPENWOP_OPTED_OUT_FIXTURES = ', ,conformance-noop, ,';
203
204
  setAdvertisedFixtures({ fixtures: ['conformance-noop', 'conformance-delay'] });
204
- expect(isFixtureAdvertised('conformance-noop')).toBe(false);
205
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.empty-whitespace-only-entries-are-ignored', 'RFC 0003', 'empty / whitespace-only entries are ignored')).toBe(false);
205
206
  expect(isFixtureAdvertised('conformance-delay')).toBe(true);
206
207
  });
207
208
 
208
209
  it('unset env behaves identically to no filtering', () => {
209
210
  delete process.env.OPENWOP_OPTED_OUT_FIXTURES;
210
211
  setAdvertisedFixtures({ fixtures: ['conformance-noop', 'conformance-delay'] });
211
- expect(getAdvertisedFixtures()?.size).toBe(2);
212
+ expect(getAdvertisedFixtures()?.size, req('openwop.it.fixtures-gating.unset-env-behaves-identically-to-no-filtering', 'RFC 0003', 'unset env behaves identically to no filtering')).toBe(2);
212
213
  });
213
214
 
214
215
  it('whitespace-only env behaves identically to unset', () => {
215
216
  process.env.OPENWOP_OPTED_OUT_FIXTURES = ' ';
216
217
  setAdvertisedFixtures({ fixtures: ['conformance-noop'] });
217
- expect(isFixtureAdvertised('conformance-noop')).toBe(true);
218
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.whitespace-only-env-behaves-identically-to-unset', 'RFC 0003', 'whitespace-only env behaves identically to unset')).toBe(true);
218
219
  });
219
220
 
220
221
  it('env is re-read on each setAdvertisedFixtures call (no memoization)', () => {
221
222
  process.env.OPENWOP_OPTED_OUT_FIXTURES = 'conformance-noop';
222
223
  setAdvertisedFixtures({ fixtures: ['conformance-noop', 'conformance-delay'] });
223
- expect(isFixtureAdvertised('conformance-noop')).toBe(false);
224
+ expect(isFixtureAdvertised('conformance-noop'), req('openwop.it.fixtures-gating.env-is-re-read-on-each-setadvertisedfixtures-call-no-memoization', 'RFC 0003', 'env is re-read on each setAdvertisedFixtures call (no memoization)')).toBe(false);
224
225
 
225
226
  // Mutate env and re-set — the new env value MUST take effect.
226
227
  process.env.OPENWOP_OPTED_OUT_FIXTURES = 'conformance-delay';
@@ -239,19 +240,19 @@ describe('env: OPENWOP_OPTED_OUT_SCENARIOS predicate', () => {
239
240
 
240
241
  it('unset env → every scenario id returns false', () => {
241
242
  delete process.env.OPENWOP_OPTED_OUT_SCENARIOS;
242
- expect(isScenarioOptedOut('otel-trace-propagation-subworkflow')).toBe(false);
243
+ expect(isScenarioOptedOut('otel-trace-propagation-subworkflow'), req('openwop.it.fixtures-gating.unset-env-every-scenario-id-returns-false', 'RFC 0003', 'unset env → every scenario id returns false')).toBe(false);
243
244
  expect(isScenarioOptedOut('any-scenario')).toBe(false);
244
245
  });
245
246
 
246
247
  it('exact scenario id match returns true', () => {
247
248
  process.env.OPENWOP_OPTED_OUT_SCENARIOS = 'otel-trace-propagation-subworkflow';
248
- expect(isScenarioOptedOut('otel-trace-propagation-subworkflow')).toBe(true);
249
+ expect(isScenarioOptedOut('otel-trace-propagation-subworkflow'), req('openwop.it.fixtures-gating.exact-scenario-id-match-returns-true', 'RFC 0003', 'exact scenario id match returns true')).toBe(true);
249
250
  expect(isScenarioOptedOut('otel-trace-propagation')).toBe(false);
250
251
  });
251
252
 
252
253
  it('CSV with multiple ids matches each entry exactly', () => {
253
254
  process.env.OPENWOP_OPTED_OUT_SCENARIOS = 'scenario-a,scenario-b,scenario-c';
254
- expect(isScenarioOptedOut('scenario-a')).toBe(true);
255
+ expect(isScenarioOptedOut('scenario-a'), req('openwop.it.fixtures-gating.csv-with-multiple-ids-matches-each-entry-exactly', 'RFC 0003', 'CSV with multiple ids matches each entry exactly')).toBe(true);
255
256
  expect(isScenarioOptedOut('scenario-b')).toBe(true);
256
257
  expect(isScenarioOptedOut('scenario-c')).toBe(true);
257
258
  expect(isScenarioOptedOut('scenario-d')).toBe(false);
@@ -259,13 +260,13 @@ describe('env: OPENWOP_OPTED_OUT_SCENARIOS predicate', () => {
259
260
 
260
261
  it('whitespace around entries is tolerated', () => {
261
262
  process.env.OPENWOP_OPTED_OUT_SCENARIOS = ' scenario-a , scenario-b ';
262
- expect(isScenarioOptedOut('scenario-a')).toBe(true);
263
+ expect(isScenarioOptedOut('scenario-a'), req('openwop.it.fixtures-gating.whitespace-around-entries-is-tolerated', 'RFC 0003', 'whitespace around entries is tolerated')).toBe(true);
263
264
  expect(isScenarioOptedOut('scenario-b')).toBe(true);
264
265
  });
265
266
 
266
267
  it('env is re-read on each call (no memoization)', () => {
267
268
  process.env.OPENWOP_OPTED_OUT_SCENARIOS = 'scenario-a';
268
- expect(isScenarioOptedOut('scenario-a')).toBe(true);
269
+ expect(isScenarioOptedOut('scenario-a'), req('openwop.it.fixtures-gating.env-is-re-read-on-each-call-no-memoization', 'RFC 0003', 'env is re-read on each call (no memoization)')).toBe(true);
269
270
  expect(isScenarioOptedOut('scenario-b')).toBe(false);
270
271
 
271
272
  process.env.OPENWOP_OPTED_OUT_SCENARIOS = 'scenario-b';