@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
@@ -48,6 +48,7 @@ import { describe, it, expect } from 'vitest';
48
48
  import { softSkip } from '../lib/soft-skip.js';
49
49
  import { driver } from '../lib/driver.js';
50
50
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
51
+ import { req } from '../lib/requirement-ids.js';
51
52
 
52
53
  const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
53
54
 
@@ -80,18 +81,18 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: advertisement shape (R
80
81
  if (d === null) {
81
82
  softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
82
83
  ctx.skip();
83
- return;
84
+ return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
84
85
  }
85
86
  const rd = capabilityFamily<{ executionModel?: { [k: string]: unknown; crossHostCausation?: Record<string, unknown>; replayDeterminism?: Record<string, unknown> } }>(d, 'multiAgent')?.executionModel?.replayDeterminism;
86
87
  if (rd === undefined) {
87
88
  softSkip('inapplicable', 'optional advertisement — `multiAgent.executionModel.replayDeterminism` not advertised by this host (RFC 0041 §D)');
88
89
  ctx.skip(); // optional advertisement — host hasn't opted in
89
- return;
90
+ return softSkip('blocked', 'precondition not met — `rd === undefined` returned early (seam, prior step, or fixture unavailable)');
90
91
  }
91
92
 
92
93
  expect(
93
94
  typeof rd.supported,
94
- driver.describe(
95
+ req('openwop.it.replay-divergence-at-refusal.replaydeterminism-when-present-conforms-to-rfc-0041-d',
95
96
  'RFCS/0041-multi-agent-replay-under-nondeterminism.md §D',
96
97
  'replayDeterminism.supported MUST be boolean when present',
97
98
  ),
@@ -101,7 +102,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: advertisement shape (R
101
102
  const version = capabilityFamily<{ executionModel?: { [k: string]: unknown; crossHostCausation?: Record<string, unknown>; replayDeterminism?: Record<string, unknown> } }>(d, 'multiAgent')?.executionModel?.version as number | undefined;
102
103
  expect(
103
104
  typeof version === 'number' && version >= 4,
104
- driver.describe(
105
+ req('openwop.it.replay-divergence-at-refusal.replaydeterminism-when-present-conforms-to-rfc-0041-d',
105
106
  'RFCS/0041-multi-agent-replay-under-nondeterminism.md §D',
106
107
  'when replayDeterminism.supported: true, multiAgent.executionModel.version MUST be >= 4',
107
108
  ),
@@ -114,7 +115,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: advertisement shape (R
114
115
  // assertion closes the conformance-enforcement gap.
115
116
  expect(
116
117
  rd.refusalDivergenceEmission,
117
- driver.describe(
118
+ req('openwop.it.replay-divergence-at-refusal.replaydeterminism-when-present-conforms-to-rfc-0041-d',
118
119
  'schemas/capabilities.schema.json §replayDeterminism.refusalDivergenceEmission',
119
120
  'hosts advertising version: 4 MUST set replayDeterminism.refusalDivergenceEmission to true',
120
121
  ),
@@ -196,7 +197,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
196
197
  if (programStatus === 404) {
197
198
  softSkip('blocked', 'precondition not met — `programStatus === 404` returned early (seam, prior step, or fixture unavailable)');
198
199
  ctx.skip(); // mock-AI program seam not exposed — soft-skip
199
- return;
200
+ return softSkip('blocked', 'precondition not met — `programStatus === 404` returned early (seam, prior step, or fixture unavailable)');
200
201
  }
201
202
  expect(programStatus).toBe(200);
202
203
 
@@ -206,7 +207,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
206
207
  if (createRes.status === 404 || createRes.status === 422) {
207
208
  softSkip('blocked', 'precondition not met — `createRes.status === 404 || createRes.status === 422` returned early (seam, prior step, or fixture unavailable)');
208
209
  ctx.skip(); // fixture not advertised
209
- return;
210
+ return softSkip('blocked', 'precondition not met — `createRes.status === 404 || createRes.status === 422` returned early (seam, prior step, or fixture unavailable)');
210
211
  }
211
212
  expect(createRes.status).toBe(201);
212
213
  const sourceRunId = (createRes.json as { runId: string }).runId;
@@ -228,14 +229,14 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
228
229
 
229
230
  expect(
230
231
  replayTerminal.status,
231
- driver.describe(
232
+ req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref',
232
233
  'RFCS/0041-multi-agent-replay-under-nondeterminism.md §B + spec/v1/rest-endpoints.md §"Common error codes"',
233
234
  'replay MUST terminate `failed` when refusal-divergence is detected (silent substitution is non-conformant)',
234
235
  ),
235
236
  ).toBe('failed');
236
237
  expect(
237
238
  replayTerminal.error?.code,
238
- driver.describe(
239
+ req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref',
239
240
  'spec/v1/rest-endpoints.md §"Common error codes" — replay_diverged_at_refusal',
240
241
  'error.code MUST be `replay_diverged_at_refusal` per the canonical catalog',
241
242
  ),
@@ -245,7 +246,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
245
246
  const divergenceEvent = replayEvents.find((e) => e.type === 'replay.divergedAtRefusal');
246
247
  expect(
247
248
  divergenceEvent,
248
- driver.describe(
249
+ req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref',
249
250
  'schemas/run-event-payloads.schema.json §replayDivergedAtRefusal',
250
251
  'replay event log MUST contain exactly one `replay.divergedAtRefusal` event identifying the divergence',
251
252
  ),
@@ -254,14 +255,14 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
254
255
  expect(divergenceEvent?.payload?.nodeId).toBe(NODE_ID);
255
256
  expect(
256
257
  divergenceEvent?.payload?.originalEnvelopeKind,
257
- driver.describe(
258
+ req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref',
258
259
  'schemas/run-event-payloads.schema.json §replayDivergedAtRefusal.originalEnvelopeKind',
259
260
  'originalEnvelopeKind MUST be `valid` (source run completed normally)',
260
261
  ),
261
262
  ).toBe('valid');
262
263
  expect(
263
264
  divergenceEvent?.payload?.replayEnvelopeKind,
264
- driver.describe(
265
+ req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref',
265
266
  'schemas/run-event-payloads.schema.json §replayDivergedAtRefusal.replayEnvelopeKind',
266
267
  'replayEnvelopeKind MUST be `refusal` (replay hit the refusal entry of the mock program)',
267
268
  ),
@@ -279,9 +280,9 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
279
280
  if (programStatus === 404) {
280
281
  softSkip('blocked', 'precondition not met — `programStatus === 404` returned early (seam, prior step, or fixture unavailable)');
281
282
  ctx.skip();
282
- return;
283
+ return softSkip('blocked', 'precondition not met — `programStatus === 404` returned early (seam, prior step, or fixture unavailable)');
283
284
  }
284
- expect(programStatus).toBe(200);
285
+ expect(programStatus, req('openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref~2', 'RFC 0041 §B', 'Phase 4 host MUST emit replay.divergedAtRefusal + fail with replay_diverged_at_refusal when original=refusal + replay=valid (symmetric case)')).toBe(200);
285
286
 
286
287
  const createRes = await driver.post('/v1/runs', {
287
288
  workflowId: 'conformance-phase4-replay-divergence',
@@ -289,7 +290,7 @@ describe.skipIf(HTTP_SKIP)('replay-divergence-at-refusal: behavioral (RFC 0041
289
290
  if (createRes.status === 404 || createRes.status === 422) {
290
291
  softSkip('blocked', 'precondition not met — `createRes.status === 404 || createRes.status === 422` returned early (seam, prior step, or fixture unavailable)');
291
292
  ctx.skip();
292
- return;
293
+ return softSkip('blocked', 'precondition not met — `createRes.status === 404 || createRes.status === 422` returned early (seam, prior step, or fixture unavailable)');
293
294
  }
294
295
  expect(createRes.status).toBe(201);
295
296
  const sourceRunId = (createRes.json as { runId: string }).runId;
@@ -79,6 +79,7 @@ import { isFixtureAdvertised } from '../lib/fixtures.js';
79
79
  import { discoverOwnedTenant } from '../lib/webhook-receiver.js';
80
80
  import { recordRequirement } from '../lib/requirement-ledger.js';
81
81
  import { requirementIdForFile } from '../lib/scenario-disposition.js';
82
+ import { req } from '../lib/requirement-ids.js';
82
83
 
83
84
  /**
84
85
  * RFC 0148 §A — the MUST NOT gets its OWN disposition, separate from the file's.
@@ -108,10 +109,10 @@ interface Delivered {
108
109
 
109
110
  async function startReceiver(): Promise<{ server: Server; url: string; received: Delivered[] }> {
110
111
  const received: Delivered[] = [];
111
- const server = createServer((req: IncomingMessage, res: ServerResponse) => {
112
+ const server = createServer((reqBody: IncomingMessage, res: ServerResponse) => {
112
113
  const chunks: Buffer[] = [];
113
- req.on('data', (c: Buffer) => chunks.push(c));
114
- req.on('end', () => {
114
+ reqBody.on('data', (c: Buffer) => chunks.push(c));
115
+ reqBody.on('end', () => {
115
116
  received.push({ body: Buffer.concat(chunks).toString('utf8') });
116
117
  res.writeHead(204);
117
118
  res.end();
@@ -193,21 +194,21 @@ describe('replay-fanout-suppression: a replay fork MUST NOT fan out re-emitted e
193
194
  + 'set OPENWOP_WEBHOOK_ALLOW_PRIVATE=true on the host (or equivalent) to run',
194
195
  );
195
196
  }
196
- expect(reg.status, driver.describe(
197
+ expect(reg.status, req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br',
197
198
  'webhooks.md §"Register"',
198
199
  'POST /v1/webhooks MUST return 201 on success',
199
200
  )).toBe(201);
200
201
 
201
202
  // ── LEG 1 — POSITIVE CONTROL. Prove this wiring delivers at all. ─────────
202
203
  const create = await driver.post('/v1/runs', { workflowId: 'conformance-noop' });
203
- expect(create.status, 'failed to start conformance-noop').toBe(201);
204
+ expect(create.status, req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br', 'webhooks.md §"Register"', 'failed to start conformance-noop')).toBe(201);
204
205
  const sourceRunId = (create.json as { runId: string }).runId;
205
206
  await pollUntilTerminal(sourceRunId, { timeoutMs: 10_000 });
206
207
  await quietWindow(DELIVERY_GRACE_MS);
207
208
 
208
209
  expect(
209
210
  forRun(receiver.received, sourceRunId).length,
210
- driver.describe(
211
+ req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br',
211
212
  'webhooks.md §"Register"',
212
213
  'POSITIVE CONTROL: the host must deliver the source run\'s events to this receiver — '
213
214
  + 'without this, every "no delivery" assertion below is vacuous',
@@ -236,7 +237,7 @@ describe('replay-fanout-suppression: a replay fork MUST NOT fan out re-emitted e
236
237
  + 'has nothing to constrain on this host',
237
238
  );
238
239
  ctx.skip();
239
- return;
240
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `replayCap?.supported !== true` returned early');
240
241
  }
241
242
 
242
243
  // ── LEG 2 — THE MUST NOT. A replay fork re-emits; it must not deliver. ───
@@ -261,16 +262,16 @@ describe('replay-fanout-suppression: a replay fork MUST NOT fan out re-emitted e
261
262
  + 'so the absence of deliveries below would prove nothing',
262
263
  );
263
264
  ctx.skip();
264
- return;
265
+ return softSkip('blocked', 'precondition not met — `forkDeclined(replay.status, \'fanout-suppression replay fork\')` returned early (seam, prior step, or fixture unavailable)');
265
266
  }
266
- expect(replay.status, 'replay fork should be accepted').toBe(201);
267
+ expect(replay.status, req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br', 'webhooks.md §"Register"', 'replay fork should be accepted')).toBe(201);
267
268
  const replayRunId = (replay.json as { runId: string }).runId;
268
269
  await pollUntilTerminal(replayRunId, { timeoutMs: 30_000 });
269
270
  await quietWindow(SUPPRESSION_WINDOW_MS);
270
271
 
271
272
  expect(
272
273
  forRun(receiver.received, replayRunId).map((d) => d.body.slice(0, 200)),
273
- driver.describe(
274
+ req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br',
274
275
  'replay.md §"Host-initiated fan-out is an external effect"',
275
276
  'a mode:"replay" fork MUST NOT emit outbound deliveries for the events it re-emits as fixed history — '
276
277
  + 'delivering one asserts to a subscriber that something happened in this run which did not',
@@ -283,11 +284,11 @@ describe('replay-fanout-suppression: a replay fork MUST NOT fan out re-emitted e
283
284
  // still carries them). Without this, a host that simply failed the fork
284
285
  // would pass leg 2.
285
286
  const forkEvents = await driver.get(`/v1/runs/${encodeURIComponent(replayRunId)}/events`);
286
- expect(forkEvents.status, 'fork events must be readable').toBe(200);
287
+ expect(forkEvents.status, req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br', 'replay.md §"Host-initiated fan-out is an external effect"', 'fork events must be readable')).toBe(200);
287
288
  const forkEventList = (forkEvents.json as { events?: { type?: string }[] }).events ?? [];
288
289
  expect(
289
290
  forkEventList.length,
290
- driver.describe(
291
+ req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br',
291
292
  'replay.md §"Host-initiated fan-out is an external effect"',
292
293
  'suppression is OUTBOUND ONLY — the fork\'s own event log MUST still carry the re-emitted events, '
293
294
  + 'so an empty fork log means leg 2 proved nothing',
@@ -309,16 +310,16 @@ describe('replay-fanout-suppression: a replay fork MUST NOT fan out re-emitted e
309
310
  });
310
311
  if (branch.status === 501 || branch.status === 400) {
311
312
  // branch not offered on this range — leg 2 still stands on its own.
312
- return;
313
+ return softSkip('blocked', 'precondition not met — `branch.status === 501 || branch.status === 400` returned early (branch not offered on this range — leg 2 still stands on its own.) (seam, prior step, or fixture unavailable)');
313
314
  }
314
- expect(branch.status, 'branch fork should be accepted').toBe(201);
315
+ expect(branch.status, req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br', 'replay.md §"Host-initiated fan-out is an external effect"', 'branch fork should be accepted')).toBe(201);
315
316
  const branchRunId = (branch.json as { runId: string }).runId;
316
317
  await pollUntilTerminal(branchRunId, { timeoutMs: 30_000 });
317
318
  await quietWindow(DELIVERY_GRACE_MS);
318
319
 
319
320
  expect(
320
321
  forRun(receiver.received, branchRunId).length,
321
- driver.describe(
322
+ req('openwop.it.replay-fanout-suppression.delivers-for-a-live-run-suppresses-for-a-replay-fork-and-delivers-again-for-a-br',
322
323
  'replay.md §"Host-initiated fan-out is an external effect"',
323
324
  'a branch fork is deliberately OUT of scope — its events are new facts, so suppressing them '
324
325
  + 'means the host keyed on "is a fork" rather than on replay-ness read from the run',
@@ -34,6 +34,7 @@ import { softSkip } from '../lib/soft-skip.js';
34
34
  import { forkDeclined } from '../lib/fork-availability.js';
35
35
  import { pollUntilTerminal } from '../lib/polling.js';
36
36
  import { isFixtureAdvertised } from '../lib/fixtures.js';
37
+ import { req } from '../lib/requirement-ids.js';
37
38
 
38
39
  const MULTI_NODE_WORKFLOW_ID = 'conformance-multi-node';
39
40
  const SKIP_NO_MULTI = !isFixtureAdvertised(MULTI_NODE_WORKFLOW_ID);
@@ -126,7 +127,7 @@ describe.skipIf(SKIP_NO_MULTI)(
126
127
  if (replay?.supported !== true) {
127
128
  softSkip('inapplicable', "host does not advertise `replay.supported: true` — the replay contract does not apply to it");
128
129
  ctx.skip();
129
- return;
130
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `replay?.supported !== true` returned early');
130
131
  }
131
132
  const modes = Array.isArray(replay.modes)
132
133
  ? replay.modes.filter((m): m is string => typeof m === 'string')
@@ -134,7 +135,7 @@ describe.skipIf(SKIP_NO_MULTI)(
134
135
  if (!modes.includes('replay')) {
135
136
  softSkip('inapplicable', "host does not advertise the `replay` fork mode — this leg's rule has no path to apply");
136
137
  ctx.skip();
137
- return;
138
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'replay\')` returned early');
138
139
  }
139
140
 
140
141
  const sourceRunId = await startAndFinishMultiNode();
@@ -146,7 +147,7 @@ describe.skipIf(SKIP_NO_MULTI)(
146
147
  // with the standard event shape will hit the assertions below.
147
148
  softSkip('blocked', "the advertised fixture's wire shape exposes no numeric sequence for node.completed(b), so there is no mid-run point to fork from");
148
149
  ctx.skip();
149
- return;
150
+ return softSkip('blocked', 'precondition not met — `fromSeq === null` returned early (seam, prior step, or fixture unavailable)');
150
151
  }
151
152
 
152
153
  const fork = await driver.post(
@@ -156,11 +157,11 @@ describe.skipIf(SKIP_NO_MULTI)(
156
157
 
157
158
  if (forkDeclined(fork.status, 'arbitrary-event fork')) {
158
159
  ctx.skip();
159
- return;
160
+ return softSkip('blocked', 'precondition not met — `forkDeclined(fork.status, \'arbitrary-event fork\')` returned early (seam, prior step, or fixture unavailable)');
160
161
  }
161
162
  expect(
162
163
  fork.status,
163
- driver.describe(
164
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed',
164
165
  'spec/v1/replay.md §"Replay-from-event-log internals"',
165
166
  `mid-range fromSeq=${fromSeq} replay fork MUST return 201`,
166
167
  ),
@@ -171,23 +172,23 @@ describe.skipIf(SKIP_NO_MULTI)(
171
172
  sourceRunId?: unknown;
172
173
  mode?: unknown;
173
174
  };
174
- expect(typeof body.runId, 'fork response MUST include a new runId').toBe(
175
+ expect(typeof body.runId, req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed', 'spec/v1/replay.md §"Replay-from-event-log internals"', 'fork response MUST include a new runId')).toBe(
175
176
  'string',
176
177
  );
177
178
  expect(
178
179
  body.runId,
179
- 'forked runId MUST differ from source',
180
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed', 'spec/v1/replay.md §"Replay-from-event-log internals"', 'forked runId MUST differ from source'),
180
181
  ).not.toBe(sourceRunId);
181
- expect(body.sourceRunId, 'fork response MUST echo sourceRunId').toBe(
182
+ expect(body.sourceRunId, req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed', 'spec/v1/replay.md §"Replay-from-event-log internals"', 'fork response MUST echo sourceRunId')).toBe(
182
183
  sourceRunId,
183
184
  );
184
- expect(body.mode, 'fork response MUST echo mode').toBe('replay');
185
+ expect(body.mode, req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed', 'spec/v1/replay.md §"Replay-from-event-log internals"', 'fork response MUST echo mode')).toBe('replay');
185
186
 
186
187
  const newRunId = body.runId as string;
187
188
  const terminal = await pollUntilTerminal(newRunId, { timeoutMs: 15_000 });
188
189
  expect(
189
190
  terminal.status,
190
- driver.describe(
191
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-replay-fork-produces-a-new-run-that-reaches-completed',
191
192
  'spec/v1/replay.md §"Replay determinism"',
192
193
  `replay fork from mid-range fromSeq=${fromSeq} MUST reach the same terminal status as the source`,
193
194
  ),
@@ -205,14 +206,14 @@ describe.skipIf(SKIP_NO_MULTI)(
205
206
  const replay = await fetchReplayCapability();
206
207
  if (replay?.supported !== true) {
207
208
  ctx.skip();
208
- return;
209
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `replay?.supported !== true` returned early');
209
210
  }
210
211
  const modes = Array.isArray(replay.modes)
211
212
  ? replay.modes.filter((m): m is string => typeof m === 'string')
212
213
  : [];
213
214
  if (!modes.includes('replay')) {
214
215
  ctx.skip();
215
- return;
216
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'replay\')` returned early');
216
217
  }
217
218
 
218
219
  const sourceRunId = await startAndFinishMultiNode();
@@ -220,7 +221,7 @@ describe.skipIf(SKIP_NO_MULTI)(
220
221
  const fromSeq = pickMidRangeFromSeq(sourceEvents);
221
222
  if (fromSeq === null) {
222
223
  ctx.skip();
223
- return;
224
+ return softSkip('blocked', 'precondition not met — `fromSeq === null` returned early (seam, prior step, or fixture unavailable)');
224
225
  }
225
226
 
226
227
  // Fork twice at the same mid-range point. Per replay.md, both
@@ -233,7 +234,7 @@ describe.skipIf(SKIP_NO_MULTI)(
233
234
  );
234
235
  if (forkDeclined(fork1.status, 'arbitrary-event fork 1')) {
235
236
  ctx.skip();
236
- return;
237
+ return softSkip('blocked', 'precondition not met — `forkDeclined(fork1.status, \'arbitrary-event fork 1\')` returned early (seam, prior step, or fixture unavailable)');
237
238
  }
238
239
  expect(fork1.status).toBe(201);
239
240
  const fork1Id = (fork1.json as { runId: string }).runId;
@@ -245,7 +246,7 @@ describe.skipIf(SKIP_NO_MULTI)(
245
246
  );
246
247
  if (forkDeclined(fork2.status, 'arbitrary-event fork 2')) {
247
248
  ctx.skip();
248
- return;
249
+ return softSkip('blocked', 'precondition not met — `forkDeclined(fork2.status, \'arbitrary-event fork 2\')` returned early (seam, prior step, or fixture unavailable)');
249
250
  }
250
251
  expect(fork2.status).toBe(201);
251
252
  const fork2Id = (fork2.json as { runId: string }).runId;
@@ -274,7 +275,7 @@ describe.skipIf(SKIP_NO_MULTI)(
274
275
 
275
276
  expect(
276
277
  tail1.length,
277
- driver.describe(
278
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-determinism-same-source-same-fromseq-identical-post-fork-events-modu',
278
279
  'spec/v1/replay.md §"Replay determinism"',
279
280
  `two replay forks at fromSeq=${fromSeq} MUST produce the same number of re-executed events`,
280
281
  ),
@@ -282,7 +283,7 @@ describe.skipIf(SKIP_NO_MULTI)(
282
283
 
283
284
  expect(
284
285
  structuralShape(tail1),
285
- driver.describe(
286
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-determinism-same-source-same-fromseq-identical-post-fork-events-modu',
286
287
  'spec/v1/replay.md §"Replay determinism"',
287
288
  `event sequence (type/nodeId/data) post-fromSeq=${fromSeq} MUST be identical across two replay forks`,
288
289
  ),
@@ -301,14 +302,14 @@ describe.skipIf(SKIP_NO_MULTI)(
301
302
  if (replay?.supported !== true) {
302
303
  softSkip('inapplicable', "host does not advertise `replay.supported: true` — the replay contract does not apply to it");
303
304
  ctx.skip();
304
- return;
305
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `replay?.supported !== true` returned early');
305
306
  }
306
307
  const modes = Array.isArray(replay.modes)
307
308
  ? replay.modes.filter((m): m is string => typeof m === 'string')
308
309
  : [];
309
310
  if (!modes.includes('branch')) {
310
311
  ctx.skip();
311
- return;
312
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'branch\')` returned early');
312
313
  }
313
314
 
314
315
  const sourceRunId = await startAndFinishMultiNode();
@@ -316,7 +317,7 @@ describe.skipIf(SKIP_NO_MULTI)(
316
317
  const fromSeq = pickMidRangeFromSeq(sourceEvents);
317
318
  if (fromSeq === null) {
318
319
  ctx.skip();
319
- return;
320
+ return softSkip('blocked', 'precondition not met — `fromSeq === null` returned early (seam, prior step, or fixture unavailable)');
320
321
  }
321
322
 
322
323
  // Branch mode with an empty overlay is the boundary case: the
@@ -331,11 +332,11 @@ describe.skipIf(SKIP_NO_MULTI)(
331
332
 
332
333
  if (fork.status === 501) {
333
334
  ctx.skip();
334
- return;
335
+ return softSkip('blocked', 'precondition not met — `fork.status === 501` returned early (seam, prior step, or fixture unavailable)');
335
336
  }
336
337
  expect(
337
338
  fork.status,
338
- driver.describe(
339
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-branch-fork-with-empty-overlay-produces-a-new-run-that-reaches-compl',
339
340
  'spec/v1/replay.md §"branch mode"',
340
341
  `mid-range fromSeq=${fromSeq} branch fork with empty overlay MUST return 201`,
341
342
  ),
@@ -345,7 +346,7 @@ describe.skipIf(SKIP_NO_MULTI)(
345
346
  const terminal = await pollUntilTerminal(newRunId, { timeoutMs: 15_000 });
346
347
  expect(
347
348
  terminal.status,
348
- driver.describe(
349
+ req('openwop.it.replay-fork-arbitrary.mid-fromseq-branch-fork-with-empty-overlay-produces-a-new-run-that-reaches-compl',
349
350
  'spec/v1/replay.md',
350
351
  `branch fork from mid-range fromSeq=${fromSeq} MUST reach terminal status`,
351
352
  ),
@@ -29,6 +29,7 @@ import { softSkip } from '../lib/soft-skip.js';
29
29
  import { forkDeclined } from '../lib/fork-availability.js';
30
30
  import { pollUntilTerminal } from '../lib/polling.js';
31
31
  import { isFixtureAdvertised } from '../lib/fixtures.js';
32
+ import { req } from '../lib/requirement-ids.js';
32
33
 
33
34
  const SOURCE_WORKFLOW_ID = 'conformance-noop';
34
35
  const SKIP_NO_NOOP = !isFixtureAdvertised(SOURCE_WORKFLOW_ID);
@@ -64,7 +65,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: fork from fromSeq=0 in replay mode', () =
64
65
  // unexercised tests apart from honest passes.
65
66
  softSkip('inapplicable', "host does not advertise the `replay` fork mode — this leg's rule has no path to apply");
66
67
  ctx.skip();
67
- return;
68
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'replay\')` returned early');
68
69
  }
69
70
  const sourceRunId = await startAndFinishNoop();
70
71
 
@@ -73,27 +74,27 @@ describe.skipIf(SKIP_NO_NOOP)('replay: fork from fromSeq=0 in replay mode', () =
73
74
  { fromSeq: 0, mode: 'replay' },
74
75
  );
75
76
 
76
- if (forkDeclined(fork.status, 'replay fork')) return;
77
- expect(fork.status, driver.describe(
77
+ if (forkDeclined(fork.status, 'replay fork')) return softSkip('blocked', 'precondition not met — `forkDeclined(fork.status, \'replay fork\')` returned early (seam, prior step, or fixture unavailable)');
78
+ expect(fork.status, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed',
78
79
  'rest-endpoints.md POST /v1/runs/{runId}:fork',
79
80
  'fork MUST return 201 on accepted replay',
80
81
  )).toBe(201);
81
82
 
82
83
  const body = fork.json as { runId?: unknown; sourceRunId?: unknown; mode?: unknown };
83
- expect(typeof body.runId, driver.describe(
84
+ expect(typeof body.runId, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed',
84
85
  'replay.md',
85
86
  'fork response MUST include a new runId',
86
87
  )).toBe('string');
87
- expect(body.runId, 'forked runId MUST differ from source').not.toBe(sourceRunId);
88
- expect(body.sourceRunId, driver.describe(
88
+ expect(body.runId, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed', 'replay.md', 'forked runId MUST differ from source')).not.toBe(sourceRunId);
89
+ expect(body.sourceRunId, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed',
89
90
  'replay.md',
90
91
  'fork response MUST echo sourceRunId',
91
92
  )).toBe(sourceRunId);
92
- expect(body.mode, 'fork response MUST echo mode').toBe('replay');
93
+ expect(body.mode, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed', 'replay.md', 'fork response MUST echo mode')).toBe('replay');
93
94
 
94
95
  const newRunId = body.runId as string;
95
96
  const terminal = await pollUntilTerminal(newRunId, { timeoutMs: 15_000 });
96
- expect(terminal.status, driver.describe(
97
+ expect(terminal.status, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed',
97
98
  'replay.md',
98
99
  'replay of a successful run MUST reach the same terminal status',
99
100
  )).toBe('completed');
@@ -106,7 +107,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: fork from fromSeq=0 in branch mode with e
106
107
  if (!modes.includes('branch')) {
107
108
  softSkip('inapplicable', "host does not advertise the `branch` fork mode — this leg's rule has no path to apply");
108
109
  ctx.skip();
109
- return;
110
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'branch\')` returned early');
110
111
  }
111
112
  const sourceRunId = await startAndFinishNoop();
112
113
 
@@ -115,8 +116,8 @@ describe.skipIf(SKIP_NO_NOOP)('replay: fork from fromSeq=0 in branch mode with e
115
116
  { fromSeq: 0, mode: 'branch', runOptionsOverlay: {} },
116
117
  );
117
118
 
118
- if (forkDeclined(fork.status, 'branch fork')) return;
119
- expect(fork.status, driver.describe(
119
+ if (forkDeclined(fork.status, 'branch fork')) return softSkip('blocked', 'precondition not met — `forkDeclined(fork.status, \'branch fork\')` returned early (seam, prior step, or fixture unavailable)');
120
+ expect(fork.status, req('openwop.it.replay-fork.produces-a-new-run-that-reaches-terminal-completed~2',
120
121
  'rest-endpoints.md POST /v1/runs/{runId}:fork',
121
122
  'branch fork MUST return 201',
122
123
  )).toBe(201);
@@ -143,7 +144,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
143
144
  if (modes.length === 0) {
144
145
  softSkip('inapplicable', "host advertises no usable fork mode for this leg");
145
146
  ctx.skip();
146
- return;
147
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `modes.length === 0` returned early');
147
148
  }
148
149
  const mode = modes.includes('branch') ? 'branch' : 'replay';
149
150
  const sourceRunId = await startAndFinishNoop();
@@ -151,7 +152,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
151
152
  `/v1/runs/${encodeURIComponent(sourceRunId)}:fork`,
152
153
  { fromSeq: -1, mode },
153
154
  );
154
- expect(res.status, driver.describe(
155
+ expect(res.status, req('openwop.it.replay-fork.rejects-negative-fromseq-with-400',
155
156
  'rest-endpoints.md',
156
157
  'negative fromSeq MUST return 400',
157
158
  )).toBe(400);
@@ -162,7 +163,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
162
163
  if (modes.length === 0) {
163
164
  softSkip('inapplicable', "host advertises no usable fork mode for this leg");
164
165
  ctx.skip();
165
- return;
166
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `modes.length === 0` returned early');
166
167
  }
167
168
  const mode = modes.includes('branch') ? 'branch' : 'replay';
168
169
  const sourceRunId = await startAndFinishNoop();
@@ -172,7 +173,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
172
173
  `/v1/runs/${encodeURIComponent(sourceRunId)}:fork`,
173
174
  { fromSeq: 99999, mode },
174
175
  );
175
- expect(res.status, driver.describe(
176
+ expect(res.status, req('openwop.it.replay-fork.rejects-fromseq-beyond-source-event-log-length-with-422',
176
177
  'rest-endpoints.md POST /v1/runs/{runId}:fork',
177
178
  'fromSeq beyond source event log MUST return 422',
178
179
  )).toBe(422);
@@ -187,7 +188,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
187
188
  // Visible skip rather than silent vacuous pass.
188
189
  softSkip('inapplicable', "host does not advertise the `replay` fork mode — the runOptionsOverlay rejection rule only applies to hosts that do");
189
190
  ctx.skip();
190
- return;
191
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!modes.includes(\'replay\')` returned early');
191
192
  }
192
193
  const sourceRunId = await startAndFinishNoop();
193
194
  const res = await driver.post(
@@ -198,7 +199,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
198
199
  runOptionsOverlay: { configurable: { recursionLimit: 50 } },
199
200
  },
200
201
  );
201
- expect(res.status, driver.describe(
202
+ expect(res.status, req('openwop.it.replay-fork.rejects-replay-mode-with-non-empty-runoptionsoverlay-overlay-is-branch-only',
202
203
  'rest-endpoints.md POST /v1/runs/{runId}:fork',
203
204
  'replay mode + non-empty overlay MUST return 400 (overlay is branch-only)',
204
205
  )).toBe(400);
@@ -209,7 +210,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
209
210
  if (modes.length === 0) {
210
211
  softSkip('inapplicable', "host advertises no usable fork mode for this leg");
211
212
  ctx.skip();
212
- return;
213
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `modes.length === 0` returned early');
213
214
  }
214
215
  const mode = modes.includes('branch') ? 'branch' : 'replay';
215
216
  const res = await driver.post(
@@ -218,7 +219,7 @@ describe.skipIf(SKIP_NO_NOOP)('replay: validation errors', () => {
218
219
  );
219
220
  expect(
220
221
  [403, 404].includes(res.status),
221
- driver.describe('rest-endpoints.md', 'fork on unknown run MUST return 404 or 403'),
222
+ req('openwop.it.replay-fork.rejects-fork-on-a-non-existent-run-with-404', 'rest-endpoints.md', 'fork on unknown run MUST return 404 or 403'),
222
223
  ).toBe(true);
223
224
  });
224
225
  });