@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
@@ -46,6 +46,8 @@ import { behaviorGate } from '../lib/behavior-gate.js';
46
46
  import { isFixtureAdvertised } from '../lib/fixtures.js';
47
47
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
48
48
  import { queryTestEvents } from '../lib/event-log-query.js';
49
+ import { req } from '../lib/requirement-ids.js';
50
+ import { softSkip } from '../lib/soft-skip.js';
49
51
 
50
52
  const FIXTURE = 'conformance-context-budget-multiturn';
51
53
  const PROFILE = 'openwop-context-budget';
@@ -135,20 +137,20 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
135
137
  const cb = ma?.executionModel?.contextBudget;
136
138
  const budget = numberOf(cb?.transcriptTokenBudget);
137
139
  if (!behaviorGate(PROFILE, budget !== undefined)) return;
138
- if (!isFixtureAdvertised(FIXTURE)) return; // fixture-gated soft-skip
140
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early (fixture-gated soft-skip)'); // fixture-gated soft-skip
139
141
 
140
142
  const advertisedCounter = stringOf(cb?.tokenCounter);
141
143
  expect(
142
144
  advertisedCounter,
143
- driver.describe('RFC 0111', 'tokenCounter MUST be advertised when transcriptTokenBudget is present (schema if/then)'),
145
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', 'tokenCounter MUST be advertised when transcriptTokenBudget is present (schema if/then)'),
144
146
  ).toBeDefined();
145
147
 
146
148
  // Drive the multi-turn orchestrator run.
147
149
  const create = await driver.post('/v1/runs', { workflowId: FIXTURE });
148
150
  expect(create.status).toBe(201);
149
151
  const runId = runIdOf(create.json);
150
- expect(runId, 'POST /v1/runs MUST return a runId').toBeDefined();
151
- if (runId === undefined) return;
152
+ expect(runId, req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', 'POST /v1/runs MUST return a runId')).toBeDefined();
153
+ if (runId === undefined) return softSkip('blocked', 'precondition not met — `runId === undefined` returned early (seam, prior step, or fixture unavailable)');
152
154
  await pollUntilTerminal(runId);
153
155
 
154
156
  // Probe the per-iteration transcript-window seam (OPTIONAL).
@@ -158,25 +160,25 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
158
160
  `/v1/host/sample/agent/transcript-window?runId=${encodeURIComponent(runId)}&iteration=${iteration}`,
159
161
  );
160
162
  if (res.status === 404 || res.status === 405) {
161
- if (iteration === 1) return; // seam unwired — soft-skip the whole scenario
163
+ if (iteration === 1) return softSkip('blocked', 'precondition not met — `iteration === 1` returned early (seam unwired — soft-skip the whole scenario) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip the whole scenario
162
164
  break; // iterations exhausted
163
165
  }
164
166
  if (res.status === 400 || res.status === 422) break; // iteration past the run's last turn
165
167
  expect(
166
168
  res.status === 200,
167
- driver.describe('host-sample-test-seams.md §14', 'the transcript-window seam MUST return 200 for a valid iteration'),
169
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'host-sample-test-seams.md §14', 'the transcript-window seam MUST return 200 for a valid iteration'),
168
170
  ).toBe(true);
169
171
  const window = transcriptWindowOf(res.json);
170
172
  expect(
171
173
  window,
172
- driver.describe('host-sample-test-seams.md §14', 'the seam MUST return { tokenCounter, tokenCount, eventIds, summarizedRanges }'),
174
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'host-sample-test-seams.md §14', 'the seam MUST return { tokenCounter, tokenCount, eventIds, summarizedRanges }'),
173
175
  ).toBeDefined();
174
- if (window === undefined) return;
176
+ if (window === undefined) return softSkip('blocked', 'precondition not met — `window === undefined` returned early (seam, prior step, or fixture unavailable)');
175
177
  windows.push({ iteration, window });
176
178
  }
177
179
 
178
180
  // Non-vacuity: a wired seam MUST report at least one iteration.
179
- expect(windows.length, 'a wired transcript-window seam MUST report at least one orchestrator iteration').toBeGreaterThan(0);
181
+ expect(windows.length, req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'host-sample-test-seams.md §14', 'a wired transcript-window seam MUST report at least one orchestrator iteration')).toBeGreaterThan(0);
180
182
 
181
183
  // Independent event-log read for the cross-check (OPTIONAL seam).
182
184
  const q = await queryTestEvents(runId);
@@ -196,14 +198,14 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
196
198
  // 1 — tokenCounter agreement.
197
199
  expect(
198
200
  window.tokenCounter,
199
- driver.describe('RFC 0111', `iteration ${iteration}: seam tokenCounter MUST equal the advertised contextBudget.tokenCounter`),
201
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', `iteration ${iteration}: seam tokenCounter MUST equal the advertised contextBudget.tokenCounter`),
200
202
  ).toBe(advertisedCounter);
201
203
 
202
204
  // 2 — the per-turn token bound.
203
205
  if (budget !== undefined) {
204
206
  expect(
205
207
  window.tokenCount,
206
- driver.describe('RFC 0111', `iteration ${iteration}: tokenCount MUST NOT exceed transcriptTokenBudget`),
208
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', `iteration ${iteration}: tokenCount MUST NOT exceed transcriptTokenBudget`),
207
209
  ).toBeLessThanOrEqual(budget);
208
210
  }
209
211
 
@@ -212,7 +214,7 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
212
214
  for (const id of window.eventIds) {
213
215
  expect(
214
216
  logEventIds.has(id),
215
- driver.describe('RFC 0111 §"Conformance seam"', `iteration ${iteration}: eventId "${id}" in the seam accounting MUST be a real persisted run event`),
217
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111 §"Conformance seam"', `iteration ${iteration}: eventId "${id}" in the seam accounting MUST be a real persisted run event`),
216
218
  ).toBe(true);
217
219
  }
218
220
  }
@@ -221,7 +223,7 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
221
223
  const uniqueIds = new Set(window.eventIds);
222
224
  expect(
223
225
  uniqueIds.size,
224
- driver.describe('RFC 0111 §"Conformance seam"', `iteration ${iteration}: eventIds MUST be a tail with no repeated entry`),
226
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111 §"Conformance seam"', `iteration ${iteration}: eventIds MUST be a tail with no repeated entry`),
225
227
  ).toBe(window.eventIds.length);
226
228
 
227
229
  // 5 — every summarized range references a recorded context.summarized event.
@@ -229,7 +231,7 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
229
231
  for (const range of window.summarizedRanges) {
230
232
  expect(
231
233
  summarizedRefs.has(range.summaryRef),
232
- driver.describe('RFC 0111', `iteration ${iteration}: summarizedRanges summaryRef "${range.summaryRef}" MUST have a matching context.summarized event`),
234
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', `iteration ${iteration}: summarizedRanges summaryRef "${range.summaryRef}" MUST have a matching context.summarized event`),
233
235
  ).toBe(true);
234
236
  }
235
237
  }
@@ -245,7 +247,7 @@ describe('context-budget-transcript-bound (RFC 0111 §"Context economy")', () =>
245
247
  for (const id of verbatimTail) {
246
248
  expect(
247
249
  summarizedIds.has(id),
248
- driver.describe('RFC 0111', `a kept (verbatim) turn "${id}" MUST NOT appear inside a summarized range`),
250
+ req('openwop.it.context-budget-transcript-bound.bounds-the-per-turn-transcript-to-transcripttokenbudget-with-an-internally-consi', 'RFC 0111', `a kept (verbatim) turn "${id}" MUST NOT appear inside a summarized range`),
249
251
  ).toBe(false);
250
252
  }
251
253
  }
@@ -34,6 +34,8 @@ import { behaviorGate } from '../lib/behavior-gate.js';
34
34
  import { isFixtureAdvertised } from '../lib/fixtures.js';
35
35
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
36
36
  import { queryTestEvents, type TestEvent } from '../lib/event-log-query.js';
37
+ import { req } from '../lib/requirement-ids.js';
38
+ import { softSkip } from '../lib/soft-skip.js';
37
39
 
38
40
  const FIXTURE = 'conformance-context-budget-multiturn';
39
41
  const PROFILE = 'openwop-context-summarization';
@@ -98,55 +100,55 @@ describe('context-summarization-replay (RFC 0111 §"Replay determinism")', () =>
98
100
  const ma = await readCapabilityFamily<MultiAgentCap>('multiAgent');
99
101
  const summarizationSupported = ma?.executionModel?.contextBudget?.summarization?.supported === true;
100
102
  if (!behaviorGate(PROFILE, summarizationSupported)) return;
101
- if (!isFixtureAdvertised(FIXTURE)) return; // fixture-gated soft-skip
103
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early (fixture-gated soft-skip)'); // fixture-gated soft-skip
102
104
 
103
105
  // Drive the multi-turn orchestrator run.
104
106
  const create = await driver.post('/v1/runs', { workflowId: FIXTURE });
105
107
  expect(create.status).toBe(201);
106
108
  const sourceRunId = runIdOf(create.json);
107
- expect(sourceRunId, 'POST /v1/runs MUST return a runId').toBeDefined();
108
- if (sourceRunId === undefined) return;
109
+ expect(sourceRunId, req('openwop.it.context-summarization-replay.replay-reuses-the-recorded-context-summarized-summaryref-never-re-summarizes', 'rest-endpoints.md POST /v1/runs/{runId}:fork', 'POST /v1/runs MUST return a runId')).toBeDefined();
110
+ if (sourceRunId === undefined) return softSkip('blocked', 'precondition not met — `sourceRunId === undefined` returned early (seam, prior step, or fixture unavailable)');
109
111
  await pollUntilTerminal(sourceRunId);
110
112
 
111
113
  // Read the recorded summarization records (OPTIONAL event-log seam).
112
114
  const sourceQ = await queryTestEvents(sourceRunId, { type: 'context.summarized' });
113
- if (!sourceQ.ok) return; // event-log seam unwired — soft-skip
115
+ if (!sourceQ.ok) return softSkip('blocked', 'precondition not met — `!sourceQ.ok` returned early (event-log seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // event-log seam unwired — soft-skip
114
116
  const sourceFingerprints = summaryFingerprints(sourceQ.events);
115
117
  if (sourceFingerprints.length === 0) {
116
118
  // The run did not summarize (budget not exceeded on this host) — nothing
117
119
  // to prove about reuse. Honest soft-skip; not a vacuous pass of the MUST.
118
120
  // eslint-disable-next-line no-console
119
121
  console.warn(`[${PROFILE}] run produced no context.summarized events; replay-reuse leg soft-skipped`);
120
- return;
122
+ return softSkip('blocked', 'precondition not met — `sourceFingerprints.length === 0` returned early ([…] run produced no context.summarized events; replay-reuse leg soft-skipped) (seam, prior step, or fixture unavailable)');
121
123
  }
122
124
 
123
125
  // Only attempt replay when the host advertises the replay fork mode.
124
126
  const wellKnown = await driver.get('/.well-known/openwop');
125
- if (!replayModesOf(wellKnown.json).includes('replay')) return;
127
+ if (!replayModesOf(wellKnown.json).includes('replay')) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!replayModesOf(wellKnown.json).includes(\'replay\')` returned early');
126
128
 
127
129
  const fork = await driver.post(
128
130
  `/v1/runs/${encodeURIComponent(sourceRunId)}:fork`,
129
131
  { fromSeq: 0, mode: 'replay' },
130
132
  );
131
- if (fork.status === 501 || fork.status === 404) return; // replay not implemented for this run — soft-skip
133
+ if (fork.status === 501 || fork.status === 404) return softSkip('blocked', 'precondition not met — `fork.status === 501 || fork.status === 404` returned early (replay not implemented for this run — soft-skip) (seam, prior step, or fixture unavailable)'); // replay not implemented for this run — soft-skip
132
134
  expect(
133
135
  fork.status,
134
- driver.describe('rest-endpoints.md POST /v1/runs/{runId}:fork', 'replay fork MUST return 201'),
136
+ req('openwop.it.context-summarization-replay.replay-reuses-the-recorded-context-summarized-summaryref-never-re-summarizes', 'rest-endpoints.md POST /v1/runs/{runId}:fork', 'replay fork MUST return 201'),
135
137
  ).toBe(201);
136
138
  const forkRunId = runIdOf(fork.json);
137
- expect(forkRunId, 'replay fork MUST return a runId').toBeDefined();
138
- if (forkRunId === undefined) return;
139
+ expect(forkRunId, req('openwop.it.context-summarization-replay.replay-reuses-the-recorded-context-summarized-summaryref-never-re-summarizes', 'rest-endpoints.md POST /v1/runs/{runId}:fork', 'replay fork MUST return a runId')).toBeDefined();
140
+ if (forkRunId === undefined) return softSkip('blocked', 'precondition not met — `forkRunId === undefined` returned early (seam, prior step, or fixture unavailable)');
139
141
  await pollUntilTerminal(forkRunId);
140
142
 
141
143
  const forkQ = await queryTestEvents(forkRunId, { type: 'context.summarized' });
142
- if (!forkQ.ok) return; // event-log seam unwired for the fork — soft-skip
144
+ if (!forkQ.ok) return softSkip('blocked', 'precondition not met — `!forkQ.ok` returned early (event-log seam unwired for the fork — soft-skip) (seam, prior step, or fixture unavailable)'); // event-log seam unwired for the fork — soft-skip
143
145
  const forkFingerprints = summaryFingerprints(forkQ.events);
144
146
 
145
147
  // The replay MUST reuse the recorded summaries (same summaryRef + replacedTurns),
146
148
  // NOT regenerate them — the direct analogue of RFC 0041 envelope-refusal recovery.
147
149
  expect(
148
150
  forkFingerprints,
149
- driver.describe(
151
+ req('openwop.it.context-summarization-replay.replay-reuses-the-recorded-context-summarized-summaryref-never-re-summarizes',
150
152
  'RFC 0111 §"Replay determinism"',
151
153
  'a replay fork MUST reuse the recorded context.summarized summaryRef (never re-summarize to a different transcript)',
152
154
  ),
@@ -49,8 +49,8 @@ import Ajv2020 from 'ajv/dist/2020.js';
49
49
  import addFormats from 'ajv-formats';
50
50
  import { driver } from '../lib/driver.js';
51
51
  import { SCHEMAS_DIR } from '../lib/paths.js';
52
-
53
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
52
+ import { req } from '../lib/requirement-ids.js';
53
+ import { softSkip } from '../lib/soft-skip.js';
54
54
 
55
55
  function provenanceSubschema(): Record<string, unknown> {
56
56
  const caps = JSON.parse(
@@ -73,11 +73,11 @@ describe('contract-provenance (RFC 0146, always-on)', () => {
73
73
 
74
74
  expect(
75
75
  caps.properties['contractProvenance'],
76
- why('capabilities.schema.json', 'declared as a root property — families live at the document root per capabilities.md §"Document-root layout", never under the deprecated wrapper'),
76
+ req('openwop.it.contract-provenance.a1-declared-at-the-document-root-and-optional', 'capabilities.schema.json', 'declared as a root property — families live at the document root per capabilities.md §"Document-root layout", never under the deprecated wrapper'),
77
77
  ).toBeDefined();
78
78
  expect(
79
79
  (caps.required ?? []).includes('contractProvenance'),
80
- why('RFC 0146 req 1', 'OPTIONAL — absent means UNSPECIFIED provenance, not "current" and not "stale"; a host must not be non-conformant for staying silent'),
80
+ req('openwop.it.contract-provenance.a1-declared-at-the-document-root-and-optional', 'RFC 0146 req 1', 'OPTIONAL — absent means UNSPECIFIED provenance, not "current" and not "stale"; a host must not be non-conformant for staying silent'),
81
81
  ).toBe(false);
82
82
  });
83
83
 
@@ -86,32 +86,32 @@ describe('contract-provenance (RFC 0146, always-on)', () => {
86
86
 
87
87
  expect(
88
88
  validate({ suiteVersion: '1.72.0', corpusCommit: '93d4692eb1e28244b860da6ddcb6521b57a712b3' }),
89
- why('RFC 0146 req 4', `a real stamp validates: ${JSON.stringify(validate.errors)}`),
89
+ req('openwop.it.contract-provenance.a2-a-full-40-hex-commit-validates-a-short-sha-or-a-vendor-build-string-does-not', 'RFC 0146 req 4', `a real stamp validates: ${JSON.stringify(validate.errors)}`),
90
90
  ).toBe(true);
91
91
  // This is what keeps the field from decaying into a free-text version box. A short SHA is
92
92
  // ambiguous across a growing history; a vendor build id belongs in `implementation`, which
93
93
  // already exists for exactly that.
94
94
  expect(
95
95
  validate({ corpusCommit: '93d4692' }),
96
- why('RFC 0146 req 4', 'a SHORT sha is REJECTED — abbreviated commits are ambiguous and this field is an identity, not a hint'),
96
+ req('openwop.it.contract-provenance.a2-a-full-40-hex-commit-validates-a-short-sha-or-a-vendor-build-string-does-not', 'RFC 0146 req 4', 'a SHORT sha is REJECTED — abbreviated commits are ambiguous and this field is an identity, not a hint'),
97
97
  ).toBe(false);
98
98
  expect(
99
99
  validate({ corpusCommit: 'build-4711' }),
100
- why('RFC 0146 req 4', 'a vendor build identifier is REJECTED — `implementation` is the field for that'),
100
+ req('openwop.it.contract-provenance.a2-a-full-40-hex-commit-validates-a-short-sha-or-a-vendor-build-string-does-not', 'RFC 0146 req 4', 'a vendor build identifier is REJECTED — `implementation` is the field for that'),
101
101
  ).toBe(false);
102
102
  });
103
103
 
104
104
  it('A3 — both members optional, and unknown members rejected', () => {
105
105
  const validate = compiled();
106
106
 
107
- expect(validate({}), why('RFC 0146 req 1', 'an empty object validates — a host may know neither')).toBe(true);
107
+ expect(validate({}), req('openwop.it.contract-provenance.a3-both-members-optional-and-unknown-members-rejected', 'RFC 0146 req 1', 'an empty object validates — a host may know neither')).toBe(true);
108
108
  expect(
109
109
  validate({ suiteVersion: '1.72.0' }),
110
- why('RFC 0146 req 1', 'a host that knows only its suite version advertises only that'),
110
+ req('openwop.it.contract-provenance.a3-both-members-optional-and-unknown-members-rejected', 'RFC 0146 req 1', 'a host that knows only its suite version advertises only that'),
111
111
  ).toBe(true);
112
112
  expect(
113
113
  validate({ suiteVersion: '1.72.0', schemaDigest: 'abc' }),
114
- why('RFC 0146 §Proposal', 'the object is closed — a digest is a DIFFERENT artifact answering a different question (tamper vs identity) and is deliberately not part of this shape'),
114
+ req('openwop.it.contract-provenance.a3-both-members-optional-and-unknown-members-rejected', 'RFC 0146 §Proposal', 'the object is closed — a digest is a DIFFERENT artifact answering a different question (tamper vs identity) and is deliberately not part of this shape'),
115
115
  ).toBe(false);
116
116
  });
117
117
 
@@ -135,7 +135,7 @@ describe('contract-provenance (RFC 0146, always-on)', () => {
135
135
  const rfc = rfcText ?? '';
136
136
  expect(
137
137
  /MUST NOT reject a request, refuse interop, or fail a run solely because/.test(rfc),
138
- why('RFC 0146 req 3', 'a consumer MUST NOT reject on a mismatch — v1.x revisions are additive, so a host on an older revision is CONFORMANT and the field detects drift rather than creating an error'),
138
+ req('openwop.it.contract-provenance.a4-the-rfc-states-the-advisory-rule-which-is-what-stops-this-becoming-an-upgrade', 'RFC 0146 req 3', 'a consumer MUST NOT reject on a mismatch — v1.x revisions are additive, so a host on an older revision is CONFORMANT and the field detects drift rather than creating an error'),
139
139
  ).toBe(true);
140
140
  });
141
141
  });
@@ -156,14 +156,14 @@ function suiteStamp(): { suiteVersion?: string; corpusCommit?: string } | null {
156
156
  describe('contract-provenance: the suite READS the advert — the consumer half (RFC 0146 G3)', () => {
157
157
  it('compares the advertised revision against the suite\'s own, and reports drift', async () => {
158
158
  const mine = suiteStamp();
159
- if (mine === null) return; // repo layout — inapplicable, see the docblock
159
+ if (mine === null) return softSkip('blocked', 'precondition not met — `mine === null` returned early (repo layout — inapplicable, see the docblock) (seam, prior step, or fixture unavailable)'); // repo layout — inapplicable, see the docblock
160
160
 
161
161
  const res = await driver.get('/.well-known/openwop');
162
- if (res.status !== 200 || res.json === null || res.json === undefined) return;
162
+ if (res.status !== 200 || res.json === null || res.json === undefined) return softSkip('blocked', 'precondition not met — `res.status !== 200 || res.json === null || res.json === undefined` returned early (seam, prior step, or fixture unavailable)');
163
163
  const adv = (res.json as Record<string, unknown>)['contractProvenance'] as
164
164
  | { suiteVersion?: string; corpusCommit?: string }
165
165
  | undefined;
166
- if (adv === undefined) return; // silent host — absent means UNSPECIFIED (req 1), not stale
166
+ if (adv === undefined) return softSkip('blocked', 'precondition not met — `adv === undefined` returned early (silent host — absent means UNSPECIFIED (req 1), not stale) (seam, prior step, or fixture unavailable)'); // silent host — absent means UNSPECIFIED (req 1), not stale
167
167
 
168
168
  const same = adv.corpusCommit !== undefined && adv.corpusCommit === mine.corpusCommit;
169
169
  console.log(
@@ -178,7 +178,7 @@ describe('contract-provenance: the suite READS the advert — the consumer half
178
178
  // because an unparseable provenance is useless to every consumer, not just this one.
179
179
  expect(
180
180
  typeof adv.corpusCommit === 'string' || typeof adv.suiteVersion === 'string',
181
- driver.describe(
181
+ req('openwop.it.contract-provenance.compares-the-advertised-revision-against-the-suite-s-own-and-reports-drift',
182
182
  'RFC 0146 req 1 + req 4',
183
183
  'an advertised contractProvenance carries at least one of suiteVersion / corpusCommit — an object conveying neither is indistinguishable from silence while looking like an answer',
184
184
  ),
@@ -189,18 +189,18 @@ describe('contract-provenance: the suite READS the advert — the consumer half
189
189
  describe('contract-provenance: a host advertising it makes a well-formed claim (RFC 0146)', () => {
190
190
  it('the advertised provenance validates against the declared shape', async () => {
191
191
  const res = await driver.get('/.well-known/openwop');
192
- if (res.status !== 200 || res.json === null || res.json === undefined) return;
192
+ if (res.status !== 200 || res.json === null || res.json === undefined) return softSkip('blocked', 'precondition not met — `res.status !== 200 || res.json === null || res.json === undefined` returned early (seam, prior step, or fixture unavailable)');
193
193
 
194
194
  const doc = res.json as Record<string, unknown>;
195
195
  const adv = doc['contractProvenance'];
196
196
  // INAPPLICABLE, not gated. The field is OPTIONAL (req 1) and strict mode must not coerce a
197
197
  // host into advertising — the same call RFC 0142 makes for `store` and RFC 0145 for
198
198
  // `registrationSource`. Silence is an honest answer here.
199
- if (adv === undefined) return;
199
+ if (adv === undefined) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `adv === undefined` returned early (INAPPLICABLE, not gated. The field is OPTIONAL (req 1) and strict mode must not coerce a host into advertising — the same ca…');
200
200
 
201
201
  expect(
202
202
  compiled()(adv),
203
- driver.describe(
203
+ req('openwop.it.contract-provenance.the-advertised-provenance-validates-against-the-declared-shape',
204
204
  'capabilities.schema.json §contractProvenance',
205
205
  `an advertised contractProvenance MUST match the declared shape — a full 40-hex corpusCommit and a published suiteVersion, nothing else: ${JSON.stringify(compiled().errors)}`,
206
206
  ),
@@ -35,8 +35,7 @@ import { join } from 'node:path';
35
35
  import Ajv2020 from 'ajv/dist/2020.js';
36
36
  import addFormats from 'ajv-formats';
37
37
  import { SCHEMAS_DIR } from '../lib/paths.js';
38
-
39
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
38
+ import { req } from '../lib/requirement-ids.js';
40
39
 
41
40
  function loadSchema(name: string): Record<string, unknown> {
42
41
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -60,36 +59,36 @@ describe('conversation-turn-model-provenance-shape: agent.model on a role:agent
60
59
  it('an agent turn carrying a conforming agent.model { provider, model } validates', () => {
61
60
  expect(
62
61
  turn({ ...agentBase, agent: { agentId: 'advisor-cfo', model: { provider: 'anthropic', model: 'claude-opus-4-8' } } }),
63
- why('RFC 0109 §Proposal', "a role:'agent' turn with agent.model { provider, model } MUST validate"),
62
+ req('openwop.it.conversation-turn-model-provenance-shape.an-agent-turn-carrying-a-conforming-agent-model-provider-model-validates', 'RFC 0109 §Proposal', "a role:'agent' turn with agent.model { provider, model } MUST validate"),
64
63
  ).toBe(true);
65
64
  });
66
65
 
67
66
  it('agent.model REQUIRES both provider and model', () => {
68
67
  expect(
69
68
  turn({ ...agentBase, agent: { model: { provider: 'anthropic' } } }),
70
- why('RFC 0109 §Proposal', 'agent.model without `model` MUST be rejected'),
69
+ req('openwop.it.conversation-turn-model-provenance-shape.agent-model-requires-both-provider-and-model', 'RFC 0109 §Proposal', 'agent.model without `model` MUST be rejected'),
71
70
  ).toBe(false);
72
71
  expect(
73
72
  turn({ ...agentBase, agent: { model: { model: 'claude-opus-4-8' } } }),
74
- why('RFC 0109 §Proposal', 'agent.model without `provider` MUST be rejected'),
73
+ req('openwop.it.conversation-turn-model-provenance-shape.agent-model-requires-both-provider-and-model', 'RFC 0109 §Proposal', 'agent.model without `provider` MUST be rejected'),
75
74
  ).toBe(false);
76
75
  });
77
76
 
78
77
  it('agent.model is CLOSED — an extra key (a secret/endpoint/prompt) MUST be rejected (the SR-1 guard)', () => {
79
78
  expect(
80
79
  turn({ ...agentBase, agent: { model: { provider: 'anthropic', model: 'claude-opus-4-8', apiKey: 'sk-secret' } } }),
81
- why('RFC 0109 §Proposal', 'agent.model MUST forbid extra keys — no credential/endpoint/prompt rides the provenance stamp'),
80
+ req('openwop.it.conversation-turn-model-provenance-shape.agent-model-is-closed-an-extra-key-a-secret-endpoint-prompt-must-be-rejected-the', 'RFC 0109 §Proposal', 'agent.model MUST forbid extra keys — no credential/endpoint/prompt rides the provenance stamp'),
82
81
  ).toBe(false);
83
82
  });
84
83
 
85
84
  it('agent.model is OPTIONAL — an agent turn that omits it still validates (additive, back-compat)', () => {
86
85
  expect(
87
86
  turn({ ...agentBase, agent: { agentId: 'advisor-cfo' } }),
88
- why('RFC 0109 §Compatibility', 'agent.model is additive — a turn without it MUST still validate'),
87
+ req('openwop.it.conversation-turn-model-provenance-shape.agent-model-is-optional-an-agent-turn-that-omits-it-still-validates-additive-bac', 'RFC 0109 §Compatibility', 'agent.model is additive — a turn without it MUST still validate'),
89
88
  ).toBe(true);
90
89
  expect(
91
90
  turn(agentBase),
92
- why('RFC 0109 §Compatibility', 'a turn with no agent object at all MUST still validate'),
91
+ req('openwop.it.conversation-turn-model-provenance-shape.agent-model-is-optional-an-agent-turn-that-omits-it-still-validates-additive-bac', 'RFC 0109 §Compatibility', 'a turn with no agent object at all MUST still validate'),
93
92
  ).toBe(true);
94
93
  });
95
94
  });
@@ -101,10 +100,10 @@ describe('conversation-turn-model-provenance-shape: capability advertisement (RF
101
100
  const block = props.conversationTurnModelProvenance as
102
101
  | { properties?: Record<string, unknown>; required?: string[]; additionalProperties?: boolean }
103
102
  | undefined;
104
- expect(block, why('RFC 0109 §Conformance', 'capabilities.conversationTurnModelProvenance MUST be declared')).toBeDefined();
105
- expect(block?.properties?.supported, why('RFC 0109 §Conformance', 'conversationTurnModelProvenance.supported MUST be declared')).toBeDefined();
106
- expect(block?.required, why('RFC 0109 §Conformance', 'supported MUST be required on the block')).toContain('supported');
107
- expect(block?.additionalProperties, why('RFC 0109 §Conformance', 'the block MUST be closed')).toBe(false);
103
+ expect(block, req('openwop.it.conversation-turn-model-provenance-shape.capabilities-schema-json-declares-conversationturnmodelprovenance-with-supported', 'RFC 0109 §Conformance', 'capabilities.conversationTurnModelProvenance MUST be declared')).toBeDefined();
104
+ expect(block?.properties?.supported, req('openwop.it.conversation-turn-model-provenance-shape.capabilities-schema-json-declares-conversationturnmodelprovenance-with-supported', 'RFC 0109 §Conformance', 'conversationTurnModelProvenance.supported MUST be declared')).toBeDefined();
105
+ expect(block?.required, req('openwop.it.conversation-turn-model-provenance-shape.capabilities-schema-json-declares-conversationturnmodelprovenance-with-supported', 'RFC 0109 §Conformance', 'supported MUST be required on the block')).toContain('supported');
106
+ expect(block?.additionalProperties, req('openwop.it.conversation-turn-model-provenance-shape.capabilities-schema-json-declares-conversationturnmodelprovenance-with-supported', 'RFC 0109 §Conformance', 'the block MUST be closed')).toBe(false);
108
107
  });
109
108
 
110
109
  it('the conversationTurnModelProvenance block validates a conforming advertisement and rejects extras', () => {
@@ -113,8 +112,8 @@ describe('conversation-turn-model-provenance-shape: capability advertisement (RF
113
112
  const ajv = new Ajv2020({ strict: false, allErrors: true });
114
113
  addFormats(ajv);
115
114
  const validate = ajv.compile(block);
116
- expect(validate({ supported: true }), why('RFC 0109 §Conformance', 'a conforming advertisement MUST validate')).toBe(true);
117
- expect(validate({}), why('RFC 0109 §Conformance', 'supported is required')).toBe(false);
118
- expect(validate({ supported: true, unexpected: 1 }), why('RFC 0109 §Conformance', 'an extra key MUST be rejected (closed block)')).toBe(false);
115
+ expect(validate({ supported: true }), req('openwop.it.conversation-turn-model-provenance-shape.the-conversationturnmodelprovenance-block-validates-a-conforming-advertisement-a', 'RFC 0109 §Conformance', 'a conforming advertisement MUST validate')).toBe(true);
116
+ expect(validate({}), req('openwop.it.conversation-turn-model-provenance-shape.the-conversationturnmodelprovenance-block-validates-a-conforming-advertisement-a', 'RFC 0109 §Conformance', 'supported is required')).toBe(false);
117
+ expect(validate({ supported: true, unexpected: 1 }), req('openwop.it.conversation-turn-model-provenance-shape.the-conversationturnmodelprovenance-block-validates-a-conforming-advertisement-a', 'RFC 0109 §Conformance', 'an extra key MUST be rejected (closed block)')).toBe(false);
119
118
  });
120
119
  });
@@ -21,6 +21,7 @@ import { readErrorCode } from '../lib/error-envelope.js';
21
21
  import { driver } from '../lib/driver.js';
22
22
  import { isFixtureAdvertised } from '../lib/fixtures.js';
23
23
  import { isConversationPrimitiveSupported } from '../lib/multi-agent-capabilities.js';
24
+ import { req } from '../lib/requirement-ids.js';
24
25
 
25
26
  const FIXTURE = 'conformance-conversation-capability-negotiation';
26
27
  // Inverted gate: this scenario runs when host does NOT advertise the
@@ -33,7 +34,7 @@ describe.skipIf(SKIP)('conversationCapabilityNegotiation: refusal contract', ()
33
34
  // The host MUST reject — either at workflow registration (404/400)
34
35
  // or at run-create (400). What MUST NOT happen is a successful
35
36
  // 201 followed by silent fallback.
36
- expect([400, 404, 422]).toContain(create.status);
37
+ expect([400, 404, 422], req('openwop.it.conversationCapabilityNegotiation.host-without-conversationprimitive-capability-refuses-conversation-bearing-workf', 'RFCS/0005-conversation.md', 'host without conversationPrimitive capability refuses conversation-bearing workflow')).toContain(create.status);
37
38
  const body = create.json as { code?: string };
38
39
  const code = readErrorCode(create.json) ?? body.code ?? '';
39
40
  expect(typeof code).toBe('string');
@@ -22,6 +22,7 @@ import { driver } from '../lib/driver.js';
22
22
  import { pollUntilTerminal } from '../lib/polling.js';
23
23
  import { isFixtureAdvertised } from '../lib/fixtures.js';
24
24
  import { isConversationPrimitiveSupported } from '../lib/multi-agent-capabilities.js';
25
+ import { req } from '../lib/requirement-ids.js';
25
26
 
26
27
  const FIXTURE = 'conformance-conversation-lifecycle';
27
28
  const SKIP = !isConversationPrimitiveSupported() || !isFixtureAdvertised(FIXTURE);
@@ -29,7 +30,7 @@ const SKIP = !isConversationPrimitiveSupported() || !isFixtureAdvertised(FIXTURE
29
30
  describe.skipIf(SKIP)('conversationLifecycle: open → exchange → close round-trip', () => {
30
31
  it('emits all three lifecycle events with matching conversationId; no exchanges after close', async () => {
31
32
  const create = await driver.post('/v1/runs', { workflowId: FIXTURE });
32
- expect(create.status).toBe(201);
33
+ expect(create.status, req('openwop.it.conversationLifecycle.emits-all-three-lifecycle-events-with-matching-conversationid-no-exchanges-after', 'RFCS/0005-conversation.md', 'emits all three lifecycle events with matching conversationId; no exchanges after close')).toBe(201);
33
34
  const runId = (create.json as { runId: string }).runId;
34
35
 
35
36
  // The fixture's exchange step requires resume input. Host-internal
@@ -19,6 +19,8 @@ import { driver } from '../lib/driver.js';
19
19
  import { pollUntilTerminal } from '../lib/polling.js';
20
20
  import { isFixtureAdvertised } from '../lib/fixtures.js';
21
21
  import { isConversationPrimitiveSupported } from '../lib/multi-agent-capabilities.js';
22
+ import { softSkip } from '../lib/soft-skip.js';
23
+ import { req } from '../lib/requirement-ids.js';
22
24
 
23
25
  const FIXTURE = 'conformance-conversation-replay';
24
26
  const SKIP = !isConversationPrimitiveSupported() || !isFixtureAdvertised(FIXTURE);
@@ -26,7 +28,7 @@ const SKIP = !isConversationPrimitiveSupported() || !isFixtureAdvertised(FIXTURE
26
28
  describe.skipIf(SKIP)('conversationReplayDeterminism: replay-fork preserves conversation log', () => {
27
29
  it('forked run yields byte-equal conversation channel projection', async () => {
28
30
  const create = await driver.post('/v1/runs', { workflowId: FIXTURE });
29
- expect(create.status).toBe(201);
31
+ expect(create.status, req('openwop.it.conversationReplayDeterminism.forked-run-yields-byte-equal-conversation-channel-projection', 'RFCS/0005-conversation.md', 'forked run yields byte-equal conversation channel projection')).toBe(201);
30
32
  const sourceRunId = (create.json as { runId: string }).runId;
31
33
 
32
34
  const terminal = await pollUntilTerminal(sourceRunId);
@@ -38,7 +40,7 @@ describe.skipIf(SKIP)('conversationReplayDeterminism: replay-fork preserves conv
38
40
  const fork = await driver.post(`/v1/runs/${encodeURIComponent(sourceRunId)}:fork`, {
39
41
  mode: 'replay',
40
42
  });
41
- if (fork.status === 404 || fork.status === 501) return; // host doesn't support replay-fork
43
+ if (fork.status === 404 || fork.status === 501) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `fork.status === 404 || fork.status === 501` returned early (host doesn\'t support replay-fork)'); // host doesn't support replay-fork
42
44
  expect([200, 201]).toContain(fork.status);
43
45
 
44
46
  const forkedRunId = (fork.json as { runId: string }).runId;
@@ -20,6 +20,7 @@ import { driver } from '../lib/driver.js';
20
20
  import { pollUntilTerminal } from '../lib/polling.js';
21
21
  import { isFixtureAdvertised } from '../lib/fixtures.js';
22
22
  import { isConversationPrimitiveSupported } from '../lib/multi-agent-capabilities.js';
23
+ import { req } from '../lib/requirement-ids.js';
23
24
 
24
25
  const FIXTURE = 'conformance-conversation-vs-clarification';
25
26
  const SKIP = !isConversationPrimitiveSupported() || !isFixtureAdvertised(FIXTURE);
@@ -41,7 +42,7 @@ describe.skipIf(SKIP)('conversationVsLegacySuspend: distinct event surfaces', ()
41
42
  expect(conversationEvents.length).toBeGreaterThan(0);
42
43
  expect(
43
44
  clarificationEvents.length,
44
- 'conversation.exchange MUST NOT emit clarification.* events',
45
+ req('openwop.it.conversationVsLegacySuspend.conversation-suspend-emits-conversation-events-not-clarification', 'RFCS/0005-conversation.md', 'conversation.exchange MUST NOT emit clarification.* events'),
45
46
  ).toBe(0);
46
47
  });
47
48
  });
@@ -24,8 +24,7 @@
24
24
 
25
25
  import { describe, it, expect } from 'vitest';
26
26
  import { isCoreStandard, isCore, deriveProfiles } from '../lib/profiles.js';
27
-
28
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
27
+ import { req } from '../lib/requirement-ids.js';
29
28
 
30
29
  const CORE = {
31
30
  protocolVersion: '1.0',
@@ -38,29 +37,29 @@ describe('core-standard-profile: floor predicate (RFC 0088 §B, server-free)', (
38
37
  it('a host meeting core + interrupts + a default transport is core-standard', () => {
39
38
  // No supportedTransports ⇒ both stream predicates default-true (profiles.md).
40
39
  const c = { ...CORE };
41
- expect(isCoreStandard(c), why('core-standard-profile.md §B', 'core + interrupts + transport ⇒ core-standard')).toBe(true);
40
+ expect(isCoreStandard(c), req('openwop.it.core-standard-profile.a-host-meeting-core-interrupts-a-default-transport-is-core-standard', 'core-standard-profile.md §B', 'core + interrupts + transport ⇒ core-standard')).toBe(true);
42
41
  });
43
42
 
44
43
  it('a bare openwop-core host without interrupts is NOT core-standard', () => {
45
44
  // openwop-core minimum, but no clarification.request ⇒ fails openwop-interrupts.
46
45
  const c = { ...CORE, supportedEnvelopes: ['schema.request'] };
47
- expect(isCore(c), why('profiles.md §openwop-core', 'still a valid openwop-core host')).toBe(true);
48
- expect(isCoreStandard(c), why('core-standard-profile.md §B', 'the floor is stricter than the v1 minimum')).toBe(false);
46
+ expect(isCore(c), req('openwop.it.core-standard-profile.a-bare-openwop-core-host-without-interrupts-is-not-core-standard', 'profiles.md §openwop-core', 'still a valid openwop-core host')).toBe(true);
47
+ expect(isCoreStandard(c), req('openwop.it.core-standard-profile.a-bare-openwop-core-host-without-interrupts-is-not-core-standard', 'core-standard-profile.md §B', 'the floor is stricter than the v1 minimum')).toBe(false);
49
48
  });
50
49
 
51
50
  it('a host advertising no event transport fails the floor', () => {
52
51
  const c = { ...CORE, supportedTransports: [] as string[] };
53
- expect(isCoreStandard(c), why('core-standard-profile.md §B', 'at least one event transport is required')).toBe(false);
52
+ expect(isCoreStandard(c), req('openwop.it.core-standard-profile.a-host-advertising-no-event-transport-fails-the-floor', 'core-standard-profile.md §B', 'at least one event transport is required')).toBe(false);
54
53
  });
55
54
 
56
55
  it('a host advertising the rest transport satisfies the transport term', () => {
57
56
  const c = { ...CORE, supportedTransports: ['rest'] };
58
- expect(isCoreStandard(c), why('core-standard-profile.md §B', 'rest transport ⇒ stream term satisfied')).toBe(true);
57
+ expect(isCoreStandard(c), req('openwop.it.core-standard-profile.a-host-advertising-the-rest-transport-satisfies-the-transport-term', 'core-standard-profile.md §B', 'rest transport ⇒ stream term satisfied')).toBe(true);
59
58
  });
60
59
 
61
60
  it('a non-1.x host is not core-standard', () => {
62
61
  const c = { ...CORE, protocolVersion: '2.0' };
63
- expect(isCoreStandard(c), why('profiles.md §openwop-core', 'core-standard implies openwop-core (1.x)')).toBe(false);
62
+ expect(isCoreStandard(c), req('openwop.it.core-standard-profile.a-non-1-x-host-is-not-core-standard', 'profiles.md §openwop-core', 'core-standard implies openwop-core (1.x)')).toBe(false);
64
63
  });
65
64
  });
66
65
 
@@ -69,7 +68,7 @@ describe('core-standard-profile: composes, does not redefine (RFC 0088 §A, serv
69
68
  const c = { ...CORE };
70
69
  expect(
71
70
  (deriveProfiles(c) as readonly string[]).includes('openwop-core-standard'),
72
- why('core-standard-profile.md §A', 'the annex is not a closed-catalog predicate'),
71
+ req('openwop.it.core-standard-profile.openwop-core-standard-is-an-annex-not-a-closed-catalog-profile-absent-from-deriv', 'core-standard-profile.md §A', 'the annex is not a closed-catalog predicate'),
73
72
  ).toBe(false);
74
73
  });
75
74
  });