@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
@@ -25,7 +25,6 @@
25
25
 
26
26
  import { describe, it, expect } from 'vitest';
27
27
  import { softSkip } from '../lib/soft-skip.js';
28
- import { driver } from '../lib/driver.js';
29
28
  import { behaviorGate, behaviorGatePresent } from '../lib/behavior-gate.js';
30
29
 
31
30
  const PROFILE = 'openwop-artifact-type-packs';
@@ -36,6 +35,7 @@ import {
36
35
  produceArtifact,
37
36
  sampleArtifactTypePack,
38
37
  } from '../lib/artifactTypes.js';
38
+ import { req } from '../lib/requirement-ids.js';
39
39
 
40
40
  describe('artifact-type-store-without-render: store-only hosts must not fail the run (RFC 0071)', () => {
41
41
  it('a stored-but-unrendered artifact completes the run', async () => {
@@ -54,15 +54,15 @@ describe('artifact-type-store-without-render: store-only hosts must not fail the
54
54
 
55
55
  expect(
56
56
  produced.json['stored'],
57
- driver.describe('artifact-type-packs.md §host.artifactTypes', 'a host advertising store:true MUST persist the artifact'),
57
+ req('openwop.it.artifact-type-store-without-render.a-stored-but-unrendered-artifact-completes-the-run', 'artifact-type-packs.md §host.artifactTypes', 'a host advertising store:true MUST persist the artifact'),
58
58
  ).toBe(true);
59
59
  expect(
60
60
  produced.json['rendered'],
61
- driver.describe('artifact-type-packs.md §host.artifactTypes', 'render:false host MUST NOT render'),
61
+ req('openwop.it.artifact-type-store-without-render.a-stored-but-unrendered-artifact-completes-the-run', 'artifact-type-packs.md §host.artifactTypes', 'render:false host MUST NOT render'),
62
62
  ).toBe(false);
63
63
  expect(
64
64
  produced.json['runStatus'],
65
- driver.describe('artifact-type-packs.md §host.artifactTypes', 'a host MUST NOT fail the run solely because it lacks a renderer for a stored artifact type'),
65
+ req('openwop.it.artifact-type-store-without-render.a-stored-but-unrendered-artifact-completes-the-run', 'artifact-type-packs.md §host.artifactTypes', 'a host MUST NOT fail the run solely because it lacks a renderer for a stored artifact type'),
66
66
  ).toBe('completed');
67
67
  });
68
68
  });
@@ -19,6 +19,8 @@ import { describe, it, expect } from 'vitest';
19
19
  import { driver } from '../lib/driver.js';
20
20
  import { behaviorGate } from '../lib/behavior-gate.js';
21
21
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
22
+ import { req } from '../lib/requirement-ids.js';
23
+ import { softSkip } from '../lib/soft-skip.js';
22
24
 
23
25
  interface AuditIntegrityCaps {
24
26
  hashChain?: boolean;
@@ -50,11 +52,11 @@ describe('audit-log-integrity: profile shape', () => {
50
52
  capabilityFamily<AuthCaps>(disco.json, 'auth')
51
53
  ?.auditLogIntegrity ?? {};
52
54
 
53
- expect(integrity.hashChain, driver.describe(
55
+ expect(integrity.hashChain, req('openwop.it.audit-log-integrity.host-that-claims-the-profile-advertises-required-capability-fields',
54
56
  'auth-profiles.md §"Audit-log integrity"',
55
57
  "openwop-audit-log-integrity profile MUST advertise auditLogIntegrity.hashChain: true",
56
58
  )).toBe(true);
57
- expect(integrity.checkpointSignatureAlgorithm, driver.describe(
59
+ expect(integrity.checkpointSignatureAlgorithm, req('openwop.it.audit-log-integrity.host-that-claims-the-profile-advertises-required-capability-fields',
58
60
  'auth-profiles.md §"Audit-log integrity" §"Key management"',
59
61
  'checkpointSignatureAlgorithm MUST be present (canonical: ed25519)',
60
62
  )).toBeDefined();
@@ -72,11 +74,11 @@ describe('audit-log-integrity: verify endpoint returns chainValid', () => {
72
74
  if (verify.status === 404) {
73
75
  // Host claims the profile but doesn't expose the endpoint — that's
74
76
  // a profile-claim violation. Fail explicitly.
75
- expect(verify.status, driver.describe(
77
+ expect(verify.status, req('openwop.it.audit-log-integrity.get-v1-audit-verify-on-a-recent-range-reports-chainvalid-true',
76
78
  'auth-profiles.md §"Audit-log integrity" §"Verification endpoint"',
77
79
  'claiming openwop-audit-log-integrity profile REQUIRES exposing GET /v1/audit/verify',
78
80
  )).not.toBe(404);
79
- return;
81
+ return softSkip('blocked', 'precondition not met — `verify.status === 404` returned early (seam, prior step, or fixture unavailable)');
80
82
  }
81
83
  expect(verify.status).toBe(200);
82
84
 
@@ -88,7 +90,7 @@ describe('audit-log-integrity: verify endpoint returns chainValid', () => {
88
90
  anomalies?: unknown[];
89
91
  };
90
92
 
91
- expect(body.chainValid, driver.describe(
93
+ expect(body.chainValid, req('openwop.it.audit-log-integrity.get-v1-audit-verify-on-a-recent-range-reports-chainvalid-true',
92
94
  'auth-profiles.md §"Audit-log integrity"',
93
95
  'unmodified audit range MUST report chainValid: true',
94
96
  )).toBe(true);
@@ -97,7 +99,7 @@ describe('audit-log-integrity: verify endpoint returns chainValid', () => {
97
99
 
98
100
  if (Array.isArray(body.checkpoints) && body.checkpoints.length > 0) {
99
101
  const cp = body.checkpoints[0];
100
- expect(typeof cp.signature, 'checkpoint signature MUST be a non-empty string').toBe('string');
102
+ expect(typeof cp.signature, req('openwop.it.audit-log-integrity.get-v1-audit-verify-on-a-recent-range-reports-chainvalid-true', 'auth-profiles.md §"Audit-log integrity"', 'checkpoint signature MUST be a non-empty string')).toBe('string');
101
103
  expect((cp.signature ?? '').length).toBeGreaterThan(0);
102
104
  }
103
105
  });
@@ -29,6 +29,8 @@ import { driver } from '../lib/driver.js';
29
29
  import { behaviorGate } from '../lib/behavior-gate.js';
30
30
  import { isFixtureAdvertised } from '../lib/fixtures.js';
31
31
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
32
+ import { req } from '../lib/requirement-ids.js';
33
+ import { softSkip } from '../lib/soft-skip.js';
32
34
 
33
35
  interface RotationCaps {
34
36
  supported?: boolean;
@@ -65,12 +67,12 @@ describe('auth-api-key-rotation: capability shape', () => {
65
67
  return;
66
68
  }
67
69
 
68
- expect(auth?.profiles?.includes(PROFILE), driver.describe(
70
+ expect(auth?.profiles?.includes(PROFILE), req('openwop.it.auth-api-key-rotation.host-claiming-rotation-profile-advertises-required-fields',
69
71
  'auth-profiles.md §`openwop-auth-api-key-rotation`',
70
72
  'capabilities.auth.profiles MUST include openwop-auth-api-key-rotation when the profile is claimed',
71
73
  )).toBe(true);
72
74
 
73
- expect(auth?.rotation?.supported, driver.describe(
75
+ expect(auth?.rotation?.supported, req('openwop.it.auth-api-key-rotation.host-claiming-rotation-profile-advertises-required-fields',
74
76
  'auth-profiles.md §`openwop-auth-api-key-rotation`',
75
77
  'capabilities.auth.rotation.supported MUST be true when the profile is claimed',
76
78
  )).toBe(true);
@@ -79,7 +81,7 @@ describe('auth-api-key-rotation: capability shape', () => {
79
81
  expect(
80
82
  Number.isInteger(auth.rotation.minGraceSeconds) &&
81
83
  auth.rotation.minGraceSeconds >= 0,
82
- driver.describe(
84
+ req('openwop.it.auth-api-key-rotation.host-claiming-rotation-profile-advertises-required-fields',
83
85
  'capabilities.schema.json auth.rotation.minGraceSeconds',
84
86
  'minGraceSeconds MUST be a non-negative integer when advertised',
85
87
  ),
@@ -109,7 +111,7 @@ describe('auth-api-key-rotation: two-key overlap', () => {
109
111
  console.warn(
110
112
  '[auth-api-key-rotation] OPENWOP_TEST_SECONDARY_API_KEY not supplied; skipping two-key overlap assertion',
111
113
  );
112
- return;
114
+ return softSkip('blocked', 'precondition not met — `!secondaryKey` returned early ([auth-api-key-rotation] OPENWOP_TEST_SECONDARY_API_KEY not supplied; skipping two-key overlap assertion) (seam, prior step, or fixture unavailable)');
113
115
  }
114
116
 
115
117
  if (!isFixtureAdvertised(FIXTURE)) {
@@ -117,12 +119,12 @@ describe('auth-api-key-rotation: two-key overlap', () => {
117
119
  console.warn(
118
120
  `[auth-api-key-rotation] ${FIXTURE} not advertised; skipping overlap assertion`,
119
121
  );
120
- return;
122
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early ([auth-api-key-rotation] … not advertised; skipping overlap assertion)');
121
123
  }
122
124
 
123
125
  // Primary key — uses driver's default Authorization header (env-loaded).
124
126
  const primary = await driver.post('/v1/runs', { workflowId: FIXTURE });
125
- expect(primary.status, driver.describe(
127
+ expect(primary.status, req('openwop.it.auth-api-key-rotation.primary-secondary-keys-both-authenticate-the-same-operation',
126
128
  'auth-profiles.md §`openwop-auth-api-key-rotation`',
127
129
  'primary key MUST authenticate POST /v1/runs during rotation grace',
128
130
  )).toBe(201);
@@ -137,7 +139,7 @@ describe('auth-api-key-rotation: two-key overlap', () => {
137
139
  headers: { Authorization: `Bearer ${secondaryKey}` },
138
140
  },
139
141
  );
140
- expect(secondary.status, driver.describe(
142
+ expect(secondary.status, req('openwop.it.auth-api-key-rotation.primary-secondary-keys-both-authenticate-the-same-operation',
141
143
  'auth-profiles.md §`openwop-auth-api-key-rotation`',
142
144
  'secondary key MUST authenticate POST /v1/runs during rotation grace',
143
145
  )).toBe(201);
@@ -167,7 +169,7 @@ describe('auth-api-key-rotation: canary redaction', () => {
167
169
  },
168
170
  );
169
171
 
170
- expect(res.status, driver.describe(
172
+ expect(res.status, req('openwop.it.auth-api-key-rotation.invalid-bearer-returns-401-without-echoing-the-canary-credential',
171
173
  'auth.md §3',
172
174
  'invalid bearer MUST return 401, not 200 or 403',
173
175
  )).toBe(401);
@@ -175,7 +177,7 @@ describe('auth-api-key-rotation: canary redaction', () => {
175
177
  // The response body MUST NOT echo the canary in any field. We
176
178
  // check the serialized JSON to catch echoes even in nested fields.
177
179
  const serialized = JSON.stringify(res.json ?? {});
178
- expect(serialized.includes(CANARY), driver.describe(
180
+ expect(serialized.includes(CANARY), req('openwop.it.auth-api-key-rotation.invalid-bearer-returns-401-without-echoing-the-canary-credential',
179
181
  'auth.md §"No credential echo" + threat-model-auth-profiles.md A1',
180
182
  'rotation-profile hosts MUST NOT echo the rejected credential in error responses',
181
183
  )).toBe(false);
@@ -46,6 +46,8 @@ import { loadEnv } from '../lib/env.js';
46
46
  import { behaviorGate } from '../lib/behavior-gate.js';
47
47
  import { isFixtureAdvertised } from '../lib/fixtures.js';
48
48
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
49
+ import { req } from '../lib/requirement-ids.js';
50
+ import { softSkip } from '../lib/soft-skip.js';
49
51
 
50
52
  interface MtlsCaps {
51
53
  supported?: boolean;
@@ -114,7 +116,7 @@ function mtlsPost(
114
116
  return new Promise((resolve) => {
115
117
  const url = new URL(baseUrl + path);
116
118
  const payload = JSON.stringify(body);
117
- const req = httpsRequest(
119
+ const reqBody = httpsRequest(
118
120
  {
119
121
  hostname: url.hostname,
120
122
  port: url.port ? Number.parseInt(url.port, 10) : 443,
@@ -138,9 +140,9 @@ function mtlsPost(
138
140
  });
139
141
  },
140
142
  );
141
- req.on('error', (error) => resolve({ error }));
142
- req.write(payload);
143
- req.end();
143
+ reqBody.on('error', (error) => resolve({ error }));
144
+ reqBody.write(payload);
145
+ reqBody.end();
144
146
  });
145
147
  }
146
148
 
@@ -152,12 +154,12 @@ describe('auth-mtls: capability shape', () => {
152
154
  return;
153
155
  }
154
156
 
155
- expect(auth?.profiles?.includes(PROFILE), driver.describe(
157
+ expect(auth?.profiles?.includes(PROFILE), req('openwop.it.auth-mtls.host-claiming-mtls-profile-advertises-required-fields',
156
158
  'auth-profiles.md §`openwop-auth-mtls`',
157
159
  'capabilities.auth.profiles MUST include openwop-auth-mtls when the profile is claimed',
158
160
  )).toBe(true);
159
161
 
160
- expect(auth?.mtls?.supported, driver.describe(
162
+ expect(auth?.mtls?.supported, req('openwop.it.auth-mtls.host-claiming-mtls-profile-advertises-required-fields',
161
163
  'auth-profiles.md §`openwop-auth-mtls`',
162
164
  'capabilities.auth.mtls.supported MUST be true when the profile is claimed',
163
165
  )).toBe(true);
@@ -165,14 +167,14 @@ describe('auth-mtls: capability shape', () => {
165
167
  if (auth?.mtls?.required !== undefined) {
166
168
  expect(
167
169
  typeof auth.mtls.required,
168
- 'mtls.required MUST be boolean when advertised',
170
+ req('openwop.it.auth-mtls.host-claiming-mtls-profile-advertises-required-fields', 'auth-profiles.md §`openwop-auth-mtls`', 'mtls.required MUST be boolean when advertised'),
169
171
  ).toBe('boolean');
170
172
  }
171
173
 
172
174
  if (auth?.mtls?.subjectMapping !== undefined) {
173
175
  expect(
174
176
  ['cn', 'san-dns', 'san-uri'].includes(auth.mtls.subjectMapping),
175
- driver.describe(
177
+ req('openwop.it.auth-mtls.host-claiming-mtls-profile-advertises-required-fields',
176
178
  'capabilities.schema.json auth.mtls.subjectMapping',
177
179
  'subjectMapping MUST be one of cn / san-dns / san-uri',
178
180
  ),
@@ -184,7 +186,7 @@ describe('auth-mtls: capability shape', () => {
184
186
  describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
185
187
  it('valid client cert + valid bearer → 201', async () => {
186
188
  const auth = await readAuthCaps();
187
- if (!isProfileAdvertised(auth)) return;
189
+ if (!isProfileAdvertised(auth)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isProfileAdvertised(auth)` returned early');
188
190
 
189
191
  const certs = loadClientCerts();
190
192
  if (!certs) {
@@ -192,10 +194,10 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
192
194
  console.warn(
193
195
  '[auth-mtls] OPENWOP_TEST_MTLS=1 but cert paths missing; skipping behavior',
194
196
  );
195
- return;
197
+ return softSkip('blocked', 'precondition not met — `!certs` returned early ([auth-mtls] OPENWOP_TEST_MTLS=1 but cert paths missing; skipping behavior) (seam, prior step, or fixture unavailable)');
196
198
  }
197
199
 
198
- if (!isFixtureAdvertised(FIXTURE)) return;
200
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
199
201
 
200
202
  const env = loadEnv();
201
203
  if (!env.baseUrl.startsWith('https://')) {
@@ -203,7 +205,7 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
203
205
  console.warn(
204
206
  `[auth-mtls] OPENWOP_BASE_URL is not HTTPS (got ${env.baseUrl}); mTLS requires HTTPS — skipping`,
205
207
  );
206
- return;
208
+ return softSkip('blocked', 'precondition not met — `!env.baseUrl.startsWith(\'https://\')` returned early ([auth-mtls] OPENWOP_BASE_URL is not HTTPS (got …); mTLS requires HTTPS — skipping) (seam, prior step, or fixture unavailable)');
207
209
  }
208
210
 
209
211
  const res = await mtlsPost(
@@ -220,7 +222,7 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
220
222
  );
221
223
  }
222
224
 
223
- expect(res.status, driver.describe(
225
+ expect(res.status, req('openwop.it.auth-mtls.valid-client-cert-valid-bearer-201',
224
226
  'auth-profiles.md §`openwop-auth-mtls`',
225
227
  'valid client cert + valid bearer MUST authenticate POST /v1/runs (201)',
226
228
  )).toBe(201);
@@ -228,16 +230,16 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
228
230
 
229
231
  it('no client cert against mtls.required: true → non-2xx or TLS failure', async () => {
230
232
  const auth = await readAuthCaps();
231
- if (!isProfileAdvertised(auth)) return;
233
+ if (!isProfileAdvertised(auth)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isProfileAdvertised(auth)` returned early');
232
234
  if (auth?.mtls?.required !== true) {
233
235
  // eslint-disable-next-line no-console
234
236
  console.warn(
235
237
  '[auth-mtls] host advertises mtls.required: false; skipping no-cert rejection (host may accept bearer-only)',
236
238
  );
237
- return;
239
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `auth?.mtls?.required !== true` returned early ([auth-mtls] host advertises mtls.required: false; skipping no-cert rejection (host may accept bearer-only))');
238
240
  }
239
241
 
240
- if (!isFixtureAdvertised(FIXTURE)) return;
242
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
241
243
 
242
244
  const env = loadEnv();
243
245
  if (!env.baseUrl.startsWith('https://')) {
@@ -245,7 +247,7 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
245
247
  console.warn(
246
248
  `[auth-mtls] OPENWOP_BASE_URL is not HTTPS (got ${env.baseUrl}); skipping no-cert rejection`,
247
249
  );
248
- return;
250
+ return softSkip('blocked', 'precondition not met — `!env.baseUrl.startsWith(\'https://\')` returned early ([auth-mtls] OPENWOP_BASE_URL is not HTTPS (got …); skipping no-cert rejection) (seam, prior step, or fixture unavailable)');
249
251
  }
250
252
 
251
253
  // No certs supplied → either 4xx or transport-layer TLS handshake failure.
@@ -260,14 +262,14 @@ describe.skipIf(!RUN_BEHAVIOR)('auth-mtls: client cert behavior', () => {
260
262
  if ('error' in res) {
261
263
  // Transport-layer TLS failure is conformant per auth-profiles.md.
262
264
  // The handshake rejected the client because no cert was offered.
263
- expect(true, driver.describe(
265
+ expect(true, req('openwop.it.auth-mtls.no-client-cert-against-mtls-required-true-non-2xx-or-tls-failure',
264
266
  'auth-profiles.md §`openwop-auth-mtls`',
265
267
  'mtls.required: true MUST reject no-cert requests (TLS handshake failure is conformant)',
266
268
  )).toBe(true);
267
- return;
269
+ return softSkip('blocked', 'precondition not met — `\'error\' in res` returned early (seam, prior step, or fixture unavailable)');
268
270
  }
269
271
 
270
- expect(res.status >= 400, driver.describe(
272
+ expect(res.status >= 400, req('openwop.it.auth-mtls.no-client-cert-against-mtls-required-true-non-2xx-or-tls-failure',
271
273
  'auth-profiles.md §`openwop-auth-mtls`',
272
274
  'mtls.required: true MUST reject no-cert requests at the auth layer (4xx) when not rejected at the TLS layer',
273
275
  )).toBe(true);
@@ -34,6 +34,8 @@ import { behaviorGate } from '../lib/behavior-gate.js';
34
34
  import { isFixtureAdvertised } from '../lib/fixtures.js';
35
35
  import { createSyntheticOIDCIssuer } from '../lib/oidc-issuer.js';
36
36
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
37
+ import { req } from '../lib/requirement-ids.js';
38
+ import { softSkip } from '../lib/soft-skip.js';
37
39
 
38
40
  /**
39
41
  * Callback-shaped: the host fetches the token endpoint on the suite's synthetic OIDC issuer.
@@ -79,12 +81,12 @@ describe('auth-oauth2-client-credentials: capability shape', () => {
79
81
  return;
80
82
  }
81
83
 
82
- expect(auth?.profiles?.includes(PROFILE), driver.describe(
84
+ expect(auth?.profiles?.includes(PROFILE), req('openwop.it.auth-oauth2-client-credentials.host-claiming-oauth2-cc-profile-advertises-required-fields',
83
85
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
84
86
  'capabilities.auth.profiles MUST include openwop-auth-oauth2-client-credentials when the profile is claimed',
85
87
  )).toBe(true);
86
88
 
87
- expect(auth?.oauth2?.supported, driver.describe(
89
+ expect(auth?.oauth2?.supported, req('openwop.it.auth-oauth2-client-credentials.host-claiming-oauth2-cc-profile-advertises-required-fields',
88
90
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
89
91
  'capabilities.auth.oauth2.supported MUST be true when the profile is claimed',
90
92
  )).toBe(true);
@@ -92,7 +94,7 @@ describe('auth-oauth2-client-credentials: capability shape', () => {
92
94
  if (auth?.oauth2?.issuer !== undefined) {
93
95
  expect(
94
96
  typeof auth.oauth2.issuer === 'string' && auth.oauth2.issuer.length > 0,
95
- driver.describe(
97
+ req('openwop.it.auth-oauth2-client-credentials.host-claiming-oauth2-cc-profile-advertises-required-fields',
96
98
  'capabilities.schema.json auth.oauth2.issuer',
97
99
  'issuer MUST be a non-empty string when advertised',
98
100
  ),
@@ -102,7 +104,7 @@ describe('auth-oauth2-client-credentials: capability shape', () => {
102
104
  if (auth?.oauth2?.audience !== undefined) {
103
105
  expect(
104
106
  typeof auth.oauth2.audience === 'string' && auth.oauth2.audience.length > 0,
105
- driver.describe(
107
+ req('openwop.it.auth-oauth2-client-credentials.host-claiming-oauth2-cc-profile-advertises-required-fields',
106
108
  'capabilities.schema.json auth.oauth2.audience',
107
109
  'audience MUST be a non-empty string when advertised',
108
110
  ),
@@ -113,7 +115,7 @@ describe('auth-oauth2-client-credentials: capability shape', () => {
113
115
  expect(
114
116
  Array.isArray(auth.oauth2.supportedAlgorithms) &&
115
117
  auth.oauth2.supportedAlgorithms.length > 0,
116
- driver.describe(
118
+ req('openwop.it.auth-oauth2-client-credentials.host-claiming-oauth2-cc-profile-advertises-required-fields',
117
119
  'capabilities.schema.json auth.oauth2.supportedAlgorithms',
118
120
  'supportedAlgorithms MUST be a non-empty array when advertised',
119
121
  ),
@@ -139,13 +141,13 @@ describe('auth-oauth2-client-credentials: malformed JWT rejected', () => {
139
141
  },
140
142
  );
141
143
 
142
- expect(res.status, driver.describe(
144
+ expect(res.status, req('openwop.it.auth-oauth2-client-credentials.returns-401-on-bearer-that-is-not-a-valid-jwt-shape',
143
145
  'auth.md §3',
144
146
  'malformed JWT bearer MUST return 401 (canonical invalid_token envelope)',
145
147
  )).toBe(401);
146
148
 
147
149
  const body = res.json as { error?: unknown; message?: unknown } | undefined;
148
- expect(typeof body?.error, driver.describe(
150
+ expect(typeof body?.error, req('openwop.it.auth-oauth2-client-credentials.returns-401-on-bearer-that-is-not-a-valid-jwt-shape',
149
151
  'auth.md §3 + rest-endpoints.md error envelope',
150
152
  'response body MUST include `error` (machine code) string',
151
153
  )).toBe('string');
@@ -165,7 +167,7 @@ describe('auth-oauth2-client-credentials: harness-minted negative cases', () =>
165
167
  console.warn(
166
168
  '[auth-oauth2-client-credentials] OPENWOP_TEST_OAUTH_ISSUER_TRUSTED not set; skipping harness-minted negative cases (operator must pre-configure the host to trust the conformance harness)',
167
169
  );
168
- return;
170
+ return softSkip('blocked', 'precondition not met — `process.env.OPENWOP_TEST_OAUTH_ISSUER_TRUSTED !== \'true\'` returned early ([auth-oauth2-client-credentials] OPENWOP_TEST_OAUTH_ISSUER_TRUSTED not set; skipping harness-minted negative cases (ope…');
169
171
  }
170
172
 
171
173
  const issuerUrl =
@@ -187,7 +189,7 @@ describe('auth-oauth2-client-credentials: harness-minted negative cases', () =>
187
189
  headers: { Authorization: `Bearer ${wrongAud.token}` },
188
190
  },
189
191
  );
190
- expect(wrongAudRes.status, driver.describe(
192
+ expect(wrongAudRes.status, req('openwop.it.auth-oauth2-client-credentials.wrong-audience-token-returns-401-when-host-trusts-the-harness',
191
193
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
192
194
  'token with wrong aud claim MUST return 401',
193
195
  )).toBe(401);
@@ -205,7 +207,7 @@ describe('auth-oauth2-client-credentials: harness-minted negative cases', () =>
205
207
  headers: { Authorization: `Bearer ${expired.token}` },
206
208
  },
207
209
  );
208
- expect(expiredRes.status, driver.describe(
210
+ expect(expiredRes.status, req('openwop.it.auth-oauth2-client-credentials.wrong-audience-token-returns-401-when-host-trusts-the-harness',
209
211
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
210
212
  'expired token (exp < now) MUST return 401',
211
213
  )).toBe(401);
@@ -223,7 +225,7 @@ describe('auth-oauth2-client-credentials: harness-minted negative cases', () =>
223
225
  headers: { Authorization: `Bearer ${algSpoofed.token}` },
224
226
  },
225
227
  );
226
- expect(algSpoofedRes.status, driver.describe(
228
+ expect(algSpoofedRes.status, req('openwop.it.auth-oauth2-client-credentials.wrong-audience-token-returns-401-when-host-trusts-the-harness',
227
229
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
228
230
  'token with alg outside supportedAlgorithms MUST return 401',
229
231
  )).toBe(401);
@@ -244,11 +246,11 @@ describe('auth-oauth2-client-credentials: positive token', () => {
244
246
  console.warn(
245
247
  '[auth-oauth2-client-credentials] OPENWOP_TEST_OAUTH_TOKEN not supplied; skipping positive-path assertion',
246
248
  );
247
- return;
249
+ return softSkip('blocked', 'precondition not met — `!token` returned early ([auth-oauth2-client-credentials] OPENWOP_TEST_OAUTH_TOKEN not supplied; skipping positive-path assertion) (seam, prior step, or fixture unavailable)');
248
250
  }
249
251
 
250
252
  if (!isFixtureAdvertised(FIXTURE)) {
251
- return;
253
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
252
254
  }
253
255
 
254
256
  const res = await driver.post(
@@ -260,7 +262,7 @@ describe('auth-oauth2-client-credentials: positive token', () => {
260
262
  },
261
263
  );
262
264
 
263
- expect(res.status, driver.describe(
265
+ expect(res.status, req('openwop.it.auth-oauth2-client-credentials.operator-supplied-valid-token-authenticates-post-v1-runs',
264
266
  'auth-profiles.md §`openwop-auth-oauth2-client-credentials`',
265
267
  'valid OAuth2-CC token MUST authenticate POST /v1/runs (201)',
266
268
  )).toBe(201);
@@ -48,6 +48,8 @@ import {
48
48
  type SyntheticOIDCIssuer,
49
49
  } from '../lib/oidc-issuer.js';
50
50
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
51
+ import { req } from '../lib/requirement-ids.js';
52
+ import { softSkip } from '../lib/soft-skip.js';
51
53
 
52
54
  /**
53
55
  * Callback-shaped: the host fetches JWKS and discovery from the suite's synthetic OIDC issuer.
@@ -94,19 +96,19 @@ describe('auth-oidc-user-bearer: capability shape', () => {
94
96
  return;
95
97
  }
96
98
 
97
- expect(auth?.profiles?.includes(PROFILE), driver.describe(
99
+ expect(auth?.profiles?.includes(PROFILE), req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields',
98
100
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
99
101
  'capabilities.auth.profiles MUST include openwop-auth-oidc-user-bearer when the profile is claimed',
100
102
  )).toBe(true);
101
103
 
102
- expect(auth?.oidc?.supported, driver.describe(
104
+ expect(auth?.oidc?.supported, req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields',
103
105
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
104
106
  'capabilities.auth.oidc.supported MUST be true when the profile is claimed',
105
107
  )).toBe(true);
106
108
 
107
109
  expect(
108
110
  Array.isArray(auth?.oidc?.issuers) && (auth?.oidc?.issuers?.length ?? 0) > 0,
109
- driver.describe(
111
+ req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields',
110
112
  'capabilities.schema.json auth.oidc.issuers',
111
113
  'issuers MUST be a non-empty array when the profile is claimed',
112
114
  ),
@@ -115,14 +117,14 @@ describe('auth-oidc-user-bearer: capability shape', () => {
115
117
  for (const issuer of auth?.oidc?.issuers ?? []) {
116
118
  expect(
117
119
  typeof issuer === 'string' && issuer.length > 0,
118
- 'each issuer entry MUST be a non-empty string',
120
+ req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields', 'capabilities.schema.json auth.oidc.issuers', 'each issuer entry MUST be a non-empty string'),
119
121
  ).toBe(true);
120
122
  }
121
123
 
122
124
  if (auth?.oidc?.audience !== undefined) {
123
125
  expect(
124
126
  typeof auth.oidc.audience === 'string' && auth.oidc.audience.length > 0,
125
- 'audience MUST be a non-empty string when advertised',
127
+ req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields', 'capabilities.schema.json auth.oidc.issuers', 'audience MUST be a non-empty string when advertised'),
126
128
  ).toBe(true);
127
129
  }
128
130
 
@@ -131,7 +133,7 @@ describe('auth-oidc-user-bearer: capability shape', () => {
131
133
  ['group-claim', 'scope-claim', 'host-acl'].includes(
132
134
  auth.oidc.supportedScopeMapping,
133
135
  ),
134
- driver.describe(
136
+ req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields',
135
137
  'capabilities.schema.json auth.oidc.supportedScopeMapping',
136
138
  'supportedScopeMapping MUST be one of group-claim/scope-claim/host-acl',
137
139
  ),
@@ -142,7 +144,7 @@ describe('auth-oidc-user-bearer: capability shape', () => {
142
144
  expect(
143
145
  Number.isInteger(auth.oidc.introspectionIntervalSeconds) &&
144
146
  auth.oidc.introspectionIntervalSeconds >= 0,
145
- 'introspectionIntervalSeconds MUST be a non-negative integer when advertised',
147
+ req('openwop.it.auth-oidc-user-bearer.host-claiming-oidc-profile-advertises-required-fields', 'capabilities.schema.json auth.oidc.supportedScopeMapping', 'introspectionIntervalSeconds MUST be a non-negative integer when advertised'),
146
148
  ).toBe(true);
147
149
  }
148
150
  });
@@ -175,16 +177,16 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
175
177
  const parsed = new URL(harnessUrl);
176
178
  const port = parsed.port ? Number.parseInt(parsed.port, 10) : 80;
177
179
 
178
- server = createServer((req, res) => {
180
+ server = createServer((reqBody, res) => {
179
181
  if (!issuer) {
180
182
  res.writeHead(503);
181
183
  res.end();
182
184
  return;
183
185
  }
184
- if (req.url === '/.well-known/jwks.json') {
186
+ if (reqBody.url === '/.well-known/jwks.json') {
185
187
  res.writeHead(200, { 'Content-Type': 'application/json' });
186
188
  res.end(issuer.jwksJson);
187
- } else if (req.url === '/.well-known/openid-configuration') {
189
+ } else if (reqBody.url === '/.well-known/openid-configuration') {
188
190
  res.writeHead(200, { 'Content-Type': 'application/json' });
189
191
  res.end(issuer.discoveryJson);
190
192
  } else {
@@ -230,7 +232,7 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
230
232
  console.warn(
231
233
  '[auth-oidc-user-bearer] harness not wired or host trust not configured; skipping wrong-iss case',
232
234
  );
233
- return;
235
+ return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early ([auth-oidc-user-bearer] harness not wired or host trust not configured; skipping wrong-iss case) (seam, prior step, or fixture unavailable)');
234
236
  }
235
237
 
236
238
  const wrongIssIssuer = createSyntheticOIDCIssuer({
@@ -248,14 +250,14 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
248
250
  },
249
251
  );
250
252
 
251
- expect(res.status, driver.describe(
253
+ expect(res.status, req('openwop.it.auth-oidc-user-bearer.wrong-iss-401',
252
254
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
253
255
  'token with non-trusted iss MUST return 401',
254
256
  )).toBe(401);
255
257
  });
256
258
 
257
259
  it('wrong aud → 401', async () => {
258
- if (!issuer || !trustWired) return;
260
+ if (!issuer || !trustWired) return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early (seam, prior step, or fixture unavailable)');
259
261
  const wrongAud = issuer.mint({ aud: 'wrong-audience', sub: 'attacker' });
260
262
  const res = await driver.post(
261
263
  '/v1/runs',
@@ -265,14 +267,14 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
265
267
  headers: { Authorization: `Bearer ${wrongAud.token}` },
266
268
  },
267
269
  );
268
- expect(res.status, driver.describe(
270
+ expect(res.status, req('openwop.it.auth-oidc-user-bearer.wrong-aud-401',
269
271
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
270
272
  'token with wrong aud MUST return 401',
271
273
  )).toBe(401);
272
274
  });
273
275
 
274
276
  it('expired exp → 401', async () => {
275
- if (!issuer || !trustWired) return;
277
+ if (!issuer || !trustWired) return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early (seam, prior step, or fixture unavailable)');
276
278
  const expired = issuer.mint(
277
279
  { sub: 'conformance-suite' },
278
280
  { expiresInSeconds: -3600 },
@@ -285,14 +287,14 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
285
287
  headers: { Authorization: `Bearer ${expired.token}` },
286
288
  },
287
289
  );
288
- expect(res.status, driver.describe(
290
+ expect(res.status, req('openwop.it.auth-oidc-user-bearer.expired-exp-401',
289
291
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
290
292
  'expired token (exp < now) MUST return 401',
291
293
  )).toBe(401);
292
294
  });
293
295
 
294
296
  it('unknown kid → 401', async () => {
295
- if (!issuer || !trustWired) return;
297
+ if (!issuer || !trustWired) return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early (seam, prior step, or fixture unavailable)');
296
298
  const unknownKid = issuer.mint(
297
299
  { sub: 'conformance-suite' },
298
300
  { keyId: 'openwop-conformance-key-NEVER-PUBLISHED' },
@@ -305,15 +307,15 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
305
307
  headers: { Authorization: `Bearer ${unknownKid.token}` },
306
308
  },
307
309
  );
308
- expect(res.status, driver.describe(
310
+ expect(res.status, req('openwop.it.auth-oidc-user-bearer.unknown-kid-401',
309
311
  'auth-profiles.md §`openwop-auth-oidc-user-bearer` + threat-model-auth-profiles.md A3',
310
312
  'token referencing a kid not in JWKS MUST return 401',
311
313
  )).toBe(401);
312
314
  });
313
315
 
314
316
  it('valid token → 201 or 403 (depending on host scope mapping)', async () => {
315
- if (!issuer || !trustWired) return;
316
- if (!isFixtureAdvertised(FIXTURE)) return;
317
+ if (!issuer || !trustWired) return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early (seam, prior step, or fixture unavailable)');
318
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
317
319
 
318
320
  const valid = issuer.mint({
319
321
  sub: 'conformance-suite',
@@ -334,7 +336,7 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
334
336
  // decision is a separate host-side policy not normated by RFC 0010.
335
337
  expect(
336
338
  [201, 403].includes(res.status),
337
- driver.describe(
339
+ req('openwop.it.auth-oidc-user-bearer.valid-token-201-or-403-depending-on-host-scope-mapping',
338
340
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
339
341
  'host-trusted token MUST yield 201 (mapped scope) or 403 (unmapped sub), NOT 401',
340
342
  ),
@@ -342,14 +344,14 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
342
344
  });
343
345
 
344
346
  it('scope-insufficient → 403 (when host uses group-claim mapping)', async () => {
345
- if (!issuer || !trustWired) return;
347
+ if (!issuer || !trustWired) return softSkip('blocked', 'precondition not met — `!issuer || !trustWired` returned early (seam, prior step, or fixture unavailable)');
346
348
  const auth = await readAuthCaps();
347
349
  if (auth?.oidc?.supportedScopeMapping !== 'group-claim') {
348
350
  // eslint-disable-next-line no-console
349
351
  console.warn(
350
352
  '[auth-oidc-user-bearer] host scope mapping is not group-claim; skipping scope-insufficient case',
351
353
  );
352
- return;
354
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `auth?.oidc?.supportedScopeMapping !== \'group-claim\'` returned early ([auth-oidc-user-bearer] host scope mapping is not group-claim; skipping scope-insufficient…');
353
355
  }
354
356
 
355
357
  const noGroups = issuer.mint({ sub: 'conformance-suite', groups: [] });
@@ -362,7 +364,7 @@ describe('auth-oidc-user-bearer: harness-driven token validation', () => {
362
364
  },
363
365
  );
364
366
 
365
- expect(res.status, driver.describe(
367
+ expect(res.status, req('openwop.it.auth-oidc-user-bearer.scope-insufficient-403-when-host-uses-group-claim-mapping',
366
368
  'auth-profiles.md §`openwop-auth-oidc-user-bearer`',
367
369
  'token-valid-but-empty-groups against group-claim host MUST return 403 (forbidden), NOT 401',
368
370
  )).toBe(403);